sql 2008 remove duplicates from inner join - sql-server-2008

Using SQL 2008 R2. I am trying to find Employees that are Active, but were previously employees in one of our other companies. The following code works; however, I noticed that if the Employee has worked for more than two companies, I get duplicates. Is there another way that I need to write this so that I do not get duplicates? I have tried using the Group By and case with when exist and nothing seems to work.
SAMPLE DATA
╔═════════════╦══════╦══════════╦══════════╦══════════╦══════════╗
║ SSN ║ PRCo ║ Employee ║ FullName ║ HireDate ║ ActiveYN ║
╠═════════════╬══════╬══════════╬══════════╬══════════╬══════════╣
║ 123-45-6789 ║ 17 ║ 456789 ║ John Doe ║ 05/27/13 ║ Y ║
╠═════════════╬══════╬══════════╬══════════╬══════════╬══════════╣
║ 123-45-6789 ║ 23 ║ 456789 ║ John Doe ║ 08/22/11 ║ N ║
╠═════════════╬══════╬══════════╬══════════╬══════════╬══════════╣
║ 123-45-6789 ║ 1 ║ 456789 ║ John Doe ║ 12/03/07 ║ N ║
╠═════════════╬══════╬══════════╬══════════╬══════════╬══════════╣
║ 999-99-9999 ║ 17 ║ 999999 ║ Jane Doe ║ 05/27/13 ║ Y ║
╠═════════════╬══════╬══════════╬══════════╬══════════╬══════════╣
║ 999-99-9999 ║ 23 ║ 999999 ║ Jane Doe ║ 01/26/09 ║ N ║
╚═════════════╩══════╩══════════╩══════════╩══════════╩══════════╝
Using the following code
select distinct p1.SSN, p1.PRCo, p1.Employee, n.FullName, p1.HireDate, p1.ActiveYN,
case when p1.ActiveYN = 'Y' then 'Y'
when p2.ActiveYN = 'Y' then 'Y'
else 'N' end as AnyActiveCo
from PREH as p1
inner join PREH as p2 on p1.SSN=p2.SSN
left outer join PREHFullName as n on p1.PRCo=n.PRCo and p1.Employee=n.Employee
where p1.PRCo<>p2.PRCo
RESULTS; Row 3 & 5 are duplicates and do not have the desired AnyActiveCo result for an employee that was in 3 different companies; however employees with just 2 companies show fine.
╔═════╦═════════════╦══════╦══════════╦══════════╦══════════╦══════════╦═════════════╗
║ Row ║ SSN ║ PRCo ║ Employee ║ FullName ║ HireDate ║ ActiveYN ║ AnyActiveCo ║
╠═════╬═════════════╬══════╬══════════╬══════════╬══════════╬══════════╬═════════════╣
║ 1 ║ 123-45-6789 ║ 17 ║ 456789 ║ John Doe ║ 05/27/13 ║ Y ║ Y ║
╠═════╬═════════════╬══════╬══════════╬══════════╬══════════╬══════════╬═════════════╣
║ 2 ║ 123-45-6789 ║ 23 ║ 456789 ║ John Doe ║ 08/22/11 ║ N ║ Y ║
╠═════╬═════════════╬══════╬══════════╬══════════╬══════════╬══════════╬═════════════╣
║ 3 ║ 123-45-6789 ║ 23 ║ 456789 ║ John Doe ║ 08/22/11 ║ N ║ N ║
╠═════╬═════════════╬══════╬══════════╬══════════╬══════════╬══════════╬═════════════╣
║ 4 ║ 123-45-6789 ║ 1 ║ 456789 ║ John Doe ║ 12/03/07 ║ N ║ Y ║
╠═════╬═════════════╬══════╬══════════╬══════════╬══════════╬══════════╬═════════════╣
║ 5 ║ 123-45-6789 ║ 1 ║ 456789 ║ John Doe ║ 12/03/07 ║ N ║ N ║
╠═════╬═════════════╬══════╬══════════╬══════════╬══════════╬══════════╬═════════════╣
║ 6 ║ 999-99-9999 ║ 17 ║ 999999 ║ Jane Doe ║ 05/27/13 ║ Y ║ Y ║
╠═════╬═════════════╬══════╬══════════╬══════════╬══════════╬══════════╬═════════════╣
║ 7 ║ 999-99-9999 ║ 23 ║ 999999 ║ Jane Doe ║ 01/26/09 ║ N ║ Y ║
╚═════╩═════════════╩══════╩══════════╩══════════╩══════════╩══════════╩═════════════╝

