Reputation: 186
I'm new to SQL so sorry if this is me being stupid!
I am trying to select a few columns where the name does not appear more than once, however using the distinct clause does not do this for some reason?
Here is my query:
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
How do I get it to only show records that are unique e.g. contact name John Smith only comes up once?
Expected Outcome:
fldContactName: fldEmail: fldSignOnlineSetup: fldOrderDate:
James Smith [email protected] 0 2016-08-14
Bill Plant [email protected] 0 2015-02-24
Actual Outcome:
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
Upvotes: 2
Views: 742
Reputation: 1269503
If you want the naming only appearing once, then group by
comes to mind. One method is:
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
just makes sure that all the columns in the result set are never duplicates. It has nothing to do with finding values with only one row. The HAVING
clause does this.
Notes:
MAX()
is really a no-op. With one row, it returns the value from the one row.GROUP BY
is on the field you care about -- the one you don't want duplicates for.HAVING
clause gets the values with only one row.MAX()
functions, but I strongly recommend using an aggregation function, so you don't learn bad habits that don't work in other databases and can behave unexpected in MySQL.fldemail <> 'NULL'
or do you intend A.fldemail IS NOT NULL
?Upvotes: 1
Reputation: 204746
Do you want to display your selected data only once or get only the data that is unique in the DB?
For the latter do
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
Upvotes: 0