Get duplicate rows and count based on single column - sql-server-2008

I need to get the distinct rows based on a single column (code in this case) where there are duplicates of that column value. Along with other information from the row and the number of duplicate rows there are. for example:
ID code ownerName
--------------------------
1 001 Mr. Brown
2 001 Mr. Pink
3 002 Mr. White
4 003 Mr. Blonde
I need this query to return
ID code ownerName count
----------------------------------
1 001 Mr. Brown 2
the duplicate row information does not matter which gets returned, but I'm having trouble combining the distinct codes with the count column.
I've tried a query like this:
SELECT DISTINCT A.code, A.ownerName
FROM Customers A WHERE
EXISTS( SELECT * FROM Customers WHERE code = A.code AND id <> A.id)
order by A.code;
but I'm having trouble getting the count; and with this query
SELECT code, COUNT(*) as numberDuplicates
FROM Customers GROUP BY code HAVING COUNT(*) > 1
I'm having trouble getting other information I don't want to group by. Can anyone help me figure out how to structure the correct query?

If I understand what you are looking for, this should work:
This will select all entries with a non-unique code and return the number of records using that code.
SELECT DISTINCT A.ID, A.Code, A.ownerName, B.Count
FROM Customers A
JOIN (
SELECT COUNT(*) as Count, B.Code
FROM Customers B
GROUP BY B.Code
) AS B ON A.Code = B.Code
WHERE B.Count > 1
ORDER by A.Code;

I think you can try something like below
SELECT TOP 1 C.ID, C.Code, C.OwnerName, C1.NumberDuplicates
FROM
Customers C
INNER JOIN
(
SELECT Code, COUNT(*) as NumberDuplicates FROM Customers GROUP BY code HAVING COUNT(*) > 1
) C1
ON C.Code = C1.Code
Hope this Helps!!

SELECT COUNT(DISTINCT CustomerID) AS NumberOfCustomers FROM Orders;

Related

Left join in SQL to identify certain rows

Given below is table A:
Cust_id
Code
1
101
1
102
1
103
2
201
Table B:
Cust_id
Code
1
101
1
102
Table B has only customer 1 and contains only two product codes of customer 1.
I want to identify the code of customers in Table B that is not present in Table B.
Cust_id
Code
1
103
To get this, I did Table A left join Table B on cust_id and code and thought those with null values of code in Table B would give the desired result, but it did not seem to work. It would be really helpful if someone could tell what should the correct steps be. Thanks
My query so far:
select a.cust_id, a.code, b.cust_id as customer, b.code as product
from a
left join b on a.cust_id = b.cust_id and a.code = b.code
Two conditions:
cust_id must be in table B
(cust_id, code) must not be in table B
The query with the conditions almost literally translated from human language to SQL:
select *
from a
where cust_id in (select cust_id from b)
and (cust_id, code) not in (select cust_id, code from b);
List item
Hello other solution using exists
select a.cust_id, a.code
from TABLEA a left join TABLEB b on
a.cust_id=b.cust_id and a.code=b.code
where b.cust_id is null and exists( select * from TABLEB
where cust_id=a.cust_id)

Not sure how to get this working with respect a SQL query

I have two tables named table1 and table2:
Table1
id date email cId
1 2013-08-28 12:21:39 t#gmail.com 12345
2 2013-07-27 10:15:18 k#gmail.com 12345
3 2018-02-13 09:41:43 a#gmail.com 12345
4 2018-02-02 10:14:42 n#gmail.com 45678
5 2017-11-16 10:16:51 l#gmail.com 45678
Table2
id status
12345 1
45678 1
56789 0
When I execute a query I am expecting to get row from table1 which has max date.
select c.id 'table 2 Id'
, DATE_FORMAT(Max(u.date),'%Y-%m-%dT%TZ') 'Date'
, u.email 'User'
from table2 c
LEFT
JOIN table1 u
ON u.cId = c.id
where c.status = 1
group
by c.id
order
by c.id;
How ever what I see is kind of confusing.
table 2 Id Date USER
12345 2018-02-13 09:41:43 t#gmail.com
I am expecting the output to be
table 2 Id Date USER
12345 2018-02-13 09:41:43 a#gmail.com
Because the max date that is selected is not same of the user t#gmail.com but of a#gmail.com
Any suggestions on where has it gone wrong and how can I tweak it to get correct result?
The moment you use a grouping function (i.e. max, sum, count, etc.) you must specify only segregating columns in the SELECT clause.
In your case, there are several emails for one given id, much like the date field.
You can't just specify
SELECT id, max(date), email ...
it wouldn't make sense, because you need to specify a grouping function for the mail.
What you're really interested in, is "the email that corresponds to the row whose date is max(date) for a given id".
This must be done using a subquery. Something like this:
SELECT
tmax.cid,
tmax.maxdate,
table1.email,
table2.status
FROM
table2
INNER JOIN table1
ON table1.cid = table2.id
INNER JOIN (
SELECT
cid,
max(date) AS maxdate
FROM
table1
GROUP BY
cid
) AS tmax
ON tmax.cid = table1.cid AND tmax.maxdate = table1.date;
The above query executed on your data set, will give this exact output (2 rows):
cid maxdate email status
12345 2018-02-13 09:41:43 a#gmail.com 1
45678 2018-02-02 10:14:42 n#gmail.com 1
which means, in English: "For each id in table2, bring its status, and bring the line in table1 for the corresponding cid, and whose date is the max date for same cid within table1."
Because I used INNER JOINs, the records in table1 that mention a cid that does not exist in table2, are discarded.
You could write the query like this (add an order desc on u.date):
SELECT c.id 'table 2 Id', DATE_FORMAT(MAX(u.date),'%Y-%m-%dT%TZ') 'Date', u.email 'User'
FROM table2 c
LEFT JOIN table1 u ON u.cId = c.id
WHERE c.status = 1
GROUP BY c.id
ORDER BY c.id, u.date DESC;

SQL: how to select customers who have ordered multiple items

here is some sample data:
ID Item
1 A
1 A
1 B
2 A
2 A
3 A
3 A
3 A
Question: Im trying to write code so that the only records that are selected are those of customer with ID 1 (ie a customer that has both product A and B). So results should look like this:
1 A
1 A
1 B
I've tried a lot of different things, but I am stuck. I tried self-join, but it doesnt produce what I want:
SELECT a.id, a.item
FROM table1 a Join table1 b on a.id=b.id
WHERE upper(a.item) = 'A'
AND upper(b.item) = 'B';
This will give me the right customer (ie customer 1) but it doesnt pull all 3 records. It just gives 1 row.
the closest similar question is
enter link description here
since you want to see which users match a certain condition and the fetch everything about those users - you need a nested query:
SELECT id,item FROM table1 WHERE id IN(
SELECT a.id
FROM table1 a Join table1 b on a.id=b.id
WHERE upper(a.item) = 'A'
AND upper(b.item) = 'B'
)
I took your working query, and used it in a WHERE clause for a more generic query - should do the trick for you
You could use your query as subselect to get the pid and then output all the pids rows. Like this:
SELECT id, item
FROM table1
WHERE id IN (SELECT a.id
FROM table1 a
JOIN table1 b
ON a.id=b.id
WHERE UPPER(a.item) = 'A'
AND UPPER(b.item) = 'B')
is it this what you are looking for? or may be I didn't understand your question.
SELECT a.pid, a.mname
FROM meds a
WHERE a.pid = 1

sql - select rows with a distinct value in a specific column

Let's assume that I have the following table:
id player_name team
1 Gladiator A
2 DarkLord B
3 Alligator A
4 MonaLisa C
5 SpongBob C
6 Mikasa B
I want to select one player from each team, which means that all the selected rows must have a unique value in the 'team' column. How can I accomplish this in MySQL?
In my example the selected rows should be:
id player_name team
1 Gladiator A
2 DarkLord B
4 MonaLisa C
This is one way to do it using a derived table so you select one id per team and join it to the original table.
select t.id, t.player_name, t.team
from tablename t
join (select team, min(id) as minid from tablename group by team) x
on x.team = t.team and x.minid = t.id
One simple way would be to fetch using a group by criteria. (Assuming your table name is TEAM_TABLE)
SELECT * FROM TEAM_TABLE GROUP BY TEAM;
This would return the first record occurring for each value of the team column.

SQL Left Join using COUNT

My query is so close, i've gone through almost all the other times this has been posted, but I'm not quite there.
SELECT a.name, IFNULL(b.student_id, 0) AS count
FROM student AS a
LEFT JOIN (SELECT student_id, COUNT(*) as count FROM quizactivity GROUP BY student_id)
AS b
ON a.id = b.student_id;
This returns a table with the names of the four entries, and then their actual id on their own table, a.id.
Name | Count
Will 1
Jane 2
Sally 0
Dave 4
Sally returns 0 because she has no results.
I am cleary returning the id of the table instead of the counts - where am I wrong?
Don't you want the count?
SELECT a.name, COALESCE(b.count, 0) AS count
FROM student a LEFT JOIN
(SELECT student_id, COUNT(*) as count
FROM quizactivity
GROUP BY student_id
) b
ON a.id = b.student_id;