Related

Access 2007 - Price Code from a Price Table

I have two tables. members and codes
I'm trying to get members.price to be automatically filled each time a new record is inserted - based on the code in members.price_code. It should match the codes.code and insert the correct codes.price in to members.price
I also need to do this for any existing members that currently have their codes set correctly, but the price field is empty
My members table:
╔════╦══════════════╦═════════════╦═══════╗
║ id ║ name ║ price_code ║ price ║
╠════╬══════════════╬═════════════╣═══════║
║ 1 ║ John Doe ║ M ║ ? ║
║ 2 ║ Jane Doe ║ M ║ ? ║
║ 3 ║ Peter Doe ║ S ║ ? ║
║ 4 ║ Lisa Doe ║ M ║ ? ║
╚════╩══════════════╩═════════════╩═══════╝
My Codes table
╔══════╦═══════════════╦═══════╗
║ code ║ description ║ price ║
╠══════╬═══════════════╬═══════╣
║ M ║ Member ║ 100 ║
║ S ║ Student ║ 50 ║
╚══════╩═══════════════╩═══════╝

Need help to retrieve data from three MySQL tables

I have three tables named "users","user_hobbies" and "hobbies". Below is the sample tables with values;Below is the users table with fields id, name and age
╔════╦══════╦═════╗
║ ID ║ NAME ║ AGE ║
╠════╬══════╬═════╣
║ 1 ║ abc ║ 23 ║
║ 2 ║ xyz ║ 24 ║
║ 3 ║ pqr ║ 21 ║
╚════╩══════╩═════╝
and below is user_hobbies table with fields id, user_id and hobby_id
╔════╦═════════╦══════════╗
║ ID ║ USER_ID ║ HOBBY_ID ║
╠════╬═════════╬══════════╣
║ 1 ║ 1 ║ 1 ║
║ 2 ║ 1 ║ 2 ║
║ 3 ║ 1 ║ 3 ║
║ 4 ║ 2 ║ 4 ║
║ 5 ║ 2 ║ 3 ║
║ 6 ║ 2 ║ 5 ║
║ 7 ║ 3 ║ 2 ║
║ 8 ║ 4 ║ 6 ║
╚════╩═════════╩══════════╝
. Below is the hobbies table with fields id and desc
╔════╦═══════════╗
║ ID ║ DESC ║
╠════╬═══════════╣
║ 1 ║ music ║
║ 2 ║ chatting ║
║ 3 ║ cricket ║
║ 4 ║ badminton ║
║ 5 ║ chess ║
║ 6 ║ cooking ║
╚════╩═══════════╝
. The actual requirement is that i need a query to retrieve name, age, hobby_id and desc (see an example below)
╔══════╦═════╦══════════╦═════════════════════════╗
║ NAME ║ AGE ║ HOBBYID ║ DESC ║
╠══════╬═════╬══════════╬═════════════════════════╣
║ abc ║ 23 ║ 1,2,3 ║ music,chatting,cricket ║
║ pqr ║ 21 ║ 2 ║ chatting ║
║ xyz ║ 24 ║ 4,3,5 ║ badminton,cricket,chess ║
╚══════╩═════╩══════════╩═════════════════════════╝
You need to join the tables first and use an aggregate function called GROUP_CONCAT().
SELECT a.Name,
a.Age,
GROUP_CONCAT(c.ID) hobbyIDs,
GROUP_CONCAT(c.desc) descList
FROM users a
INNER JOIN user_hobbies b
ON a.ID = b.user_ID
INNER JOIN hobbies c
ON b.hobby_ID = c.ID
GROUP BY a.Name, a.Age
SQLFiddle Demo
MySQL GROUP_CONCAT()
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
OUTPUT
╔══════╦═════╦══════════╦═════════════════════════╗
║ NAME ║ AGE ║ HOBBYIDS ║ DESCLIST ║
╠══════╬═════╬══════════╬═════════════════════════╣
║ abc ║ 23 ║ 1,2,3 ║ music,chatting,cricket ║
║ pqr ║ 21 ║ 2 ║ chatting ║
║ xyz ║ 24 ║ 4,3,5 ║ badminton,cricket,chess ║
╚══════╩═════╩══════════╩═════════════════════════╝

