2016-11-28 3 views
2

Ich bin neu in SQL so leid, wenn ich dumm bin!SQL Distinct-Klausel funktioniert nicht?

Ich versuche, ein paar Spalten zu wählen, wo der Name nicht mehr als einmal erscheint, aber die Verwendung der distinct-Klausel tut dies aus irgendeinem Grund nicht?

Hier ist meine Frage:

SELECT DISTINCT A.fldContactName, A.fldsignonlinesetup, B.fldorderdate, A.fldemail 
FROM tblcustomers AS A 
LEFT JOIN tblorders AS B ON A.fldcustomerid = B.fldcustomerid 
WHERE B.fldorderdate BETWEEN '2013-01-01' AND '2016-12-31' 
AND A.fldemail <> 'NULL' AND A.fldcontactname <> 'NULL' AND A.fldcontactname <> '' 
AND A.fldemail <> '' 
AND A.fldsignonlinesetup = 0 
ORDER BY A.fldcontactname ASC 

Wie kann ich es nur zeigen Aufzeichnungen erhalten, die einzigartig sind z.B. Kontakt Name John Smith kommt nur einmal auf?

Erwartetes Ergebnis:

fldContactName: fldEmail:  fldSignOnlineSetup: fldOrderDate: 
James Smith  [email protected]   0    2016-08-14 
Bill Plant   [email protected]   0    2015-02-24 

tatsächliche Ergebnis:

fldContactName: fldEmail:  fldSignOnlineSetup: fldOrderDate: 
James Smith  [email protected]   0    2016-08-14 
Bill Plant   [email protected]   0    2015-02-24 
James Smith  [email protected]   0    2014-06-20 
+1

Geben Sie Beispieldaten und erwartetes Ergebnis an. – Viki888

+2

Meinst du wirklich 'fldemail <> 'NULL'' oder meinst du' A.fldemail IST NICHT NULL'? Ihre Version ist ein String-Vergleich zu einer Zeichenfolge mit vier Buchstaben. Die zweite überprüft, dass der Wert nicht "NULL" ist. –

+0

Distinct ist auf allen Feldern verschieden, nicht nur eins. Wenn nur ein Datensatz pro Name angezeigt werden soll, müssen Sie die Geschäftsregeln kennen, mit denen Sie verknüpfte Datensätze ausschließen können, oder Sie müssen die Werte verwandter Datensätze in ein Feld verketten. Da Benutzer wahrscheinlich mehr als eine Bestellung haben, ist dies unwahrscheinlich dass Sie immer nur eine Zeile pername haben und Ihre Geschäftsregeln erfüllen, es sei denn, Sie möchten nur die erste oder die letzte Bestellung. – HLGEM

Antwort

1

Wenn Sie die Benennung nur erscheinen, einmal wollen, dann kommt group by in den Sinn. Eine Methode ist:

SELECT c.fldContactName, 
     MAX(c.fldsignonlinesetup) as fldsignonlinesetup, 
     MAX(c.fldorderdate) as fldorderdate, 
     MAX(c.fldemail) as fldemail 
FROM tblcustomers c LEFT JOIN 
    tblorders o 
    ON c.fldcustomerid = o.fldcustomerid 
WHERE o.fldorderdate BETWEEN '2013-01-01' AND '2016-12-31' AND 
     c.fldemail <> 'NULL' AND c.fldcontactname <> 'NULL' AND 
     c.fldcontactname <> '' AND c.fldemail <> '' AND 
     c.fldsignonlinesetup = 0 
GROUP BY c.fldcontactname 
HAVING COUNT(*) = 1 
ORDER BY c.fldcontactname ASC; 

SELECT DISTINCT macht einfach sicher, dass alle die Spalten in der Ergebnismenge sind nie Duplikate. Es hat nichts damit zu tun, Werte mit nur einer Zeile zu finden. Die HAVING Klausel tut dies.

Hinweise:

  • Die Verwendung von Tabellen-Aliases ist gut, aber die Abkürzungen für Tabellennamen machen die Abfrage verständlicher.
  • Die MAX() ist wirklich ein No-Op. Mit einer Zeile wird der Wert aus der einen Zeile zurückgegeben.
  • Die GROUP BY ist auf dem Feld, das Ihnen wichtig ist - das, für das Sie keine Duplikate benötigen.
  • Die HAVING-Klausel erhält die Werte mit nur einer Zeile.
  • MySQL benötigt nicht die MAX() Funktionen, aber ich empfehle dringend, eine Aggregationsfunktion zu verwenden, damit Sie keine schlechten Gewohnheiten lernen, die in anderen Datenbanken nicht funktionieren und sich in MySQL unerwartet verhalten können.
  • Meinst du wirklich fldemail <> 'NULL' oder beabsichtigen Sie A.fldemail IS NOT NULL?
+1

Hinweis für das OP, dies kann oder nicht geben Sie, was Sie brauchen. Es hängt wirklich von Ihren Geschäftsregeln ab, die nur Ihr spezielles Geschäft definieren kann. – HLGEM

+0

Vielen Dank für Ihre Hilfe, aber beim Ausführen dieser Abfrage heißt es, dass es einen ungültigen Spaltennamen 'fldorderdate' gibt? –

+0

muss wahrscheinlich 'o.fldorderdate' in der' SELECT'-Liste anstelle von 'c' sein. –

0

Wollen Sie nur Ihre ausgewählten Daten angezeigt werden einmal oder nur die Daten erhalten, die in der DB einzigartig ist?

Für letztere

tun
SELECT A.fldContactName, A.fldsignonlinesetup, B.fldorderdate, A.fldemail 
FROM tblcustomers AS A 
LEFT JOIN tblorders AS B ON A.fldcustomerid = B.fldcustomerid 
WHERE B.fldorderdate BETWEEN '2013-01-01' AND '2016-12-31' 
AND A.fldemail not in ('NULL', '') 
AND A.fldcontactname not in ('NULL', '') 
AND A.fldsignonlinesetup = 0 
GROUP BY A.fldContactName, A.fldsignonlinesetup, B.fldorderdate, A.fldemail 
HAVING count(*) = 1 
ORDER BY A.fldcontactname ASC