Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Top bei Union Abfrage (https://www.delphipraxis.net/131915-top-bei-union-abfrage.html)

PASST 2. Apr 2009 16:28

Datenbank: ADS • Version: 9.1 • Zugriff über: TADS

Top bei Union Abfrage
 
Hallo allerseits,

ich benötige Hilfestellung zu einer Abfrage mit TOP im Zusammenhang mit UNION.
Zum Bsp suche ich zu jedem Land jeweils die Top 10 Kunden.
SQL-Code:
select top 10 land, kunde, sum(umsatz)
from auswertung
where land = 'Deutschland'
group by kunde
order by sum(umsatz) DESC
Durch "umsatz DESC" erreiche ich, dass die umsatzstärksten Kunden angezeigt werden.
Versuche ich jetzt die Top10-Kunden verschiedener Länder zusammenzufügen, klappt das nicht
SQL-Code:
select top 10 land, kunde, sum(umsatz)
from auswertung
where land = 'Deutschland'
group by kunde

union

select top 10 land, kunde, sum(umsatz)
from auswertung
where land = 'Niederlande'
group by kunde

union

select top 10 land, kunde, sum(umsatz)
from auswertung
where land = 'Belgien'
group by kunde

order by land, umsatz DESC
In diesem Fall werden nicht die umsatzstärksten sondern die umsatzschwächsten Kunden des jeweiligen Landes angezeigt. Der Kompiler akzeptiert auch nicht, dass "order by" nicht hinter jede Einzelabfrage gestellt wird.

Hat jemand eine Idee wie ich diese Abfrage erfolgreich zusammenbasteln kann?

Gruß
Peter

Zwoetzen 2. Apr 2009 17:02

Re: Top bei Union Abfrage
 
SQL-Code:
SELECT TOP 10 * 
FROM (

select land, kunde, sum(umsatz)
from auswertung
where land = 'Deutschland'
group by kunde

union

select land, kunde, sum(umsatz)
from auswertung
where land = 'Niederlande'
group by kunde

union

select land, kunde, sum(umsatz)
from auswertung
where land = 'Belgien'
group by kunde

)
ORDER BY land, umsatz DESC
Sollte so eigentlich passen ;)

EDIT: Oder die Top10 jedes Landes, sodass am Ende hier 30 Datensätze rauskommen sollen? Dann nur das ORDER BY in eine Überabfrage, und die SELECT TOP 10 in den UNIONs beibehalten.
Bin grad ein wenig verwirrt ^^

gmc616 2. Apr 2009 17:06

Re: Top bei Union Abfrage
 
Mit "Order By" wird die komplette Abfrage (alle Union Select) sortiert.
Man kann im "Order By" die Spalte angeben, nach der sortiert werden soll.

SQL-Code:
Order by 1 asc, 2 desc;

mkinzler 2. Apr 2009 17:06

Re: Top bei Union Abfrage
 
Unterstützt ADS Derived Tables?
SQL-Code:
Select Top 5 from (<Union-Abfrage>);

joachimd 2. Apr 2009 19:41

Re: Top bei Union Abfrage
 
Zitat:

Zitat von mkinzler
Unterstützt ADS Derived Tables?
SQL-Code:
Select Top 5 from (<Union-Abfrage>);

Ist im Prinzip ja die Lösung von Zwoetzen ... nur eine Änderung: Die Tabelle muss mit einem Alias spezifiziert werden.

SQL-Code:
Select Top 5 a.* from (<Union-Abfrage>) a;

PASST 3. Apr 2009 08:18

Re: Top bei Union Abfrage
 
Leider führt keiner der Vorschläge zum Ergebnis, was ich suche.

Ich komme wahrscheinlich nicht herum jeweils einzelne Abfrage auszuführen, die Resultate in eine temporäre Tabelle zu speichern und diese dann wieder abzufragen.

Das Arbeiten mit temporären Tabellen scheint bei komplexen Abfragen unter SQL-Servern üblich zu sein oder hat jemand eine andere Idee?

Gruß
PEter

joachimd 3. Apr 2009 09:43

Re: Top bei Union Abfrage
 
eine Abfrage mit vorgegebenen Ländern:
SQL-Code:
select * from
(
  select top 5 * from #test where land='DE' order by umsatz desc
) a
union select * from

  select top 5 * from #test where land='NL' order by umsatz desc
) b
union select * from

  select top 5 * from #test where land='UK' order by umsatz desc
) c
union select * from

  select top 5 * from #test where land='FR' order by umsatz desc
) d
union select * from

  select top 5 * from #test where land='IT' order by umsatz desc
) e

order by land
eine Lösung über ein Script mit temp Tabelle kommt gleich ;)

joachimd 3. Apr 2009 09:51

Re: Top bei Union Abfrage
 
So, hier nun eine Script-Lösung, die absolut flexibel ist. Es ist im Prinzip egal, wieviele Felder in der Quelltabelle (hier #test) stehen. Die letzte Abfrage erstellt dann aus der ID-Liste (#result) das, was Du schliesslich benötigst.
Übrigens: Du musst das nicht als Stored Procedure anlegen. Einfach komplett in eine TAdsQuery verpacken und gut.

SQL-Code:
declare c cursor as select distinct(land) from #test;

try
  drop table #result;
catch all
end try;

create table #result(id integer);

open c;
while fetch c do
  insert into #result select top 5 id from #test where land=c.land order by umsatz desc;
end while;
close c;

select a.* from #test a
  inner join #result b on a.id=b.id
order by land, umsatz desc

nahpets 3. Apr 2009 09:54

Re: Top bei Union Abfrage
 
Hallo,

guck mal bitte, ob dat jeht:

SQL-Code:
select top 10 * from (
  select top 10 land, kunde, sum(umsatz) As Umsatz from auswertung where land = 'Deutschland' group by kunde order by 3
) de
union all
select * from (
  select top 10 land, kunde, sum(umsatz) As Umsatz from auswertung where land = 'Niederlande' group by kunde order by 3
) ne
union all
select * from (
  select top 10 land, kunde, sum(umsatz) As Umsatz from auswertung where land = 'Belgien' group by kunde order by 3
) be
order by land, umsatz DESC
Habe gerade was analoges mit anderen Daten probiert, das Ergebnis sah plausibel aus.

PASST 3. Apr 2009 13:36

Re: Top bei Union Abfrage
 
Danke, die letzten Vorschläge von nahpets und joachimd haben funktioniert. Das Skript habe ich jetzt nicht ausgeführt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz