Delete duplicate rows for greater then 1 - sql-server-2014

I have a script that looks for duplicates. I want to know how now to delete those duplicates.
Select LastName, FirstName, DateOfBirth, Count (*) As Duplicates
From PatientDemographics2
Group by FirstName, LastName, DateOfBirth
Having count (*) >1
Order by LastName, FirstName Asc

You can ROW_NUMBER() to detect duplicate
WITH cte AS (
SELECT LastName, FirstName, DateOfBirth
, ROW_NUMBER() OVER(PARTITION BY LastName, FirstName, DateOfBirth ORDER BY LastName) AS rn
FROM PatientDemographic2
)
DELETE FROM cte
WHERE rn > 1

Or simply:
DELETE FROM PatientDemographics2 WHERE id NOT IN (
SELECT MIN(id) i1 FROM PatientDemographics2
GROUP BY FirstName, LastName, DateOfBirth
)
demo: https://rextester.com/KOZI16883

Related

delete duplicate record using rank() function in cte

with DeleteDUplicateinXYZ
as
(
Select ID, rank()over( order by Id Asc) as [rank]
from ppp -----------never use 'partion by' while using rank
)Delete from DeleteDUplicateinXYZ
where [rank] in (Select id, count([rank])
from DeleteDUplicateinXYZ group by Id having count([rank]) >=2)

MySQL Rows Based On Prority Values

Lets say I have a table with four columns: FirstName, LastName, Number (not a primary key) and Status. If a there are a persons with the same First name, Last name and number, but differing status (where status is a string such as "King" or "Queen" or "Jack").
I want to retrieve all the values from the table for all columns, but if there are duplicates where there are those with the same first name, last name, and number, I want to get those with status of "King", and if there a duplicates without the "King" status then get those with "Queen" and if there is no duplicates with "King" or "Queen" than only get one of those with "Jack".
Basically, the order of priority is King, Queen, and then Jack. so, I want all values from the table but if there are duplicates only include the one with the highest priority. I did some research and it appears that SQL implementations other than MYSql provide functions such as dense_rank, but I need to implement this in MYSql and I cannot find any way how.
try using session variable:
SET #row_number:=1;
SELECT
FirstName,
LastName,
Number,
Status
FROM(
SELECT
#row_number:=
CASE
WHEN #FirstName = FirstName AND #LastName = LastName AND #Number = Number
THEN #row_number + 1
ELSE 1
END AS num,
#FirstName := FirstName as FirstName,
#LastName := LastName as LastName,
#Number := Number as Number,
Status
FROM
t1
ORDER BY
FirstName,
lastName,
Number,
CASE
WHEN STATUS = 'King' THEN '1'
WHEN STATUS = 'Queen' THEN '2'
WHEN STATUS = 'Jack' THEN '3'
END
) as ttt
WHERE num = 1;
One method of doing this involves union all:
select t.*
from t
where t.status = 'King'
union all
select t.*
from t
where t.status = 'Queen' and
not exists (select 1 from t t2 where t2.name = t.name andt2.status in ('King'))
union all
select t.*
from t
where t.status = 'Jack' and
not exists (select 1 from t t2 where t2.name = t.name and t2.status in ('King', 'Queen'));
Another method uses a correlated subquery:
select t.*
from t
where (name, field(t.status, 'King', 'Queen', 'Jack')) in
(select t2.name, max(field(t2.status, 'King', 'Queen', 'Jack'))
from t t2
where t2.status in ('King', 'Queen', 'Jack')
group by t2.name
);

MySQL query for joining two queries

I have a mysql table having register number, dob, student name, sex, total mark in a semester in each row.
I would like to get records of 10 Boys and 5 girls in descending order of total marks in a single SQL query.
My MySQL dialect is rusty but this should do the trick
(SELECT * FROM Students WHERE sex = 'Male' ORDER BY TotalMarks DESC LIMIT 10)
UNION ALL
(SELECT * FROM Students WHERE sex = 'Female' ORDER BY TotalMarks DESC LIMIT 5)
It's a single query, mind you.
Try this code:
select
a.studentID,
a.studentName,
a.dob,
a.totalMark
from
(
select
studentID,
studentName,
dob,
totalMark
from
students
where
sex='M'
order by
studentMark desc
limit 10
union all
select
studentID,
studentName,
dob,
totalMark
from
students
where
sex='F'
order by
totalMark desc
limit 5
)
order by
totalMark desc
try this
select * from
(select reg_number, dob, student_name, sex, total_marks where sex='male'
order by total_marks desc limit 10
union
select reg_number, dob, student_name, sex, total_marks where sex='female'
order by total_marks desc limit 5) a order by total_marks desc

