Sql waardes vergelijken uit 1 tabel

Status
Niet open voor verdere reacties.

Slikekster

Gebruiker
Lid geworden
11 jan 2010
Berichten
6
Ik zit met een klein slq dilemma, ik heb een database en datawarehouse opgebouwd en nu zit ik met de volgende marketing vraag: Is het mogelijk om een lijst te krijgen van klantgegevens en verkopen, waar de verkopen in 2009 2x zo klein zijn als de verkopen in 2008 of minderr.

Met de volgende Query lukt het me wel om alle totaalaankopen van de klanten in 2009 weer te geven, maar hoe kan ik dit vergelijken met de aankopen van 2008?
[sql]
SELECT
DMSA_DimCustomer.LastName, (SUM(DMSA_FactSales.TotalPurchase)) AS Totaal, DMSA_DimTime.YearNumber

FROM
DMSA_FactSales INNER JOIN
DMSA_DimProduct ON DMSA_FactSales.DimProductId = DMSA_DimProduct.ProductId INNER JOIN
DMSA_DimTime ON DMSA_FactSales.DimTimeId = DMSA_DimTime.TimeID INNER JOIN
DMSA_DimCustomer ON DMSA_FactSales.DimCustomerId = DMSA_DimCustomer.CustomerId

WHERE DMSA_DimTime.YearNumber = 2009

GROUP BY DMSA_DimCustomer.LastName, DMSA_DimTime.YearNumber
[/sql]
Deze query is gemaakt met de query builder van reporting services vandaar alle inner joins...
Moet ik me bezig gaan houden met Subqueries, Unions of intersects?
 
Laatst bewerkt door een moderator:
Je kunt een tabel inner joinen op zichzelf door beide een alias te geven, op die manier kun je data vergelijken met andere rijen in dezelfde tabel.

[sql]
SELECT *
FROM een_tabel as t1
INNER JOIN een_tabel as t2
WHERE t1.verkopen > t2. verkopen AND t1.artikel_code = t2.artikel_code AND t1.jaar = 2008 AND t2.jaar = 2009
[/sql]

Dit zou bijv. alle velden uit een tabel vissen waarbij het veld 'verkopen' in 2008 groter was dan in 2009.

Succes :)
 
Bedankt voor je reactie en ik snap ook je oplossing, helaas werkt niet niet voor mij :confused:

Weer even wat verder geprobeerd heb nu de volgende Query:
[SQL]SELECT Testanalysetabel.YearNumber, DMSA_DimCustomer.LastName, SUM(Testanalysetabel.TotalPurchase) AS Totaal, DMSA_DimProduct.ProductGroup
FROM Testanalysetabel AS t1 INNER JOIN
Testanalysetabel AS t2 INNER JOIN
DMSA_DimProduct ON Testanalysetabel.ProductId = DMSA_DimProduct.ProductId INNER JOIN
DMSA_DimCustomer ON Testanalysetabel.CustomerId = DMSA_DimCustomer.CustomerId

Where t1.Totaal > t2.Totaal AND t1.SalesId = t2.SalesId AND t1.YearNumber = 2008 AND t2.Yearnumber = 2009
Group By Testanalysetabel.YearNumber, DMSA_DimCustomer.LastName, DMSA_DimProduct.ProductGroup [/SQL]

Maar dit geeft de volgende foutmelding:

Msg 156, Level 15, State 1, Line 7
Incorrect syntax near the keyword 'Where'.
 
Laatst bewerkt:
Wat ik iig wel mis zie gaan is dat je bij je INNER JOIN nog verwijst naar Testanalysetabel, maar dat mag niet meer aangezien je beide kopien een andere naam hebt gegeven.

Je zult daar moeten verwijzen naar t1 en t2.
 
Gewijzigd :thumb: , krijg nog steeds de volgende foutmelding:

Msg 156, Level 15, State 1, Line 7
Incorrect syntax near the keyword 'Where'.

Ik krijg het idee dat ik iets met haakjes moet doen of verkeerd heb of is het iets anders?
 
Laatst bewerkt:
Ik zie erg veel fouten.

1. Heb je ook in de select de Testanalysetabel gewijzigd in t1/t2?

