22. september 2005 - 22:28Der er
15 kommentarer og 1 løsning
union og top n? er det umuligt?
Jeg ønsker at vise en top 100 og en buttom 5%, er det muligt ved hjælp af union?
jeg får nemlig en fejl ved union:
her er min T-sql:
use northwind SELECT TOP 100 productid, quantity , unitprice, SUM(quantity*unitprice) as akk FROM [order details] GROUP BY productid, quantity, unitprice ORDER BY SUM(quantity*unitprice) DESC UNION SELECT TOP 5 productid, quantity, unitprice, SUM(quantity*unitprice) FROM [order details] GROUP BY productid, quantity, unitprice ORDER BY SUM(quantity*unitprice)
Server: Msg 156, Level 15, State 1, Line 5 Incorrect syntax near the keyword 'ORDER'. Server: Msg 156, Level 15, State 1, Line 12 Incorrect syntax near the keyword 'ORDER'.
tidligere nævnte fejl UDEN anvendelse af (..)UNION(..): Server: Msg 156, Level 15, State 1, Line 6 Incorrect syntax near the keyword 'UNION'.
select * from ( SELECT TOP 100 productid, quantity , unitprice, SUM(quantity*unitprice) as akk FROM [order details] GROUP BY productid, quantity, unitprice ORDER BY SUM(quantity*unitprice) DESC ) X1 UNION ALL select * from ( SELECT TOP 5 productid, quantity, unitprice, SUM(quantity*unitprice) FROM [order details] GROUP BY productid, quantity, unitprice ORDER BY SUM(quantity*unitprice) ) X2
Men - for pokker det vil stinke performancemæssigt...
TOP'en begrænser ikke forespørgslen kun de udledte data, dvs. at sql server skal lave hele udtrækket og sortere det ud fra en computed column for hele din tabel - og så blot levere de hhv 100 første og 5 sidste rækker... Check hellere afsnittet om "Creating Indexes on Computed Columns" i Books Online.
Dog en lille tilføjelse: Hvis det er bottom 5% der skal hentes i den sidste del af union, bør det vel hedde:
select * from ( SELECT TOP 100 productid, quantity , unitprice, SUM(quantity*unitprice) as akk FROM [order details] GROUP BY productid, quantity, unitprice ORDER BY SUM(quantity*unitprice) DESC ) X1 UNION ALL select * from ( SELECT TOP 5 PERCENT productid, quantity, unitprice, SUM(quantity*unitprice) FROM [order details] GROUP BY productid, quantity, unitprice ORDER BY SUM(quantity*unitprice) ) X2
Desuden, uden at vide hvad det skal bruges til, så ku' det jo også være det ville være en idé at angive, hvad de to dele indeholdt:
select 'Top 100' AS Segment, X1.* from ( SELECT TOP 100 productid, quantity , unitprice, SUM(quantity*unitprice) as akk FROM [order details] GROUP BY productid, quantity, unitprice ORDER BY SUM(quantity*unitprice) DESC ) X1 UNION ALL select 'Bottom 5%', X2.* from ( SELECT TOP 5 PERCENT productid, quantity, unitprice, SUM(quantity*unitprice) FROM [order details] GROUP BY productid, quantity, unitprice ORDER BY SUM(quantity*unitprice) ) X2
Jeg sidder og undrer mig over, hvorfor quantity er med (eller vel snarere hvorfor der ikke er en SUM på det felt. unitprice er vel rimeligt statisk, men quantity må da ændre sig hele tiden, så hvad får man ud af at gruppere på det felt, andet end en masse ubrugelige data.
Nå, spørgeren har vel tænkt over, hvad han ønsker sig... :-)
kjulius, trer: smid et svar og jeg fordeler point. Kort og godt var det kun for at bruge UNION til at samle de to dataset til et enkelt og forventede at jeg havde overset et eller andet, idet begge dataset fungerede fint hver for sig. Der er tale om øvelse, hvor opgaven var simplere end regnet. Løste opgaven som jeg skulle samle de to dataset i ét... men sådan var det åbenbart ikke ment.. undskylder ulejligheden, men er blevet en del klogere... smid svar og jeg vil fordele point til jer.
trer > 'God SQL, den ser ud til at kunne holde hjem! :-)'
så er jeg kommet hjem til egen box, og forsøger jeres foreslag, men får en fejl: Server: Msg 8155, Level 16, State 2, Line 1 No column was specified for column 4 of 'X2'.
... så helt hjem holder den vist ikke ;-). PROCENT, ved anvenelse af TOP, er dog uvedkommende, fejlen taget i betragtning. Målet var som sagt at bruge UNION hvis det var muligt.
.... men forslaget manglede et alias i nederste SELECT statement, så kører det. Venter stadig svar fra trer, før jeg fordeler point.
Der er lidt forskel på hvor striks de forskellige databaser er mht. at feltnavne skal være angivet på sekundære selects i en union. Nogle databaser bruger bare feltnavnet fra den primære.
--> trer/Troels: Ja, jeg tog lige et kig på dit "CV", og kan se, at du er godt ved "muffen". Imponerende placering på ranglisten! Især fordi det er første gang jeg har "truffet" dig herinde, tror jeg. Måske "mødes" vi jo igen en anden gang.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.