SQL query max(), count()

the database schema looks like
employee(employee_name,street,city)
works(employee_name,company_name,salary)
company(company_name,city)
manages(employee_name,manager_name)
the query needed to do is:
find the company that has the most employees.
I could find out the maximum count by the query:
SELECT max( cnt ) max_cnt
FROM (
SELECT count( employee_name ) cnt, company_name
FROM works
GROUP BY company_name
)w1;
But now I can't find out the name of the company. If anyone has some idea please share.
To get the entire row containing the maximum value you can use ORDER BY ... DESC LIMIT 1 instead of MAX:
SELECT company_name, cnt
FROM (
SELECT company_name, count(employee_name) AS cnt
FROM works
GROUP BY company_name
) w1
ORDER BY cnt DESC
LIMIT 1
How about something like:
SELECT count( employee_name ) cnt, company_name
FROM works
GROUP BY company_name
ORDER BY cnt DESC
LIMIT 1;
Edit:
Corrected above for MySQL
SELECT company_name,count(*) as cnt
FROM works
GROUP BY company_name
ORDER BY cnt DESC
select company_name
from works
group by company_name
having count(distinct employee_name)>=all(select count(distinct employee_name)
from works
group by company_name )
Here's the working query
Select * from(SELECT count(EmpName)cnt, CName FROM works GROUP BY CName Order By cnt desc) where ROWNUM = 1;
This looks like a course question.
If more than one companies have the same largest number of employees the query with LIMIT doesn't work. "ORDER BY" didn't filter out useless info. Thus we have the following solution
SELECT company_name FROM
(SELECT company_name, count(employee_name) cnt
FROM works
GROUP BY company_name)
JOIN
(SELECT max(cnt) max_cnt
FROM (
SELECT count(employee_name) cnt
FROM works
GROUP BY company_name
)) ON cnt = max_cnt
select company_name from works_for
group by company_name
having count(employee_name) = (select max(count(employee_name))from works_for
group by company_name);
In Oracle
select company_name, count(*) as count
from works
group by company_name
having count(*) >= all(select count(*) from works group by company_name)

Need help returning unique results in mySQL

I am having trouble and need some help finding a correct SQL query. Here is my code so far:
SELECT firstname, lastname, date_of_birth
FROM `data`
WHERE firstname IN (SELECT firstname
FROM `data`
WHERE diagnosis_location = 'Mayo')
AND lastname IN (SELECT lastname
FROM `data`
WHERE diagnosis_location = 'Mayo')
AND date_of_birth IN (SELECT date_of_birth
FROM `data`
WHERE diagnosis_location = 'Mayo')
AND firstname IN (SELECT firstname
FROM `data`
WHERE diagnosis_location = 'Lahey')
AND lastname IN (SELECT lastname
FROM `data`
WHERE diagnosis_location = 'Lahey')
AND date_of_birth IN (SELECT date_of_birth
FROM `data`
WHERE diagnosis_location = 'Lahey')
Yes, it's a monster of a query and probably isn't all that efficient. But what I am trying to do is only return the first name, last name, and date of birth of all patients diagnosed at both the 'Mayo' location and the 'Lahey' location. This query does return those patients, but it returns multiple rows of the same exact data.
How could I limit it so duplicates of the same exact results are trimmed out?
Use:
SELECT firstname, lastname, date_of_birth
FROM `data`
WHERE diagnosis_location IN ('Mayo', 'Lahey')
GROUP BY firstname, lastname, date_of_birth
HAVING COUNT(DISTINCT diagnosis_location) = 2
You should rather have a look at using EXISTS for something like this
Maybe try something like
SELECT DISTINCT
firstname,
lastname,
date_of_birth
FROM `data` d
WHERE EXISTS (
SELECT *
FROM `data` dE
WHERE d.firstname = dE.firstname
AND d.lastname = dE.lastname
AND d.date_of_birth = dE.date_of_birth
AND diagnosis_location ='Mayo'
)
AND EXISTS (
SELECT *
FROM `data` dE
WHERE d.firstname = dE.firstname
AND d.lastname = dE.lastname
AND d.date_of_birth = dE.date_of_birth
AND diagnosis_location = 'Lahey'
)
try this:
select `firstname`, `lastname`, `date_of_birth`
from `data`
where `diagnosis_location`='Mayo' or `diagnosis_location`='Lahey'
group by `firstname`, `lastname`, `date_of_birth`
having count(`diagnosis_location`) = 2