SQL-Profis: WITH innerhalb WHERE EXISTS?
Obermotz 12.10.2011 - 16:40 1519 7
Obermotz
Fünfzylindernazi
|
SELECT ... ghp, .., gpnr, GPID, ...... verdammtvieles
FROM gruppen G1
WHERE projektnr = 10460
AND vorzeichen = 'P'
AND pversion = ' '
AND mandant = 1
AND GHP = 0
AND GPID LIKE 'FED%'
AND EXISTS(
WITH n(gpid) as
(
SELECT gpid
FROM GRUPPEN G2
WHERE PROJEKTNR= 10460 AND GPID LIKE 'PA%'
UNION ALL
SELECT gpid
FROM GRUPPEN G3
WHERE GHP = 0
AND POSNR = GHP
)
SELECT 1 FROM n)
ORDER BY 12, Sortier_nr, gpid;
Im Zuge einer Umstellung von Oracle auf MS SQL Server versuche ih hier eine Hierarchie aufzulösen. Die Query sieht bisher gut aus, nur lässt der SQL Server das WITH innerhalb der WHERE EXISTS - Klausel nicht zu.Kennt jemand eine Alternative oder weiß wie man es besser machen können. Anm: Die Tabelle Gruppen wird hier übrigens als G1, G2 und G3 mehrmals mit sich selbst verglichen, nur zum besseren Verständnis. Der ursprüngliche Oracle - Syntax war eine START WITH... CONNECT BY PRIOR - Klausel, die es in MS SQL so leider nicht gibt..
Bearbeitet von Obermotz am 14.10.2011, 08:48
|
pong
Addicted
|
Und warum löst du das WITH nicht einfach als Subselect auf und näherst dich an ANSI ran?
btw. das ist kein SQL Problem sondern der typische Fall wenn man von einem DBMS den gesamten Facettenreichtum ausreizen will und sich jenseits jedes Standards bewegt :/
pong
|
Obermotz
Fünfzylindernazi
|
Das Problem ist, die ursprüngliche Oracle Query ist vermutlich über 10 Jahre alt. Es werden hier rekursiv Tabellen mit sich selbst verglichen (die Query ist schon vereinfacht). Als Programmierer und weniger DB-Spezialist würd ich den Schas ja gern auscodieren, aber bei den Datenmengen, die da geschaufelt werden steht das ausser Frage. Insofern versteh ich den Programmierer, der vor 10 Jahren das Statement reingeklopft hat, in dem todsicheren Wissen dass es sowieso niemals eine andere Enterprise-DB geben wird als Oracle ![;)](/images/smilies/wink.gif) Und von "(ANSI)Standards" brauch ich in dem Business gar nicht anfangen. In der realen Welt ist der Standard ein feuchter Sommertraum mancher Weltverbesserer ![:D](/images/smilies/biggrin.gif) Aber ja, es scheint eh keine andere Möglichkeit zu geben als das WITH aufzulösen oder vorher die Daten der Subselects in ne temporäre View zu schiessen.. // Ach ja, gerade nachgesehen .. WITH ist sogar ne ANSI-SQL Funktion. Wundert mich umso mehr dass der SQL Server die Klausel nicht innerhalb des WHERE EXISTS zulässt..
Bearbeitet von Obermotz am 13.10.2011, 10:09
|
Polyfire
Addicted
|
Evt. das With ganz an den Anfang vors erste Select. Schau mal in der MSSql Hilfe unter Common Table Expressions
|
pong
Addicted
|
Werden Stored Procedures bei euch zugelassen? Darfst temporäre Tabellen verwenden?
Dieser rekursive ****** gehört zu den Dingen auf dieser Welt die einfach verboten werden sollten. //sorry für die Bemerkung, ist aber so.
Wenn ich morgen oder am Weekend Zeit hab, versuch ichs dir aufzuschlüsseln.
pong
|
lowtekk
Little Overclocker
|
Bekommst du nicht bei der Ausführen die Warnung dass vor einem WITH ein semikolon stehen muss?
|
Muli
Little Overclocker
|
Hi! Ich seh keinen Grund warum du hier ein with benötigen würdest, oder überseh ich was? select somefoo
from gruppen g1
WHERE projektnr = 10460
AND vorzeichen = 'P'
AND pversion = ' '
AND mandant = 1
AND GHP = 0
AND GPID LIKE 'FED%'
and exists (select 1
from gruppen g2
where g1.projektnr = g2.projektnr
and g2.gpid like 'PA%'
union all
select 1
from gruppen g3
where g3.ghp = 0
and g3.posnr = g3.ghp -- ??
)
2te Variante wär das ganze mit 2 left outer joins zu bauen cheers
Bearbeitet von Muli am 14.10.2011, 08:34
|
Obermotz
Fünfzylindernazi
|
Werden Stored Procedures bei euch zugelassen? Darfst temporäre Tabellen verwenden?
Dieser rekursive ****** gehört zu den Dingen auf dieser Welt die einfach verboten werden sollten. //sorry für die Bemerkung, ist aber so.
Wenn ich morgen oder am Weekend Zeit hab, versuch ichs dir aufzuschlüsseln.
pong Danke, ich habs jetzt schlussendlich so gelöst. Erst mal mit einer Temporären Tabelle, die aber durch den Programmablauf und mehrere DB-Connections nicht geeignet war (wurde mitten im Ablauf wieder gelöscht, konnte nicht ganz nachvollziehen, an welcher Stelle). Ich schaufle die Daten vom WITH jetzt in einer Prepare-Funktion in eine View, diese lässt sich per Subselect problemlos in die WHERE EXISTS-Klausel einbinden.
|