SQL-Query für MS-SQL-Server mit Distinct und count



  • OK. Beispiel:

    CREATE TABLE test(id INT PRIMARY KEY, m_nr INT, time_key INT, flag INT);
    
    INSERT INTO  test VALUES(1, 100, 1, 0);
    INSERT INTO  test VALUES(2, 200, 2, 1);
    INSERT INTO  test VALUES(3, 200, 3, 1);
    INSERT INTO  test VALUES(4, 100, 4, 0);
    INSERT INTO  test VALUES(5, 100, 5, 1);
    
    SELECT COUNT(*) AS anzahl, m_nr, id 
    FROM test
    WHERE time_key IN ( SELECT MAX(time_key) FROM test WHERE flag = 1 GROUP BY m_nr)
    GROUP BY m_nr, id; 
    
    -- oder
    
    -- Anzahl der guten Motoren
    SELECT COUNT(*) AS anzahl FROM test
    WHERE time_key IN ( SELECT MAX(time_key) FROM test WHERE flag = 1 GROUP BY m_nr);
    

    Ist jetzt keine Lösung, mehr als Anregung ..



  • Das sieht ja schon mal nicht schlecht aus, mit dem bin ich auch schon ein ganzes Stück weiter gekommen, aber leider ist das noch nicht 100% das was ich wollte. Also es geht:

    SELECT count(Distinct MotorNummer) AS ANZAHL 
    FROM [dbo].[TRWErgebnisse] 
    WHERE Zeitstempel IN ( SELECT MAX(Zeitstempel) 
                           FROM [dbo].[TRWErgebnisse] GROUP BY MotorNummer) 
    AND ID<=23 AND [ErrCode] = 0 AND MotorGut = 1
    

    Auch wenn ich nach dem Schema alle oder NIOs abfrage. Jetzt aber das Problem:
    Wenn ich folgende Tabelle habe:

    ID    MotorNummer    GUT
    1     4711            NIO
    2     0812            NIO
    3     0813            IO
    4     0815            IO
    5     0815            IO
    6     0815            NIO
    

    Und ich mach jetzt obigen code dann zählt er die IOs das wäre dann 2 IO
    Wenn ich die query invertiere zählt er 3 NIO
    Wenn ich due Gut-Abfrage weglasse dann zählt er 4. Ist ja alles einzeln richtig, aber wenn ich obige Tabelle habe sollten es eigentlich ein IO und 3 NIO sein. Weil der Motor 0815 ja schon NIO gecountet wurde. Aber die Abfragen wissen ja gar nichts von einander, wie sollen sie dann auch checken ob die andere schon was hat. Kann es sein dass folgender Part aus der Query nicht richtig funktioniert?

    Zeitstempel IN ( SELECT MAX(Zeitstempel) FROM [dbo].[TRWErgebnisse] GROUP BY MotorNummer)
    

    Weil wenn ich das richtig verstanden habe sollte er ja nur die neuesten nehmen, dann sähe ja die Tabelle so aus:

    ID    MotorNummer    GUT
    1     4711            NIO    <= NIO
    2     0812            NIO    <= NIO
    3     0813            IO     <= IO
    4     0815            IO     <= raus
    5     0815            IO     <= raus
    6     0815            NIO    <= NIO
    

    Dann würde ja aber auch das counten stimmen. Sieht jemand den Fehler?



  • aber wenn ich obige Tabelle habe sollten es eigentlich ein IO und 3 NIO sein

    Mit dieser Anweisung bekommst du 4 zurück. 3 NIO + 1 IO

    SELECT COUNT(*) AS anzahl FROM test 
    WHERE time_key IN ( SELECT MAX(time_key) FROM test GROUP BY m_nr);
    

    Mir ist jetzt nicht klar, wo das Problem ist 😕

    Aber die Abfragen wissen ja gar nichts von einander, wie sollen sie dann auch checken ob die andere schon was hat.

    ID    MotorNummer TimeStamp     GUT
    1     4711          1           NIO
    2     0812          2           NIO
    3     0813          3           IO
    4     0815          4           IO
    5     0815          5           IO
    6     0815          6           NIO
    
    WHERE time_key IN ( SELECT MAX(time_key) FROM test GROUP BY m_nr
    

    Liefert

    ID    MotorNummer TimeStamp     GUT
    1     4711          1           NIO
    2     0812          2           NIO
    3     0813          3           IO
    6     0815          6           NIO
    

    zurück.

    SELECT COUNT(*) AS anzahl FROM test WHERE
    

    zählt jetzt 4.

    😕 😕



  • Ja, OK mit deinem Post gehe ich konform. Ich bekomme auch 4 zurück.
    Ich will 3 Zahlen haben.
    1. Anzahl Motoren
    2. Anzahl gute Motoren
    3. Anzahl schlechte Motoren.
    Meine Querys dazu sind demnach:

    SELECT count(Distinct MotorNummer) AS ANZAHL FROM [dbo].[TRWErgebnisse] WHERE Zeitstempel IN ( SELECT MAX(Zeitstempel) FROM [dbo].[TRWErgebnisse] GROUP BY MotorNummer) " + Bedingung
    

    Wobei Bedingung für die drei Zahlen für 1. nichts ist, für 2. und 3. folgendes:

    AND [ErrCode] = 0 AND MotorGut = 1 // für 2.
    AND ([ErrCode] != 0 OR MotorGut = 0) //für 3.
    

    wenn ich nun die drei Anfragen mache, kommen gesamt zwar die 4 raus was ja auch richtig ist die zweite Anfrage nach guten liefert aber 2
    und die nicht guten 3 (wären dann aber ja 5)

    Er muss also wenn die doppelten draußen sind dieses Ergebnis nach IO und NIO durchsuchen.

    Nochmal anderes Beispiel ich will IO zählen und hab

    0815 IO
    0815 NIO
    4711 NIO
    4711 IO
    

    Wenn ich jetzt gut suche bleiben IMHO bei der Abfrage von oben

    0815 IO
    4711 IO
    

    hier nimmt er nun die ältesten und zählt die.Da kommt dann zwei raus.
    richtig wäre aber zuerst mal schauen welche der doppelten am ältesten sind also

    0815 NIO
    4711 IO
    

    und erst jetzt dann bei der Gutsuche die nicht guten raus schmeißen! Dann bleibt noch

    4711 IO
    

    wenn ich das nun zähle komme ich auf 1 wenn ich erst NIO wegwerfe komme ich aber auf 2 s.o.
    Vielen Dank für deine Hilfe!



  • CREATE TABLE test(id INT PRIMARY KEY, m_nr INT, time_key INT, flag INT); 
    
    INSERT INTO  test VALUES(1, 0815, 1, 0); 
    INSERT INTO  test VALUES(2, 0815, 2, 1); 
    INSERT INTO  test VALUES(3, 4711, 3, 1); 
    INSERT INTO  test VALUES(4, 4711, 4, 0); 
    
    SELECT m_nr FROM test WHERE time_key IN( 
     SELECT MIN(time_key) AS time_key FROM test 
     WHERE m_nr IN (SELECT m_nr FROM test GROUP BY m_nr HAVING COUNT(*) > 1)
     GROUP BY m_nr) AND flag = 1;
    

    Du brauchst ein anständiges SQL - Buch ⚠ Lass dich nicht von Informix abschrecken. Hier sind die SQL Grundlagen sehr gut erklärt
    http://www.amazon.de/exec/obidos/ASIN/3827312450/qid=1116847129/sr=1-8/ref=sr_1_10_8/028-5141478-6164518

    Ich muss mich jetzt wieder meiner Arbeit widmen.
    Viel Erfolg ..



  • Ich hab einige Datenbankbücher, aber wenn ich so ein Problem hab krieg ich das dennoch nicht hin.
    Eine kleine Frage hab ich noch. Sonst hatte ich immer AS ANZAHL und in Anzahl stand dann mein gezählter Wert. Ich brauche auch jetzt ne Spalte die ANZAHL heißt, aus der ich die Anzahl raus holen kann. Wo steht denn nu die Anzahl drin?
    DANKE viel mals für deine Bemühungen find ich echt klasse, dass du mir so geholfen hast.



  • Ich hab einige Datenbankbücher, aber wenn ich so ein Problem hab krieg ich das dennoch nicht hin.

    Dir fehlt einfach die Erfahrung. Bist du gerade im Praxissemester?

    Ich brauche auch jetzt ne Spalte die ANZAHL heißt, aus der ich die Anzahl raus holen kann. Wo steht denn nu die Anzahl drin?

    Da bin ich jetzt überfragt.

    DANKE viel mals für deine Bemühungen find ich echt klasse, dass du mir so geholfen hast.

    Jo, kein Problem 😉



  • Tanzfreak schrieb:

    Dir fehlt einfach die Erfahrung. Bist du gerade im Praxissemester?

    Jo bin ich. 🙂

    Tanzfreak schrieb:

    Da bin ich jetzt überfragt.

    😮 Du hast doch die Query gebastelt, wo ist das ergebnis dass du erzielen wolltest?



  • Ach so !!

    SELECT COUNT(m_nr) AS anzahl FROM test WHERE time_key IN( 
     SELECT MIN(time_key) AS time_key FROM test 
     WHERE m_nr IN (SELECT m_nr FROM test GROUP BY m_nr HAVING COUNT(*) > 1) 
     GROUP BY m_nr) AND flag = 1;
    


  • also jetzt hab ich ne Lösung wie ich es haben wollte, falls jemand mal in ähnliche Situation gelangt und durch ne Suche hierauf kommt will ich die Lösung nicht vorenthalten. Ich mache es nun so:

    CString CACRSQLSet::CountTeile(CString Bedingung)
    {
    	CString strSQL_gesTeile = STRSQL_TEILE;
    
    	CString SqlCmd1 = "Create table #tmp_Auswertung (Zaehler int, MotorNummer char (10))"; 
    	CString SqlCmd2 = "INSERT INTO #Tmp_Auswertung ( Zaehler, MotorNummer) SELECT Max(dbo.TRWErgebnisse.Zaehler) AS MaxOfZaehler, dbo.TRWErgebnisse.MotorNummer FROM dbo.TRWErgebnisse GROUP BY dbo.TRWErgebnisse.MotorNummer";
    	CString SqlCmd3 = "SELECT Count (*) AS ANZAHL, dbo.TRWErgebnisse.ErrCode FROM dbo.#tmp_Auswertung INNER JOIN dbo.TRWErgebnisse ON dbo.#tmp_Auswertung.Zaehler = dbo.TRWErgebnisse.Zaehler AND dbo.#tmp_Auswertung.MotorNummer = dbo.TRWErgebnisse.MotorNummer AND " + Bedingung + " GROUP BY dbo.TRWErgebnisse.ErrCode asc";
    	CString SqlCmd4 = "Drop table #Tmp_Auswertung";
    	CString strAnzahl;
    	CDatabase db;
    	db.Open( _T("ACR"),FALSE,true,_T("ODBC;UID=anyusr;PWD=anyusr"),false);
    
    	CRecordset Set(&db);
    
    	db.ExecuteSQL(SqlCmd1);
    	db.ExecuteSQL(SqlCmd2);
    	Set.Open(CRecordset::dynaset | CRecordset::forwardOnly, SqlCmd3);
    
    	if(!Set.IsEOF())
    	{
    		Set.GetFieldValue("ANZAHL", strAnzahl);
    	}
    	Set.Close();
    	db.ExecuteSQL(SqlCmd4);
    	return strAnzahl;
    }
    

    Und es geht!!


Anmelden zum Antworten