2. Je mist na de inner join met t2 de conditie waarop de join moet plaatsvinden (dus iets als "INNER JOIN Testanalysetabel AS t2 ON t1.CustomerId = t2.CustomerId")

3. Bij kolommen met group-functies als sum en count mag je deze kolommen niet gebruiken in een WHERE-clause. Jij doet dit nu wel met Totaal. Je kan wel een clause formuleren in een HAVING-clause.

4. In de where-clause zeg je t1.totaal > t2.totaal, maar je hebt maar 1 kolom totaal gedefinieerd in je select. Je hebt in je select zowel sum(t1.totalpurchase) als sum(t2..totalpurchase) nodig.

5. In de HAVING-clause mag je vervolgens niet de alias gebruiken (dus niet totaal) maar moet je de oorspronkelijke functies.kolommen gebruiken (dus weer sum(bla) herhalen.

Dit levert zoiets. Bevat wsl nog wel wat fouten, maar helpt je hopelijk op weg...
[SQL]SELECT t1.YearNumber, DMSA_DimCustomer.LastName, SUM(t1.TotalPurchase) AS Totaal2009, SUM(t2.TotalPurchase) AS Totaal2008, DMSA_DimProduct.ProductGroup
FROM Testanalysetabel AS t1
INNER JOIN Testanalysetabel AS t2
ON t1.SalesId = t2.SalesId
INNER JOIN DMSA_DimProduct
ON t1.ProductId = DMSA_DimProduct.ProductId
INNER JOIN DMSA_DimCustomer
ON t1.CustomerId = DMSA_DimCustomer.CustomerId
WHERE t1.YearNumber = 2008 AND t2.Yearnumber = 2009
GROUP BY t1.YearNumber, DMSA_DimCustomer.LastName, DMSA_DimProduct.ProductGroup
HAVING SUM(t1.TotalPurchase) > SUM(t2.TotalPurchase) [/SQL]

Succes, laat even weten of t wat wordt :)
 
