Laden...

[SQL Server 8.0 SP3] is not null bei left join

Erstellt von bayeror vor 18 Jahren Letzter Beitrag vor 18 Jahren 2.562 Views
bayeror Themenstarter:in
21 Beiträge seit 2004
vor 18 Jahren
[SQL Server 8.0 SP3] is not null bei left join

Hallo!
Ich möcht gern bei einem Select ein left gejointes feld mit is not null abfragen.
also:


    SELECT asst.ASST_Ref a,
           asst.ASST_Type b,
           asst.ASST_TRANS_Desc c,
           asst.ASST_State d,
           trans.TRANS_Ref,
           [B]trans.TRANS_Text e,[/B]
           ISNULL(TRANS_Text, '?') f
      FROM MM_TRANSLATION   trans,
           MM_ASSET_TYPE    asst
     WHERE 
       trans.TRANS_Text like '%'
       AND trans.LANG_Ref  = 1
       AND asst.COM_Ref    = 1
       [B]AND asst.ASST_TRANS_Desc *= trans.TRANS_Ref[/B]
       [B]AND e is not null[/B]

Ausgabe sieht so aus:


a           b       c           d           TRANS_Ref   e                   f                   
----------- ------- ----------- ----------- ----------- ------------------- --------------------
93          GC      1           10          1           Schwerkraftbahn     Schwerkraftbahn
94          LD      -1          10          NULL        NULL                ?
95          LT      -1          10          NULL        NULL                ?
96          CC      -1          10          NULL        NULL                ?
97          TC      -1          10          NULL        NULL                ?
98          VC      -1          10          NULL        NULL                ?
99          RC      -1          10          NULL        NULL                                                                                                                                                                                         

Die NULLs werden also nicht ausgemustert! Eigentlich sollte nur der erste Datensatz angezeigt werden. Ein Join auf "f" also "f != '?' " wird mir ignoriert.

Ich habs auch schon versucht diesen Select als Subselect zu machen also:


select * from(
select....(siehe oben)
) tbla
where tbla.f is not null

Dies zeigte aber auch keine Wirkung...

Ich hab schon ein paar Leute gefragt, die mir das erst nicht glauben wollten, und als sie es sahen dann ratlos waren. Mein Kopf raucht... weiß echt nicht mehr weiter!
Ich hoffe mir kann von euch jemand helfen!
Danke schon mal!

Achja, noch ne kleine Bemerkung:
Zu evtl. kommenden Fragen, wie z.B. "warum machst du einen left-Join und streichst die so dazugewonnenen Daten mit 'is not null' wieder raus?" möchte ich gleich sagen (und bitte nicht in den falschen Hals kriegen):
Der Select is sonst OK. Mir geht es rein um das "is not null"!

1.696 Beiträge seit 2006
vor 18 Jahren

es funz nicht, weil es NOT IS NULL heisst 🙂

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

bayeror Themenstarter:in
21 Beiträge seit 2004
vor 18 Jahren

Danke für die Antwort, aber is not null is schon richtig

S
8.746 Beiträge seit 2005
vor 18 Jahren

Mal explizites Inner Join probiert?

1.696 Beiträge seit 2006
vor 18 Jahren

Original von svenson
Es funzt nicht, weil die Abfrage überhaupt kein Join ist, ich sehe zumindest weit und breit kein JOIN.

doch das ist cross join

@bayeror, sorry wegen not is null, du hast recht.

IMHO darf man Alias nicht in Where verwenden, daher funz das nicht.

... AND trans.TRANS_Text is not null sollte helfen

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

S
8.746 Beiträge seit 2005
vor 18 Jahren

Sollte hier nicht ein INNER JOIN anstelle des Cross Joins verwendet werden?

bayeror Themenstarter:in
21 Beiträge seit 2004
vor 18 Jahren

Original von vbprogger

Original von svenson
Es funzt nicht, weil die Abfrage überhaupt kein Join ist, ich sehe zumindest weit und breit kein JOIN.
doch das ist cross join

@bayeror, sorry wegen not is null, du hast recht.

IMHO darf man Alias nicht in Where verwenden, daher funz das nicht.

... AND trans.TRANS_Text is not null sollte helfen

kein problem 🙂

Alias geht schon in der Where-Klausel. Wenn ich deine Version versuche, komm ich auch zum gleichen Ergebnis...

bayeror Themenstarter:in
21 Beiträge seit 2004
vor 18 Jahren

Original von svenson
Sollte hier nicht ein INNER JOIN anstelle des Cross Joins verwendet werden?

Sry, mein Sqlisch is nicht das beste... aber ich mach doch hier nen left outer join, oder nicht?

AND asst.ASST_TRANS_Desc *= trans.TRANS_Ref
S
8.746 Beiträge seit 2005
vor 18 Jahren

Nee, der Select über Tabellen mit where ist ein Cross-Join, wie mich vbprogger richtigerweise korrigierte. Probier mal INNER JOIN, das sollte funzen.

Abe ehrlich gesagt: Dein Code sollte auch funzen, auch wenn er weniger performant als ein INNER JOIN ist. Du machst erst eine riesige Kreuztabelle (jeder mit jedem) und wirfst dann alles raus, was offenbar keine Beziehung hat (Referenz-Feld == NULL). Der INNER JOIN baut von vornherein nur eine Tabelle mit den Paaren, die auch verknüpft sind. Bin auch ein wenig ratlos.