summing records

I have one table of records like
╔═════╦══════╦══════════╦══════════╗
║ PID ║ NAME ║ DATE1 ║ DATE2 ║
╠═════╬══════╬══════════╬══════════╣
║ 123 ║ john ║ 20110401 ║ 19700101 ║
║ 123 ║ john ║ 20110401 ║ 19700101 ║
║ 123 ║ john ║ 20110401 ║ 19700101 ║
║ 323 ║ mike ║ 20110401 ║ 19900101 ║
║ 323 ║ mike ║ 20110401 ║ 19900101 ║
╚═════╩══════╩══════════╩══════════╝
query1 is count on pid
query2 is if all the four fields are same the record is to be taken as one record else individual records and records to be counted on pid order.
The above result is:
╔═════╦══════════════╦═════════════╗
║ PID ║ TOTALRECORDS ║ TOTALUNIQUE ║
╠═════╬══════════════╬═════════════╣
║ 123 ║ 3 ║ 1 ║
║ 323 ║ 2 ║ 1 ║
╚═════╩══════════════╩═════════════╝
I did select pid,count(pid),(select count(pid) group by pid,name,date1,date2) from <table> group by pid;
But I get an error... kindly correct my code.
SELECT pid,
COUNT(*) totalRecords,
COUNT(DISTINCT name, date1, date2) totalUnique
FROM TableName
GROUP BY pid
SQLFiddle Demo
SQLFiddle Demo (with not unique record)
Result
╔═════╦══════════════╦═════════════╗
║ PID ║ TOTALRECORDS ║ TOTALUNIQUE ║
╠═════╬══════════════╬═════════════╣
║ 123 ║ 3 ║ 1 ║
║ 323 ║ 2 ║ 1 ║
╚═════╩══════════════╩═════════════╝

Get Records Not Present in Other Table

I have two tables:
all_countries
╔════╦═════════════╗
║ ID ║ COUNTRY ║
╠════╬═════════════╣
║ 1 ║ USA ║
║ 2 ║ China ║
║ 3 ║ India ║
║ 4 ║ France ║
║ 5 ║ UK ║
║ 6 ║ Australia ║
║ 7 ║ Philippines ║
╚════╩═════════════╝
supported_countries
╔════════════╦═══════════╦═══════════╗
║ COUNTRY_ID ║ COUNTRY ║ FILTER_ID ║
╠════════════╬═══════════╬═══════════╣
║ 1 ║ USA ║ 1 ║
║ 2 ║ China ║ 1 ║
║ 3 ║ India ║ 1 ║
║ 4 ║ France ║ 2 ║
║ 1 ║ USA ║ 2 ║
║ 6 ║ Australia ║ 2 ║
╚════════════╩═══════════╩═══════════╝
Query:
SELECT a.*
FROM all_countries a
LEFT JOIN supported_countries s
ON a.id = s.country_id
WHERE s.country_id IS NULL;
So as per above example I should get.
UK
Philippines
It works fine, but what if, if I filter the country example I choose to filter = 2.
i get zero result.
SELECT a.*
FROM all_countries a
LEFT JOIN supported_countries s
ON a.id = s.country_id
WHERE s.filter = 2 AND s.country_id IS NULL;
supposed to be i want to get this result, if filter = 2.
╔════╦═════════════╗
║ ID ║ COUNTRY ║
╠════╬═════════════╣
║ 2 ║ China ║
║ 3 ║ India ║
║ 5 ║ UK ║
║ 7 ║ Philippines ║
╚════╩═════════════╝
Am I doing the correct query?
add the condition on the ON clause,
SELECT a.*
FROM all_countries a
LEFT JOIN supported_countries s
ON a.id = s.country_id AND
s.filter_ID = 2 -- <<=== HERE
WHERE s.country_id IS NULL;
SQLFiddle Demo
Result:
╔════╦═════════════╗
║ ID ║ COUNTRY ║
╠════╬═════════════╣
║ 2 ║ China ║
║ 3 ║ India ║
║ 5 ║ UK ║
║ 7 ║ Philippines ║
╚════╩═════════════╝

