"We are back" « oc.at

SQL-Profis: WITH innerhalb WHERE EXISTS?

Obermotz 12.10.2011 - 16:40 1519 7
Posts

Obermotz

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
Code: SQL
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
Avatar
Registered: Oct 2001
Location: Wien (ned im Kra..
Posts: 414
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
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
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 ;)

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

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
Avatar
Registered: Feb 2007
Location: .
Posts: 415
Evt. das With ganz an den Anfang vors erste Select.
Schau mal in der MSSql Hilfe unter Common Table Expressions

pong

Addicted
Avatar
Registered: Oct 2001
Location: Wien (ned im Kra..
Posts: 414
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
Avatar
Registered: Jul 2010
Location: Wien
Posts: 97
Bekommst du nicht bei der Ausführen die Warnung dass vor einem WITH ein semikolon stehen muss?

Muli

Little Overclocker
Registered: Mar 2001
Location: Ziersdorf
Posts: 105
Hi!

Ich seh keinen Grund warum du hier ein with benötigen würdest, oder überseh ich was?
Code: SQL
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
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
Zitat von pong
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.
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz