![]() |
Datenbank: SQL-Server 2000 • Zugriff über: BDE
left join NULL
Hallo,
habe folgende abfrage select a.menge as bestand, b.menge as reserviert, (a.menge - b.menge) as diff from tab1 a left join tab2 b on (a.name = b.name) Bekomme auch für alle Artikel (tab1) die Differenz, außer bei den Artikeln wo keine reservierung besteht (kein Datensatz in Tab2), da bekomme ich diff = NULL. Klar da menge - Null = Null richtig wäre aber: menge - NULL = menge Wie bekomme ich das hin? Danke jangbu |
Re: left join NULL
Nach Null abfragen ( IIF(), CASE..WHEN, NullIF())
|
Re: left join NULL
Hallo,
so sollte es gehen:
SQL-Code:
select
a.menge as bestand, b.menge as reserviert, (IsNull(a.menge,0) - IsNull(b.menge,0)) as diff from tab1 a left join tab2 b on (a.name = b.name) |
Re: left join NULL
super Danke!
jangbu |
Re: left join NULL
Zitat:
Zum Vergleich: Unendlich+1 ist immer noch Unendlich |
Re: left join NULL
Hallo Joachim,
im Prinzip dürftes Du hier recht haben. Im aktuellen Beispiel sieht mir das aber eher so aus: Wir haben eine 1:1-Beziehung, bei der man (aus Bequemlichkeit?) auf die 1 hinter dem : verzichtet, sofern dort nur 0 als Wert vorhanden ist. Es dürfte hier wohl korrekter sein, diesen Satz auch dann anzulegen, wenn b.menge = 0 ist. Für meine Begriffe eine häufig verwendete Unsitte, die die Abfragen unnütz kompilziert machen. Bei "ordentlicher" Ausmodellierung und konsequenter Umsetzung dürfte so manch ein Left Join überflüssig sein und sich oben vorgeschlagene Konstrukte erübrigen. |
Re: left join NULL
Hab jetzt aber doch noch mal eine Frage dazu:
die Tabelle bestand (a) ist 1:n mit der Tabelle reserviert (b) verknüpft. Es kann also für einen Artikel in (a) mehrer reservierungen in (b) geben. Für den Fall einer 1:1 Beziehnung klappt folgende Abfrage (auch wenn überhauptkeine Reservierungen bestehen)
SQL-Code:
Wie bekomme ich jedoch die Differenz - also den verfügbaren Bestand - heraus, wenn es mehrere reservierungen gibt, ich also die "Summe der reservierungen" vom Bestand abziehen muss?
select
a.menge as bestand, b.menge as reserviert, (IsNull(a.menge,0) - IsNull(b.menge,0)) as diff from tab1 a left join tab2 b on (a.name = b.name) Durch den left join bekomme ich soviele Zeilen zurück wie es reservierungen gibt, brauche aber nur eine, müsste vorher in der rechten tabelle die summe bilden. jangbu [edit=mkinzler]SQL-Tag eingefügt Mfg, mkinzler[/edit] |
Re: left join NULL
Hallo jangbu,
Zitat:
In meiner Erinnerung sind die MS-Views aber elend langsam. warum gibt es eigentlich mehrere einträge mit Reservierung? Gruß K-H |
Re: left join NULL
Hallo,
mal ein nicht getesteter Versuch:
SQL-Code:
select
Bestand, Reserviert, Bestand - Reserviert As Diff from ( select a.Name, Max(IsNull(a.Menge,0)) As Bestand, /* Sollte immer der gleiche Wert sein. */ Sum(IsNull(b.Menge,0)) As Reserviert from tab1 a left join tab2 b on (a.Name = b.Name) Group By a.Name ) intern |
Re: left join NULL
müsste auch über eine einfache Gruppierung gehen:
SQL-Code:
Je nach DBMS ist diese Variante schneller.
select
a.Bestand, b.Reserviert, a.Bestand - ifnull(b.Reserviert,0) As Diff from tab1 a left outer join ( select Name, Sum(Menge) As Reserviert -- Aggregatfunktionen ignorieren NULL-Werte from tab2 Group By 1 ) b on a.name=b.name Übrigens: Verzichte bitte auf die Verknüpfung über den Namen und nimm einen nichtssagenden Schlüssel (Primary Key, Autoinc -bäh- oder GUID). Einmal den Namen falsch geschrieben, findest Du die richtige Menge nicht mehr. Und noch eine ganz exotische Geschichte, die eventuell noch mehr Performance bringen kann - und vor allem auch hilft, falls Du mehrere Bestände des gleichen Artikels in Tab1 hast:
SQL-Code:
select
name, sum(bestand) as bestand, sum(reserviert) as reserviert, sum(bestand)-sum(reserviert) as diff from ( select name, bestand, 0 as reserviert from tab1 union select name, 0 as bestand, reserviert from tab2 ) group by 1 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz