Vinnaren i pepparkakshustävlingen!
2018-11-05, 20:27
  #1
Medlem
Hej kodexperter!

Jag har en lite klurig fråga. Jag har en tabell med två kolumner. Vi kan säga för enkelhets skull att den första kolumnen är antalet äpplen och den andra är under hur många dagar dessa äpplen ska delas ut.

Tabellen ser ut så här:

Antal_äpplen Antal_dagar_äpplen_utdelade
(7) (7)
(6) (3)
(12 ) (4)

Den nya tabellen ska fördela ut äpplena genom att ta "Antal_äpplen" i första kolumnen dividerat med "Antal_dagar_äpplen_utdelade" och lägga dem i varsin kolumn. Den nya tabellen innehåller dagar och äpplena börjar alltid att delas ut på måndag. Den nya tabellen blir då så här:

M T O T F L S
(1) (1) (1) (1) (1) (1) (1)
(2) (2) (2)
(3) (3) (3) (3)

Finns det någon har tips på hur man ska göra? Jag antar att det är någon form av Split-funktion men jag hittar inga bra exempel med siffror. Tack i förhand för hjälpen!

Ps. Sorry om det blir lite fula tabeller, lyckas inte riktigt göra det i flashback!
__________________
Senast redigerad av Perfecthairline 2018-11-05 kl. 20:32.
Citera
2018-11-05, 20:51
  #2
Medlem
Du skulle kunna använda funktionen pivot, men den är ganska knepig att få till.

Om det är fler än 7 dagar skulle jag inte göra sådär, utan jag skulle lägga datum i en kolumn och aggregaten i övriga kolumner.

Man kan skapa en tabell med datum och sedan joina och gruppera på den.

Om du skall ha fler än 7 dagar så blir det löjligt många kolumner annars.

Men, om du absolut vill lösa denhär skoluppgiften så som läraren tänkt sig så kika på pivot.
__________________
Senast redigerad av krakelibrankel 2018-11-05 kl. 21:04.
Citera
2018-11-05, 21:19
  #3
Medlem
Citat:
Ursprungligen postat av krakelibrankel
Du skulle kunna använda funktionen pivot, men den är ganska knepig att få till.

Om det är fler än 7 dagar skulle jag inte göra sådär, utan jag skulle lägga datum i en kolumn och aggregaten i övriga kolumner.

Man kan skapa en tabell med datum och sedan joina och gruppera på den.

Om du skall ha fler än 7 dagar så blir det löjligt många kolumner annars.

Men, om du absolut vill lösa denhär skoluppgiften så som läraren tänkt sig så kika på pivot.
Hehe, det är ganska länge sedan jag satt på en skolbänk och det verkliga fallet är betydligt mer komplext än exemplet med äpplen...

Pivot funkar men först måste jag splitta en rad i flera. Exemplet med 7 äpplen på 7 dagar exempelvis ska ju först 7 rader med 1 äpple på varje rad, sedan är det lätt att pivotera.
Citera
2018-11-05, 21:39
  #4
Medlem
Citat:
Ursprungligen postat av Perfecthairline
Hehe, det är ganska länge sedan jag satt på en skolbänk och det verkliga fallet är betydligt mer komplext än exemplet med äpplen...

Pivot funkar men först måste jag splitta en rad i flera. Exemplet med 7 äpplen på 7 dagar exempelvis ska ju först 7 rader med 1 äpple på varje rad, sedan är det lätt att pivotera.

Du skulle kunna använda nummer för att repsentera dagarna, typ 1, 2, 3, 4, 5, 6.. osv.

Du kan du köra case when dag <= antal_dagar_äpplen_utdelade then antal_äpplen / antal_dagar_äpplen_utdelade else null end

De skulle ge dig mönstret iaf.


Om du bara har 7 dagar så kan du skriva 7 case satser, en för varje kolumn, men om du skall ha massor av dagar så nej, då funkar ej den bruteforce metoden.
__________________
Senast redigerad av krakelibrankel 2018-11-05 kl. 21:42.
Citera
2018-12-22, 02:19
  #5
Medlem
Dynamisk och rolig lösning, två olika lösningar, ungefär lika
Kod:
DECLARE @äpplen TABLE (
	antal_äpplen int,
	antal_dagar int
);
INSERT INTO @äpplen
VALUES
	(7, 7),
	(6, 3),
	(12, 4);
-- CTE 1
WITH
	dagar(dag) AS (
				SELECT * FROM STRING_SPLIT('1,2,3,4,5,6,7', ',')
	),
	äpplen (rad, antal_äpplen, antal_dagar) AS (
	SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)), * FROM @äpplen
	),
	utdelning(rad, dag, antal) AS (
		SELECT
			a.rad,
			d.dag,
			a.antal_äpplen/a.antal_dagar
		FROM dagar d INNER JOIN äpplen a ON d.dag <= a.antal_dagar
	)
SELECT [1], [2], [3], [4], [5], [6], [7] FROM utdelning
PIVOT (
	SUM(antal) FOR dag IN ([1], [2], [3], [4], [5], [6], [7])
) p;
-- CTE 2
WITH
	äpplen (rad, antal_äpplen, antal_dagar) AS (
	SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)), * FROM @äpplen
	), 
	b (rad, dag, antal)AS (
SELECT a.rad, x.value, a.antal_äpplen/a.antal_dagar FROM äpplen a
CROSS APPLY STRING_SPLIT('1,2,3,4,5,6,7', ',') x
WHERE x.value <= a.antal_dagar
)
SELECT [1], [2], [3], [4], [5], [6], [7] FROM b
PIVOT (
	SUM(antal) FOR dag IN ([1], [2], [3], [4], [5], [6], [7])
) p;
__________________
Senast redigerad av thesqlguru 2018-12-22 kl. 02:30.
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback