Softpicks.Net  Deutsch Foren-Übersicht Softpicks.Net Deutsch
Software Forum Deutsch
 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen   RegistrierenRegistrieren 
 ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Abfrage-Problem

 
Neues Thema eröffnen   Neue Antwort erstellen    Softpicks.Net Deutsch Foren-Übersicht -> SQL Server
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Jürgen Volke



Anmeldedatum: 01.01.1970
Beiträge: 725

BeitragVerfasst am: Do Okt 11, 2007 7:41 am    Titel: Abfrage-Problem Antworten mit Zitat



Hallo Michael

>
> folgendes Szenario und Tabellenaufbau:
>
> Rechnungstabelle: (mit 3-4 Datensätzen)
>
> RechID | .......
> --------------------
> 100 | ........
> 101 | ........
> 102 | ........
> 103 | ........
>
>
> Historytabelle: (enthält Daten, wer wann was an den Rechnungen
> --------------- gemacht/-ändert hat) (mit 3-4 Datensätzen)
>
> RechID | Vorgang | PersonalID
> --------------------------------------
> 100 | 1 | ...........
> 101 | 1 | ...........
> 102 | 1 | ...........
> 103 | 1 | ...........
> 100 | 2 | ...........
> 101 | 2 | ...........
>
>
> Beschreibung: die Vorgangsnummern in der Historytablle spiegeln immer
> eine
> Aktion wieder => 1 steht z.B. für "Rechnung erstellt" ... 2 für "Rechnung
> gedruckt"
>
> Wie bekomme ich nun raus, welche Rechnung alle NICHT GEDRUCKT sind?
> (demnach NICHT den Vorgang 2 haben)
>
> Wie man rausbekommt, wie viele Rechnungen gedruckt sind liegt auf der
> Hand:
> SELECT COUNT(*) AS count
> FROM Rechnungstabelle INNER JOIN
> Historytabelle ON Rechnungstabelle.RechID =
> Historytabelle.RechID
> WHERE (Historytabelle.Vorgang = 2)
>
>
> Jedoch suche ich die umgekehrte Aktion: NICHT GEDRUCKTE RECHNUNGEN
>
> Habe es schon mit WHERE <> 2 bzw. NOT =2 versucht...
>
> SELECT COUNT(*) AS count
> FROM Rechnungstabelle INNER JOIN
> Historytabelle ON Rechnungstabelle.RechID =
> Historytabelle.RechID
> WHERE NOT (Historytabelle.Vorgang = 2)
>
> jedoch gibt er mir
> dort alle zurück, weil die entsprechende RechID jeweils mehrmals in der
> Historytabelle vorkommt, da eine Rechnung ja mehrere Prozesse durchläuft
> (Erstellung, Drucken, Zusenden, etc.)
>
>
> Wer kann mir helfen das ich die gewünschen NICHT GEDRUCKTEN Rechnungen
> bekomme!?

in etwa:
SELECT * FROM Rechnungstabelle
WHERE RECHID NOT IN
(SELECT RECHID FROM Historientabelle WHERE Vorgang = 2)

HTH Jürgen


.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Dieter Noeth



Anmeldedatum: 01.01.1970
Beiträge: 241

BeitragVerfasst am: Sa Okt 13, 2007 4:16 pm    Titel: Abfrage-Problem Antworten mit Zitat



Roland Dick wrote:

>> SELECT * FROM Rechnungstabelle
>> WHERE RECHID NOT IN
>> (SELECT RECHID FROM Historientabelle WHERE Vorgang = 2)
>
> Oder auch mit einem LEFT JOIN:
>
> SELECT * FROM Rechnungstabelle
> LEFT JOIN Historytabelle
> ON Rechnungstabelle.RechID = Historytabelle.RechID
> AND Historytabelle.Vorgang = 2
> WHERE Historytabelle.RechID IS NULL
>
> Das ist nach meinem Wissen etwas performanter, weil IN eine
> möglicherweise grosse Datenmenge "zwischenspeichern" muss.

Wieso nicht einfach die 1:1 Übersetzung der Ausgangsfrage?
EXISTS ist meistens die effizienteste Lösung:

SELECT * FROM Rechnungstabelle r
WHERE NOT EXISTS
(SELECT * FROM Historytabelle h
WHERE r.RechID = h.RechID
AND h.Vorgang = 2
)

Dieter
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Roland Dick



Anmeldedatum: 01.01.1970
Beiträge: 6

BeitragVerfasst am: Sa Okt 13, 2007 10:50 pm    Titel: Abfrage-Problem Antworten mit Zitat



Hallo Jürgen und Michael,

Jürgen Volke schrieb:
> in etwa:
> SELECT * FROM Rechnungstabelle
> WHERE RECHID NOT IN
> (SELECT RECHID FROM Historientabelle WHERE Vorgang = 2)

Oder auch mit einem LEFT JOIN:

SELECT * FROM Rechnungstabelle
LEFT JOIN Historytabelle
ON Rechnungstabelle.RechID = Historytabelle.RechID
AND Historytabelle.Vorgang = 2
WHERE Historytabelle.RechID IS NULL

Das ist nach meinem Wissen etwas performanter, weil IN eine
möglicherweise grosse Datenmenge "zwischenspeichern" muss.

mfG,

Roland
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Michael Vollmer



Anmeldedatum: 01.01.1970
Beiträge: 4

BeitragVerfasst am: So Okt 14, 2007 12:07 am    Titel: Abfrage-Problem Antworten mit Zitat



Am Sat, 13 Oct 2007 16:16:33 +0200 schrieb Dieter Noeth:

> Roland Dick wrote:
>
>>> SELECT * FROM Rechnungstabelle
>>> WHERE RECHID NOT IN
>>> (SELECT RECHID FROM Historientabelle WHERE Vorgang = 2)
>>
>> Oder auch mit einem LEFT JOIN:
>>
>> SELECT * FROM Rechnungstabelle
>> LEFT JOIN Historytabelle
>> ON Rechnungstabelle.RechID = Historytabelle.RechID
>> AND Historytabelle.Vorgang = 2
>> WHERE Historytabelle.RechID IS NULL
>>
>> Das ist nach meinem Wissen etwas performanter, weil IN eine
>> möglicherweise grosse Datenmenge "zwischenspeichern" muss.
>
> Wieso nicht einfach die 1:1 Übersetzung der Ausgangsfrage?
> EXISTS ist meistens die effizienteste Lösung:
>
> SELECT * FROM Rechnungstabelle r
> WHERE NOT EXISTS
> (SELECT * FROM Historytabelle h
> WHERE r.RechID = h.RechID
> AND h.Vorgang = 2
> )
>
> Dieter

Danke für die vielen Lösungen.

Nun stellt sich mir die Frage, was bei sehr großen Datenmengen die wirklich
performantere Lösung ist!?

Mfg
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Josef Poetzl



Anmeldedatum: 01.01.1970
Beiträge: 63

BeitragVerfasst am: Mo Okt 15, 2007 10:58 am    Titel: Abfrage-Problem Antworten mit Zitat



Hallo!

Michael Vollmer schrieb:
[...]
> Nun stellt sich mir die Frage, was bei sehr großen Datenmengen die wirklich
> performantere Lösung ist!?

Die Prüfung (das Datenmodell) so umstellen, dass NOT EXISTS/IN nicht
erforderlich ist.
.... Klappt nicht immer, aber einen Versuch ist es allemal wert. ;)

mfg
Josef
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Peter Doering



Anmeldedatum: 01.01.1970
Beiträge: 75

BeitragVerfasst am: Mo Okt 15, 2007 1:55 pm    Titel: Abfrage-Problem Antworten mit Zitat



Hallo,

Michael Vollmer wrote:
> Am Sat, 13 Oct 2007 22:50:38 +1000 schrieb Roland Dick:
>> Jürgen Volke schrieb:
>>> in etwa:
>>> SELECT * FROM Rechnungstabelle
>>> WHERE RECHID NOT IN
>>> (SELECT RECHID FROM Historientabelle WHERE Vorgang = 2)
>>
>> Oder auch mit einem LEFT JOIN:
>>
>> SELECT * FROM Rechnungstabelle
>> LEFT JOIN Historytabelle
>> ON Rechnungstabelle.RechID = Historytabelle.RechID
>> AND Historytabelle.Vorgang = 2
>> WHERE Historytabelle.RechID IS NULL
>>
>> Das ist nach meinem Wissen etwas performanter, weil IN eine
>> möglicherweise grosse Datenmenge "zwischenspeichern" muss.
>
> Bei mir liefert dieser Weg der Abfrage
> 0 zurück, was falsch ist.

RechID Is Null schliesst auch Vorgang=2 bzw. <>2 aus. Deshalb waere mein
Favorit z. Zt. die Not Exists Variante.

Gruss - Peter
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Michael Vollmer



Anmeldedatum: 01.01.1970
Beiträge: 4

BeitragVerfasst am: Mo Okt 15, 2007 3:56 pm    Titel: Abfrage-Problem Antworten mit Zitat



Am Mon, 15 Oct 2007 13:55:16 +0200 schrieb Peter Doering:

> Hallo,
>
> Michael Vollmer wrote:
>> Am Sat, 13 Oct 2007 22:50:38 +1000 schrieb Roland Dick:
>>> Jürgen Volke schrieb:
>>>> in etwa:
>>>> SELECT * FROM Rechnungstabelle
>>>> WHERE RECHID NOT IN
>>>> (SELECT RECHID FROM Historientabelle WHERE Vorgang = 2)
>>>
>>> Oder auch mit einem LEFT JOIN:
>>>
>>> SELECT * FROM Rechnungstabelle
>>> LEFT JOIN Historytabelle
>>> ON Rechnungstabelle.RechID = Historytabelle.RechID
>>> AND Historytabelle.Vorgang = 2
>>> WHERE Historytabelle.RechID IS NULL
>>>
>>> Das ist nach meinem Wissen etwas performanter, weil IN eine
>>> möglicherweise grosse Datenmenge "zwischenspeichern" muss.
>>
>> Bei mir liefert dieser Weg der Abfrage
>> 0 zurück, was falsch ist.
>
> RechID Is Null schliesst auch Vorgang=2 bzw. <>2 aus. Deshalb waere mein
> Favorit z. Zt. die Not Exists Variante.
>
> Gruss - Peter

Es funktioniert jedoch so.
Alle Varianten liefern die gewünschten RICHTIGEN Ergebnisse.

mfg
Micha
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Peter Doering



Anmeldedatum: 01.01.1970
Beiträge: 75

BeitragVerfasst am: Mo Okt 15, 2007 4:03 pm    Titel: Abfrage-Problem Antworten mit Zitat



Hallo Josef,

Josef Poetzl wrote:
> Peter Doering schrieb:
>> Michael Vollmer wrote:
>>> Am Sat, 13 Oct 2007 22:50:38 +1000 schrieb Roland Dick:
>>>> Jürgen Volke schrieb:
> [...]
>>>> SELECT * FROM Rechnungstabelle
>>>> LEFT JOIN Historytabelle
>>>> ON Rechnungstabelle.RechID = Historytabelle.RechID
>>>> AND Historytabelle.Vorgang = 2
>>>> WHERE Historytabelle.RechID IS NULL
>>>>
>>>> Das ist nach meinem Wissen etwas performanter, weil IN eine
>>>> möglicherweise grosse Datenmenge "zwischenspeichern" muss.
>>>
>>> Bei mir liefert dieser Weg der Abfrage
>>> 0 zurück, was falsch ist.
>>
>> RechID Is Null schliesst auch Vorgang=2 bzw. <>2 aus.
>
> *LEFT* JOIN Historytabelle
> ON Rechnungstabelle.RechID = Historytabelle.RechID
> *AND*
> Historytabelle.Vorgang = 2
>
> müsste imo schon das gewünschte Ergebnis liefern.

Man sollte doch immer erst testen Wink

Es funktioniert tatsaechlich, entgegen meiner Annahme, es wuerde sich
verhalten, als waere die Abfrage auf Vorgang in der Where-Klausel.

--
Create Table #RechnungsTabelle ( RechID int )

Insert Into #RechnungsTabelle (RechID ) Values ( 1 )
Insert Into #RechnungsTabelle (RechID ) Values ( 2 )
Insert Into #RechnungsTabelle (RechID ) Values ( 3 )
Insert Into #RechnungsTabelle (RechID ) Values ( 4 )

Create Table #HistoryTabelle ( RechID int, Vorgang Int )

Insert Into #HistoryTabelle (RechID, Vorgang ) Values ( 1, 2 )
Insert Into #HistoryTabelle (RechID, Vorgang ) Values ( 2, 2 )
Insert Into #HistoryTabelle (RechID, Vorgang ) Values ( 3, 1 )

SELECT *
FROM #RechnungsTabelle AS R LEFT JOIN #HistoryTabelle AS H
ON R.RechID = H.RechID AND H.Vorgang = 2
WHERE H.RechID IS NULL

DROP TABLE #HistoryTabelle
DROP TABLE #RechnungsTabelle
--

Die Prozedur liefert wie erwartet RechIDs 3 und 4. Es muss also an etwas
anderem liegen.

>> Deshalb waere mein Favorit z. Zt. die Not Exists Variante.
>
> da schließe ich mich an. ;)

Und ich ruecke in diesem Fall wieder davon ab. Join ist besser als
In/Exists ;-)

Gruss - Peter
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Josef Poetzl



Anmeldedatum: 01.01.1970
Beiträge: 63

BeitragVerfasst am: Mo Okt 15, 2007 5:13 pm    Titel: Abfrage-Problem Antworten mit Zitat



Hallo!

Peter Doering schrieb:
> Und ich ruecke in diesem Fall wieder davon ab. Join ist besser als
> In/Exists ;-)

Warum?

vergleiche die 2 Beispiele einmal im Ausführungsplan:

SELECT R.*
FROM #RechnungsTabelle AS R
LEFT JOIN #HistoryTabelle AS H
ON R.RechID = H.RechID AND H.Vorgang = 2
WHERE H.RechID IS NULL


SELECT R.*
FROM #RechnungsTabelle AS R
WHERE NOT EXISTS (SELECT * FROM #HistoryTabelle H
WHERE H.RechID = R.RechID AND H.Vorgang = 2)


mfg
Josef
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Josef Poetzl



Anmeldedatum: 01.01.1970
Beiträge: 63

BeitragVerfasst am: Di Okt 16, 2007 11:36 am    Titel: Abfrage-Problem Antworten mit Zitat



Hallo!

Peter Doering schrieb:
> Josef Poetzl wrote:
>> SELECT R.*
>> FROM #RechnungsTabelle AS R
>> LEFT JOIN #HistoryTabelle AS H
>> ON R.RechID = H.RechID AND H.Vorgang = 2
>> WHERE H.RechID IS NULL
>>
>> SELECT R.*
>> FROM #RechnungsTabelle AS R
>> WHERE NOT EXISTS (SELECT * FROM #HistoryTabelle H
>> WHERE H.RechID = R.RechID AND H.Vorgang = 2)
>
> Also, ich lese den Plan so, dass bei der Join-Variante ein zusaetzlicher
> Schritt (Filter) ausgefuehrt wird, der bei der Exists-Variante fehlt. Bei
> den 4 Rows spielt das keine Rolle, aber je mehr % der Filter aufnimmt,
> desto schneller werden hinterher die Table- bzw. Index Scans laufen (ganz
> abgesehen davon, dass noch kein Index angelegt ist Wink.
>
> Wie liest du den Plan?

Entlang der Pfeile. ;-)

mfg
Josef
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Michael Vollmer



Anmeldedatum: 01.01.1970
Beiträge: 4

BeitragVerfasst am: Mi Okt 17, 2007 10:54 am    Titel: Abfrage-Problem Antworten mit Zitat



Am Tue, 16 Oct 2007 11:36:35 +0200 schrieb Josef Poetzl:

> Hallo!
>
> Peter Doering schrieb:
>> Josef Poetzl wrote:
>>> SELECT R.*
>>> FROM #RechnungsTabelle AS R
>>> LEFT JOIN #HistoryTabelle AS H
>>> ON R.RechID = H.RechID AND H.Vorgang = 2
>>> WHERE H.RechID IS NULL
>>>
>>> SELECT R.*
>>> FROM #RechnungsTabelle AS R
>>> WHERE NOT EXISTS (SELECT * FROM #HistoryTabelle H
>>> WHERE H.RechID = R.RechID AND H.Vorgang = 2)
>>
>> Also, ich lese den Plan so, dass bei der Join-Variante ein zusaetzlicher
>> Schritt (Filter) ausgefuehrt wird, der bei der Exists-Variante fehlt. Bei
>> den 4 Rows spielt das keine Rolle, aber je mehr % der Filter aufnimmt,
>> desto schneller werden hinterher die Table- bzw. Index Scans laufen (ganz
>> abgesehen davon, dass noch kein Index angelegt ist Wink.
>>
>> Wie liest du den Plan?
>
> Entlang der Pfeile. Wink
>
> mfg
> Josef

Wie und wo kann man sich diesen Plan anzeigen lassen?

mfg
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Peter Doering



Anmeldedatum: 01.01.1970
Beiträge: 75

BeitragVerfasst am: Mi Okt 17, 2007 12:36 pm    Titel: Abfrage-Problem Antworten mit Zitat



Hallo,

Michael Vollmer wrote:
> Josef Poetzl:
>>>
>>> Wie liest du den Plan?
>
> Wie und wo kann man sich diesen Plan anzeigen lassen?

In SSMS entweder den entsprechenden Icon im SQL-Editor Toolbar anklicken,
oder Ctrl-M, oder Menue Query - Include Actual Execution Plan.

Anschliessend die Abfrage ausfuehren.

Man kann sich den voraussichtlichen Ausfuehrungsplan bereits vor
Ausfuehrung anzeigen lassen. Dazu erst das/die auszuwertende(n)
Statement(s) markieren, Ctrl-L (bzw. Menue Query - Display Estimated
Execution Plan usw.).

Gruss - Peter
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Josef Poetzl



Anmeldedatum: 01.01.1970
Beiträge: 63

BeitragVerfasst am: Mi Okt 17, 2007 12:54 pm    Titel: Abfrage-Problem Antworten mit Zitat



Hallo!

Peter Doering schrieb:
> Ich hatte so viele Tasks im Plan, dass die Linien
> so duenn und deshalb die Pfeile nicht mehr zu erkennen waren. Zoom braucht
> unsereins ja nicht ;-)

Ich sehe gerade, dass im Management Studio die Pfeile nicht besonders
augenfreundlich dargestellt werden. Da ich meist noch den
Queryanalyzer verwende viel mir das bisher nicht auf.
... die Bedienung nach einem Zoom (z.B. zum Vergrößern des
Anzeigebereichs für den letzten dargestellten Ablauf) ist auch nicht
besonders freundlich ... oder ich stelle mich dabei einfach nur doof
an. Wink
Es gibt zwar "Zoom anpassen" ... ich hätte aber lieber "Bereich an
Zoom anpassen"

(Anm.: ich guckte im SSMS Express.)

mfg
Josef
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Josef Poetzl



Anmeldedatum: 01.01.1970
Beiträge: 63

BeitragVerfasst am: Mi Okt 17, 2007 1:13 pm    Titel: Abfrage-Problem Antworten mit Zitat



Hallo!

Josef Poetzl schrieb:
> .. oder ich stelle mich dabei einfach nur doof
> an. Wink

.... nicht nur dort, auch beim Schreiben von f und v! :-)

mfg
Ingrid
.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Softpicks.Net Deutsch Foren-Übersicht -> SQL Server Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht teilnehmen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de