*EDIT* Ah, du verwendest den "=*"-Operator, der ja einen outer join angeben soll. Vielleicht ist der nicht mehr supported, denn eigentlich:

"In earlier versions of Microsoft® SQL Server™ 2000, left and right outer join conditions were specified in the WHERE clause using the = and = operators. In some cases, this syntax results in an ambiguous query that can be interpreted in more than one way. SQL-92 compliant outer joins are specified in the FROM clause and do not result in this ambiguity. Because the SQL-92 syntax is more precise, detailed information about using the old Transact-SQL outer join syntax in the WHERE clause is not included with this release. The syntax may not be supported in a future version of SQL Server. Any statements using the Transact-SQL outer joins should be changed to use the SQL-92 syntax."

Verwende einfach mal die neue Syntax, aber wie gesagt, ich denke, dass ein Inner-Join das ist was du willst. Du willst ja nur dann einen ASSET_TYPE haben, wenn es dazu eine passende TRANSLATION gibt, oder?

bayeror Themenstarter:in
21 Beiträge seit 2004
vor 18 Jahren

Der *= Operator Funktioniert schon, und dass ich einen outer und keinen inner Join verwende ist Absicht. Das von mir gepostete Statement ist sozusagen nur die "halbe Wahrheit". Der Select wäre noch etwas komplexer geworden, da der Select in einem Such-Dialog eingetzt wird z.B. (trans.TRANS_Text like @transText or @transText = null) usw. Aber haben wir jetzt anders gelöst, indem wir die Abfrage in mehrere Selects aufgesplittet haben. Ist performanter.

Aber rein Interessenhalber... ich verstehs trotzdem nicht:


SELECT * from (
    SELECT asst.ASST_Ref a,
           asst.ASST_Type b,
           asst.ASST_TRANS_Desc c,
           asst.ASST_State d,
           trans.TRANS_Ref,
           trans.TRANS_Text e,
           ISNULL(TRANS_Text, 'abcdefg') f
      FROM MM_TRANSLATION   trans,
           MM_ASSET_TYPE    asst
     WHERE 
       trans.TRANS_Text like '%'
       AND trans.LANG_Ref  = 1
       AND asst.COM_Ref    = 1
       AND asst.ASST_TRANS_Desc *= trans.TRANS_Ref
) tbla
where e is not like null

oder auch


SELECT * from(
....
) tbla
where f != 'abcdefg'

bringt mir auch die Datensätze mit TRANS_Text = null zurück. Ein Join auf ein ASSET_TYPE-Feld z.B. ASST_Type funktioniert, aber auf betroffene Felder des outer Joins wird ein Equi-Join ignoriert. Könnte ich verstehen, wenns beim inneren Select Probleme gäbe, aber beim äußeren?? Dem letzteren sollte es doch eigentlich völlig egal sein, was im Inneren genau vorgeht, ob outer Join oder nicht. Er bekommt ein Result Set welches eigentlich einem temporärem Table gleich kommen sollte, mit welchem es übrigens auch funktioniert!

Ich hab mir einige Meinungen von Leuten die sich mit Datenbanken, meist leider nur ORACLE, auskennen eingeholt. Die waren fest der Überzeugung, dass das Statement, so wie gepostet, richtig funktionieren sollte. Da sollte doch kein Unterschied zwischen Microsoft und Oracle sein, ist doch nix spezielles, sondern rein SQL, oder nicht?
Würde mich echt interessieren was da vorgeht. Wenn da wer was weiß, würds mich freuen von ihm zu hören!

1.696 Beiträge seit 2006
vor 18 Jahren

was bekommst du bei

 
    SELECT asst.ASST_Ref a,
           asst.ASST_Type b,
           asst.ASST_TRANS_Desc c,
           asst.ASST_State d,
           trans.TRANS_Ref,
           trans.TRANS_Text e,
           ISNULL(TRANS_Text, 'abcdefg') f
      FROM MM_TRANSLATION   trans 
                LEFT JOIN
           MM_ASSET_TYPE    asst
                ON asst.ASST_TRANS_Desc = trans.TRANS_Ref
     WHERE 
       trans.TRANS_Text is not null
       AND trans.LANG_Ref  = 1
       AND asst.COM_Ref    = 1

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

B
483 Beiträge seit 2005
vor 18 Jahren

CASE zu benutzen
TRANS_Text=isnull CASE WHEN ...

bayeror Themenstarter:in
21 Beiträge seit 2004
vor 18 Jahren

boco25: Mit CASE kan man afaik nur die Daten an sich verändern, aber nicht aussortieren.

danke vbprogger!
so gehts!
Dass *= solche Probleme macht!?! Der Join an sich wird ja richtig durchgeführt...Komisch.

Weißt du auch wieso sich das Verhalten von *= auch außerhalb des inline views, also im äußeren select fortführt?

1.696 Beiträge seit 2006
vor 18 Jahren

nö, kann ich nichts dazu sagen, denn ich verwende solche syntaktischen Abkürzungen nicht, höchstens bei += in Oracle, aber Oracle kommt bei mir noch seltener als der Weihnachtsmann zum Einsatz 😁

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::