Join table to get the latest rows from unique row

I have two table
The table structure goes something like this
Table A
╔══════╦════════╗
║ P_ID ║ P_NAME ║
╠══════╬════════╣
║ 1 ║ name1 ║
║ 2 ║ name2 ║
║ 3 ║ name3 ║
║ 4 ║ name5 ║
╚══════╩════════╝
Table B
╔═════╦════════╦════════╦═══════════╦═══════╗
║ ID ║ P_ID ║ C_ID ║ C_PRICE ║ TIME ║
╠═════╬════════╬════════╬═══════════╬═══════╣
║ 1 ║ 1 ║ 3 ║ 11 ║ 11111 ║
║ 2 ║ 2 ║ 4 ║ 22 ║ 22222 ║
║ 3 ║ 3 ║ 5 ║ 33 ║ 33333 ║
║ 4 ║ 3 ║ 6 ║ 44 ║ 44444 ║
║ 5 ║ 3 ║ 6 ║ 55 ║ 55555 ║
║ 6 ║ 4 ║ 7 ║ 66 ║ 66666 ║
╚═════╩════════╩════════╩═══════════╩═══════╝
The requirement is
1. Join two table
2. Group By C_ID
3. The latest rows in Group By
I tried to modify the answer By Bill Karwin from How do I join the most recent row in one table to another table?
SELECT e.*, s1.*
FROM table_a e
INNER JOIN
table_b s1
ON (e.p_id = s1.p_id)
LEFT OUTER JOIN table_b s2
ON (e.p_id = s2.p_id AND s1.id < s2.id)
WHERE s2.p_id IS NULL;
but I could not achieve what I want. From his answer I will get
╔═════╦════════╦════════╦═══════════╦═══════╦═════════╗
║ ID ║ P_ID ║ C_ID ║ C_PRICE ║ TIME ║ P_NAME ║
╠═════╬════════╬════════╬═══════════╬═══════╬═════════╣
║ 1 ║ 1 ║ 3 ║ 11 ║ 11111 ║ name1 ║
║ 2 ║ 2 ║ 4 ║ 22 ║ 22222 ║ name2 ║
║ 5 ║ 3 ║ 6 ║ 55 ║ 55555 ║ name3 ║
║ 6 ║ 4 ║ 7 ║ 66 ║ 66666 ║ name5 ║
╚═════╩════════╩════════╩═══════════╩═══════╩═════════╝
But the output what I want is as below ( dublicate P_ID is ok but for each dublicate P_ID should not have dublicate C_ID )
╔═════╦════════╦════════╦═══════════╦═══════╦═════════╗
║ ID ║ P_ID ║ C_ID ║ C_PRICE ║ TIME ║ P_NAME ║
╠═════╬════════╬════════╬═══════════╬═══════╬═════════╣
║ 1 ║ 1 ║ 3 ║ 11 ║ 11111 ║ name1 ║
║ 2 ║ 2 ║ 4 ║ 22 ║ 22222 ║ name2 ║
║ 3 ║ 3 ║ 5 ║ 33 ║ 33333 ║ name3 ║
║ 5 ║ 3 ║ 6 ║ 55 ║ 55555 ║ name3 ║
║ 6 ║ 4 ║ 7 ║ 66 ║ 66666 ║ name5 ║
╚═════╩════════╩════════╩═══════════╩═══════╩═════════╝
SELECT e.*, s1.*
FROM table_a e INNER JOIN
(SELECT * FROM (SELECT * FROM table_b ORDER BY time DESC) temp GROUP BY c_id) s1;
The innermost ORDER BY ensures the for the same c_id the desired row always comes first, the outter GROUP BY will group on c_id, and having not specified otherwise will return the first row found for each group.
You must
Join two table
Group By C_ID
Number row for each group desc ordered by chosen field (last imply order!)
Filter by row number = 1.
This can help you for numbering rows.