Plagvreugd bedankt voor je reactie! Deze Query ziet er goed uit en geeft ook geen foutmeldingen. Helaas krijg ik geen resultaten maar alleen die kolomnamen te zien..terwijl er toch zeker weten goede data in de tabellen zit.. :( Dit heeft te maken met deze Inner Join: Testanalysetabel AS t2 ON t1.SalesId = t2.SalesId, als ik hem laat joinen op CustomerId of ProductId krijg ik wel resultaten alleen kloppen deze resultaten niet.
Kan ik de tabel nog op een andere manier met zichzelf joinen?
 
Laatst bewerkt:
Hi,

Krijg je bij deze query wel resultaten:

[SQL]SELECT *
FROM (select * from Testanalysetabel
where YearNumber = 2008) AS t1
INNER JOIN
(select * from Testanalysetabel
where YearNumber = 2009) AS t2
ON t1.SalesId = t2.SalesId [/SQL]

Als er geen resultaten uit komen ligt het aan je data. Als er wel resultaten aan komen is er iets mis met de query, al zou ik niet echt weten wat.
 
Is het mogelijk om een lijst te krijgen van klantgegevens en verkopen, waar de verkopen in 2009 2x zo klein zijn als de verkopen in 2008 of minderr.

Ik weet niet of je ondertussen al een oplossing hebt. Ik heb er over nagedacht en ik zou het zo aanpakken. Ik heb al een tijdje niks meer met SQL gedaan, dus er kunnen fouten in zitten.

waar de verkopen in 2009
Aan je code te zien bedoelde je hier de opbrengst van de verkopen over dat jaar.

[SQL] (SELECT client, SUM(purchaseTotal) as totalPurchase
FROM sales
WHERE year = 2009
GROUP BY client) as s2009 [/SQL]

de verkopen in 2008
Hetzelfde maar voor 2008
[SQL] (SELECT client, SUM(purchaseTotal) as totalPurchase
FROM sales
WHERE year = 2008
GROUP BY client) as s2008 [/SQL]

Vervolgens wil je het per klant vergelijken, dus moet je deze koppelen. Alle klanten van 2008 moeten hierin voorkomen. Ook wanneer zij in 2009 eventueel geen aankopen hebben gedaan:

[SQL](SELECT client FROM
(SELECT client, SUM(purchaseTotal) as p2008
FROM sales
WHERE year = 2008
GROUP BY client) as s2008
LEFT OUTER JOIN
(SELECT SUM(purchaseTotal) as p2009
FROM sales
WHERE year = 2009
GROUP BY client) as s2009
ON s2008.client = s2009.client
WHERE (p2008/2) >= p2009) as decliningclients [/SQL]

Bovenstaande query geeft een resultset met klantids waar de klant voorkomt in 2008 en de som van aankoopbedragen van 2008 gedeeld door 2 groter is dan de som van aankoopbedragen van 2009 of NULL.

Vervolgens wil je die nog combineren met de klantentabel voor de klantgegevens. Je selecteert alle informatie van alle client id's die voorkomen in de eerder genoemde resultset:

[SQL] SELECT clients.*
FROM clients
WHERE clients.id IN
(SELECT client
FROM
(SELECT client, SUM(purchaseTotal) as p2008
FROM sales
WHERE year = 2008
GROUP BY client) as s2008
LEFT OUTER JOIN
(SELECT SUM(purchaseTotal) as p2009
FROM sales
WHERE year = 2009
GROUP BY client) as s2009
ON s2008.client = s2009.client
WHERE (p2008/2) >= p2009) [/SQL]
 
Laatst bewerkt:
Bedankt JP Romijn voor je hulp, helaas wil het me nog steeds niet lukken, heb nu de volgende query:
[SQL](SELECT CustomerId FROM
(SELECT CustomerId, SUM(TotalPurchase) AS p2008
FROM Testanalysetabel
WHERE YearNumber = 2008
GROUP BY CustomerId) AS s2008
LEFT OUTER JOIN
(SELECT SUM(TotalPurchase) AS p2009
FROM Testanalysetabel
WHERE Yearnumber = 2009
GROUP BY CustomerId) AS s2009
ON s2008.CustomerId = s2009.CustomerId
WHERE (p2008/2) >= p2009)[/SQL]

Dit geeft de volgende foutmeling:
Msg 207, Level 16, State 1, Line 11
Invalid column name 'CustomerId'.

Als ik dan de query opsplits en bijv. alleen deze query doe:
[SQL] (SELECT CustomerId, SUM(TotalPurchase) AS totalPurchase
FROM testanalysetabel
WHERE yearnumber = 2009
GROUP BY Customerid) AS s2009[/SQL]

Krijg ik de volgende foutmelding:
Msg 156, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'AS'.

Als ik AS s2009 weghaal werkt de query wel, het lukt dus niet om na Group By een alias te geven aan iets.
 
Laatst bewerkt:
[SQL](SELECT CustomerId FROM
(SELECT CustomerId, SUM(TotalPurchase) AS p2008
FROM Testanalysetabel
WHERE YearNumber = 2008
GROUP BY CustomerId) AS s2008
LEFT OUTER JOIN
(SELECT CustomerId, SUM(TotalPurchase) AS p2009
FROM Testanalysetabel
WHERE Yearnumber = 2009
GROUP BY CustomerId) AS s2009
ON s2008.CustomerId = s2009.CustomerId
WHERE (p2008/2) >= p2009)[/SQL]

Misschien helpt het als we bij tabel 's2009' ook de CostrumerId selecteren.
 
Laatst bewerkt:
Bedankt ik krijg resultaten met de volgende Query:

[SQL] (SELECT * FROM
(SELECT CustomerId, SUM(TotalPurchase) AS p2008
FROM Testanalysetabel
WHERE YearNumber = 2008
GROUP BY CustomerId) AS s2008
LEFT OUTER JOIN
(SELECT CustomerId, SUM(TotalPurchase) AS p2009
FROM Testanalysetabel
WHERE Yearnumber = 2009
GROUP BY CustomerId) AS s2009
ON s2008.CustomerId = s2009.CustomerId
WHERE (p2008/2) >= p2009)[/SQL]

406 rows met kloppende data!! Iedereen erg bedankt zover, ik kom hiermee al een stuk verder :thumb:
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan