ottscho
Goto Top

SQL Statment über mehrere Tabellen

Hallo zusammen,

ich habe 2 Tabellen, welche ich vergleichen möchte. In einer Tabelle sind Aufträge, Kundennummer und Datum und in der Anderen Angebote, Kundennummer und Datum.
Nun möchet ich Pro Kundennummer die Angebote und Aufträge in einem bestimmten Zeitraum gegenüberstellen.

so z.b.

Datensatzspalte / AngeboteAnzahl / AuftragAnzahl
Datensatz1 / 1 / 1
Datensatz2 / 1 / 2
Datensatz3 / 0 / 1
Datensatz4 / 1 / 0

Mit diesem SQL Statment mache ich es zur Zeit, aber sobald in einer Tabelle ein Count mit 0 ist, wird die komplette Zeile verworfen.
Ich komme einfach nicht drauf, wie es gehen könnte...

select	account.accountnumber,account.name, an.AngebotAnzahl, au.AuftragAnzahl 
from	( 
	select	new_parentaccountid, count (*) As AngebotAnzahl 
	from	new_offer  
	group by new_parentaccountid) an 
	join ( 
	select	new_parentaccountid, count (*) As AuftragAnzahl 
	from	new_order
	group by new_parentaccountid) au on an.new_parentaccountid = au.new_parentaccountid
join account on an.new_parentaccountid = account.accountid


Vllt habt ihr mir noch einen Tipp.

Vielen Dank

Content-Key: 127585

Url: https://administrator.de/contentid/127585

Printed on: April 19, 2024 at 06:04 o'clock

Member: nxclass
nxclass Oct 21, 2009 at 06:18:11 (UTC)
Goto Top
... so ?
SELECT
    a.accountnumber,
    a.name,
    an.AngebotAnzahl,
    au.AuftragAnzahl 
FROM
    `account` a
        LEFT JOIN ( 
            SELECT `new_parentaccountid`, COUNT(*) As 'AngebotAnzahl'  
            FROM `new_offer`
            GROUP BY `new_parentaccountid`
        ) an ON a.accountid = an.new_parentaccountid
        LEFT JOIN ( 
            SELECT `new_parentaccountid`, COUNT(*) As 'AuftragAnzahl'   
            FROM `new_order`
            GROUP BY `new_parentaccountid`
        ) au ON a.accountid = au.new_parentaccountid
ORDER BY a.name;

oder so ?
SELECT
    a.accountnumber,
    a.name,
    COUNT(an.new_parentaccountid) AS 'AngebotAnzahl',  
    COUNT(au.new_parentaccountid) AS 'AuftragAnzahl'   
FROM
    `account` a
        LEFT JOIN `new_offer` an ON a.accountid = an.new_parentaccountid
        LEFT JOIN `new_order` au ON a.accountid = au.new_parentaccountid
GROUP BY a.accountnumber
ORDER BY a.name;
Member: ottscho
ottscho Oct 21, 2009 at 06:31:35 (UTC)
Goto Top
ja, das sieht jetzt schon sehr gut aus.
Und wenn ich jetzt noch die Anzahl der Firmen begrenzen wollte, müsste ich unten noch ein WHERE reinmachen, dass ich nicht alle Datensätze von ACCOUNT bekomme, sondern nur von bestimmen Firmen.

Das sollte gehen face-smile

Ich probiere es mal aus.

Danke erst mal
Member: ottscho
ottscho Nov 02, 2009 at 12:49:51 (UTC)
Goto Top
Hallo,
ich verusche gerade die selbe Abfrage auf einer anderen Datenbank:

SELECT	WDKDSTAM.KKDNR,
WDKDSTAM.KNAME1,
DK.DK_Anzahl,
ML.ML_Anzahl
FROM	WDKDSTAM
    LEFT JOIN (
        SELECT KLKDNR, count(KLKDNR) AS DK_Anzahl
        FROM WDKALKULATION
        WHERE KLDATE between '01.11.2009' and '30.11.2009'  
        AND KLPGR = 'DK'  
        GROUP BY KLKDNR
    ) DK ON WDKDSTAM.KKDNR = DK.KLKDNR
    LEFT JOIN (
        SELECT KLKDNR, count(KLKDNR) AS ML_Anzahl
        FROM WDKALKULATION
        WHERE KLDATE between '01.11.2009' and '30.11.2009'  
        AND KLPGR = 'ML'  
        GROUP BY KLKDNR
    ) ML ON WDKDSTAM.KLDKDNR = ML.KLKDNR;

Leider bekomme ich einen Fehler in der Zeile 7, beim select?
Wenn ich das Select alleine abfrage funktioniert es aber...

Weiß jmd die Lösung?
Member: nxclass
nxclass Nov 02, 2009 at 19:03:23 (UTC)
Goto Top
versuch mal:
SELECT
    wdks.KKDNR,
    wdks.KNAME1,
    count(wdk1.KLKDNR) AS DK_Anzahl,
    count(wdk2.KLKDNR) AS ML_Anzahl
FROM
    WDKDSTAM wdks
        LEFT JOIN WDKALKULATION wdk1 ON wdks.KKDNR = wdk1.KLKDNR
        LEFT JOIN WDKALKULATION wdk2 ON wdks.KKDNR = wdk2.KLKDNR
WHERE
    wdk1.KLDATE BETWEEN '01.11.2009' AND '30.11.2009' AND  
    wdk1.KLPGR = 'DK' AND  
    wdk2.KLDATE BETWEEN '01.11.2009' AND '30.11.2009' AND  
    wdk2.KLPGR = 'ML'  
GROUP BY
    wdk1.KLKDNR,
    wdk2.KLKDNR

... einige Datenbanken verstehen nicht die verschachtelten SELECT Anweisungen.
Member: ottscho
ottscho Nov 03, 2009 at 06:50:48 (UTC)
Goto Top
Danke für die Hilfe.
Leider geht dieser Code auch nicht.

Fehler:
invalid column reference
Member: nxclass
nxclass Nov 03, 2009 at 07:41:04 (UTC)
Goto Top
mit was für einer Datenbank arbeitest Du?

SELECT wdks.*, wdk1.*, wdk2.*
FROM
    WDKDSTAM wdks
        LEFT JOIN WDKALKULATION wdk1 ON wdks.KKDNR = wdk1.KLKDNR
        LEFT JOIN WDKALKULATION wdk2 ON wdks.KKDNR = wdk2.KLKDNR
WHERE
    wdk1.KLDATE BETWEEN '01.11.2009' AND '30.11.2009' AND  
    wdk1.KLPGR = 'DK' AND  
    wdk2.KLDATE BETWEEN '01.11.2009' AND '30.11.2009' AND  
    wdk2.KLPGR = 'ML'  
...geht das ?

kann deine DB den Befehl 'CREATE TEMPORARY TABLE ... SELECT' ?
Member: ottscho
ottscho Nov 03, 2009 at 07:58:48 (UTC)
Goto Top
NEIN, TEMPRARY wird nicht erkannt. Aber man könnte evtl. eine VIEW machen.

Ich arbeite mit Borland Interbase SQL 6
Member: nxclass
nxclass Nov 03, 2009 at 10:29:50 (UTC)
Goto Top
dann mache doch 2 VIEWs:
SELECT KLKDNR, count(KLKDNR) AS DK_Anzahl
FROM WDKALKULATION
WHERE KLDATE between '01.11.2009' and '30.11.2009' AND KLPGR = 'DK'  
GROUP BY KLKDNR;
und
SELECT KLKDNR, count(KLKDNR) AS ML_Anzahl
FROM WDKALKULATION
WHERE KLDATE between '01.11.2009' and '30.11.2009' AND KLPGR = 'ML'  
GROUP BY KLKDNR

und über diese beiden VIEWs dann den SELECT
SELECT
    wdks.KKDNR,
    wdks.KNAME1,
    v1.KLKDNR AS DK_Anzahl,
    v2.KLKDNR AS ML_Anzahl
FROM
    WDKDSTAM wdks
        LEFT JOIN { VIEW 1 } v1 ON wdks.KKDNR = v1.KLKDNR
        LEFT JOIN { VIEW 2 } v2 ON wdks.KKDNR = v2.KLKDNR

---

... leider kenne ich das Borland Interbase SQL 6 nicht.
Member: Biber
Biber Nov 03, 2009 at 10:58:00 (UTC)
Goto Top
Moin nxclass,

der Workaround über die Views hat den immensen Nachteil, dass in jedem dieser Views hart verdrahtet eine feste WHERE-Clause codiert ist.
Das WHERE bezogen auf die Kategorie KLPGR (mit "ML" oder "DK") ist ja dort gut aufgehoben.
Aber der Verzicht auf jegliche Flexibilität durch das Einmeisseln von "WHERE KLDATE Between '1.11.2009' and '30.11.2009'" wäre für mich ein Killerkriterium. No way.

@ottscho

lass uns nochmal zurück zu deinem Post von 2.11.
Leider bekomme ich einen Fehler in der Zeile 7, beim select?
Welchen genau?

Wenn ich das Select alleine abfrage funktioniert es aber...
kannst du das mal in zwei ganzen Sätzen beschreiben? Welche Selects, welches Ergebnis?

Grüße
Biber
Member: ottscho
ottscho Nov 03, 2009 at 11:10:35 (UTC)
Goto Top
SELECT	WDKDSTAM.KKDNR,
WDKDSTAM.KNAME1,
DK.DK_Anzahl,
ML.ML_Anzahl
FROM	WDKDSTAM
    LEFT JOIN (
        SELECT KLKDNR, count(KLKDNR) AS DK_Anzahl
        FROM WDKALKULATION
        WHERE KLDATE between '01.11.2009' and '30.11.2009'  
        AND KLPGR = 'DK'  
        GROUP BY KLKDNR
    ) DK ON WDKDSTAM.KKDNR = DK.KLKDNR
    LEFT JOIN (
        SELECT KLKDNR, count(KLKDNR) AS ML_Anzahl
        FROM WDKALKULATION
        WHERE KLDATE between '01.11.2009' and '30.11.2009'  
        AND KLPGR = 'ML'  
        GROUP BY KLKDNR
    ) ML ON WDKDSTAM.KLDKDNR = ML.KLKDNR;

Fehler:
Dynamic SQL Error
SQL error code = -104
Token unknown - liine 7, char7
SELECT

Wenn ich diesen Code alleine ausführe:
SELECT KLKDNR, count(KLKDNR) AS DK_Anzahl
        FROM WDKALKULATION
        WHERE KLDATE between '01.11.2009' and '30.11.2009'  
        AND KLPGR = 'DK'  
        GROUP BY KLKDNR
funktioniert es...
Member: Biber
Biber Nov 03, 2009 at 17:02:33 (UTC)
Goto Top
Moin ottscho,

der SQLCode -104 ist eigentlich immer derjenige für "ILLEGAL STRING"..

Kann es sein, dass du beim Zusammenbraten des Select-Statements eventuell KEIN Leerzeichen zwischen dem "ML.ML_Anzahl" in Zeile 04 und dem "From WKKDSTAM" in Zeile 05 stehen hast?
Hast Du die Möglichkeit, dieses Statement als Copy & Paste-Kopie direkt über irgendeine Client-Workbench abzufeuern?
Bzw. wo kommt denn die Erwähnung des "DYNAMIC SQL" in der Fehlermeldung her? Wer bastelt denn den Statementstring wie zusammen?

Grüße
Biber
Member: ottscho
ottscho Nov 04, 2009 at 07:03:08 (UTC)
Goto Top
Morgen,

also ein Leerzeichen ist vorhanden, das habe ich eben überprüft.
Das Statment schicke ich über den Borland IBAdmin3 direkt an die DB.
Der Fehler kommt auch von diesem Programm, siehe Screenshot:

http://www.myimg.de/?img=screenshot4ec71.jpg
Member: Biber
Biber Nov 04, 2009 at 08:47:34 (UTC)
Goto Top
Moin ottscho,

tjy, das macht mich auch etwas ratlos.

Letzter Versuch meinerseits (allerdings gebe ich diesem Versuch auch nur eine Erfolgschance von 5%):

SELECT	WDKDSTAM.KKDNR,
WDKDSTAM.KNAME1,
DK.DK_Anzahl,
ML.ML_Anzahl
FROM	WDKDSTAM
    LEFT JOIN (
        SELECT a.KLKDNR, count(a.KLKDNR) AS DK_Anzahl
        FROM WDKALKULATION a
        WHERE a.KLDATE between '01.11.2009' and '30.11.2009'  
        AND a.KLPGR = 'DK'  
        GROUP BY a.KLKDNR 
    ) DK ON WDKDSTAM.KKDNR = DK.KLKDNR
    LEFT JOIN (
        SELECT b.KLKDNR, count(b.KLKDNR) AS ML_Anzahl
        FROM WDKALKULATION b
        WHERE b.KLDATE between '01.11.2009' and '30.11.2009'  
        AND b.KLPGR = 'ML'  
        GROUP BY b.KLKDNR 
    ) ML ON WDKDSTAM.KLDKDNR = ML.KLKDNR;

Keine Ahnung, wieso deine DB sich da so ziert... exotisch ist eigentlich nichts an deinem Statement laut Screenshot.

Grüße
Biber
Member: ottscho
ottscho Nov 04, 2009 at 09:12:56 (UTC)
Goto Top
Hallo Biber,

danke für deine Mühen.
Ich habe nun im IBAdmin3 keine Änderung. Fehler bleibt erhalten.
Zum Tst habe ich mal in Excel die Datebank per ODBC und Microsoft SQL Query eingebunden und hier das Statment versucht.
Auch keine Erfolg.
Die Fehlermeldung ist gleich!

Gruß
ottscho
Member: nxclass
nxclass Nov 04, 2009 at 09:35:55 (UTC)
Goto Top
... den immensen Nachteil, dass in jedem dieser Views hart verdrahtet eine feste WHERE-Clause codiert ist ...

und wenn Er an der Stelle nur ein Feld mit 'Monat-Jahr' generiert und dieses Feld in die GROUP -Klausel einfügt - sollte es doch flexibel genug sein um in der Abfrage danach zu Filtern (WHERE).