SQL Query to get name that appear twice - sql

I have the below Table
Table1
Emp ID | Emp Name
001 | ABC
002 | DEF
003 | GHI
004 | ABC
005 | XYZ
I am trying to get EMP ID and Emp Name where Emp Name is same but Emp ID is different. There is primary key in the table
Here the output will be
Emp ID | Emp Name
001 | ABC
004 | ABC

You didn't specify your DBMS, so this is ANSI SQL:
select emp_id, emp_name
from (
select emp_id, emp_name,
count(*) over (partition by emp_name) as name_count
from employee
) t
where name_count > 1^;

Group by Emp_Name, select records having count Emp_ID more than one and then select all records from table having such Emp_Name:
select Emp_ID, Emp_Name
from Table1
where Emp_Name in
(
select Emp_Name
from Table1
group by Emp_Name
having count(Emp_ID) > 1
)

Please try with below.
SELECT T1.* FROM
TABLE1 T1
JOIN
(
SELECT EMP_NAME, COUNT(EMP_ID) FROM TABLE1 GROUP BY EMP_NAME HAVING COUNT(EMP_ID) > 1
) T2 ON T1.EMP_NAME = T2.EMP_NAME

I have the same problem yesterday :) and i believe below code will give you what you want.
Use INNER JOIN to make a self join query, then use HAVING clause.
CREATE TABLE #Table1 (Emp_ID int, Emp_Name varchar(50))
INSERT INTO [#Table1]
(
[Emp_ID],
[Emp_Name]
)
SELECT '001','ABC'
UNION ALL SELECT '002','DEF'
UNION ALL SELECT '003','GHI'
UNION ALL SELECT '004','ABC'
UNION ALL SELECT '005','XYZ'
SELECT [t1].[Emp_ID], [t1].[Emp_Name] FROM [#Table1] t1
INNER JOIN
(
SELECT [#Table1].[Emp_Name] FROM [#Table1]
GROUP BY [#Table1].[Emp_Name]
HAVING COUNT([#Table1].[Emp_ID]) > 1
) t2
ON [t1].[Emp_Name] = [t2].[Emp_Name]
DROP TABLE [#Table1]
Below is the result:
Emp_ID Emp_Name
1 ABC
4 ABC
SQL Fiddle Demo - Click here

Another EXISTS version, but without any aggregating:
select t1.*
from tablename t1
where exists (select 1 from tablename t2
where t2.Emp_Name = t1.Emp_Name
and t2.Emp_ID <> t1.Emp_ID)
May speed up things a bit. Otherwise I'd try self join version:
select t1.*
from tablename t1
join tablename t2 on t2.Emp_Name = t1.Emp_Name
and t2.Emp_ID <> t1.Emp_ID
Perhaps, depending on data, you need to do SELECT DISTINCT.

Related

Create a duplicate row on top of Select statement

table TEST
id
Name
1
abc
2
xyz
In general i used to get records from below query
Select id,name from TEST.
id
Name
1
abc
2
xyz
but now i want to create a duplicate for each row on top my select query
expected output: please suggest how can i achieve result like below
id
Name
1
abc
1
abc
2
xyz
2
xyz
You may cross join your table with a sequence table containing how ever many copies you want. Here is an example using an inline sequence table:
SELECT t1.id, t1.Name
FROM yourTable t1
CROSS JOIN (
SELECT 1 AS seq FROM dual UNION ALL
SELECT 2 FROM dual UNION ALL
SELECT 3 FROM dual
) t2
WHERE t2.seq <= 2
ORDER BY t1.id;
To me, UNION (ALL) set operator seems to be quite simple.
Sample data:
SQL> select * from test;
ID NAME
---------- ----
1 abc
2 xyz
UNION ALL:
SQL> select * from test
2 union all
3 select * from test;
ID NAME
---------- ----
1 abc
2 xyz
1 abc
2 xyz
SQL>
CREATE table test(
id integer,
name VARCHAR2(4)
);
INSERT into test (id, name) VALUES (1,'ABC');
INSERT into test (id, name) VALUES (2,'XYZ');
with data as (select level l from dual connect by level <= 2)
select *
from test, data
order by id, l
/
One more option is LATERAL
SELECT t.*
FROM test
, LATERAL (
SELECT id, name FROM DUAL
union all
SELECT id, name FROM DUAL
) t
One option is using a self-join along with ROW_NUMBER analytic function such as
WITH t AS
(
SELECT t1.id, t1.name, ROW_NUMBER() OVER (PARTITION BY t1.id ORDER BY 0) AS rn
FROM test t1,
test t2
)
SELECT id, name
FROM t
WHERE rn <= 2
Demo

sql select values from another table if exist

Please help, need to select from table 1, but if entry with the same id exists in table2 should return name and last name from there otherwise values from table1
table1
id|name|lastname
1 | |
2 | |
3 | |
table2
id|name|lastname
3 | |
Tried this, but not working
SELECT ID, NAME, LASTNAME
FROM table1
WHERE EXISTS
(SELECT 1 FROM table2 WHERE table2.ID = table1.ID)
if entry with the same id exists in table2 should return name and last name from there otherwise values from table1
You want a LEFT OUTER JOIN and then to use COALESCE:
SELECT t1.id,
COALESCE( t2.name, t1.name ) AS name,
COALESCE( t2.lastname, t1.lastname ) AS last_name
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON ( t1.id = t2.id )
Which, for your sample data:
CREATE TABLE table1 ( id, name, lastname ) AS
SELECT 1, 'Alice1', 'Abbot1' FROM DUAL UNION ALL
SELECT 2, 'Betty1', 'Baron1' FROM DUAL UNION ALL
SELECT 3, 'Carol1', 'Casey1' FROM DUAL;
CREATE TABLE table2 ( id, name, lastname ) AS
SELECT 3, 'Carol2', 'Casey2' FROM DUAL;
Outputs:
ID
NAME
LAST_NAME
3
Carol2
Casey2
2
Betty1
Baron1
1
Alice1
Abbot1
db<>fiddle here

how to find collegue Id in table

i have one table as Employee that have two column Id and Branch. i have to find its collegue Id except his own id from table without using subquery.
Id Branch
==============
1 Delhi
2 Mumbai
3 Delhi
4 Delhi
5 Mumbai
6 Mumbai
if i enter e.g. 3 then my answer has to be 1 and 4.
Without a subquery means with a self join:
select tt.*
from tablename t inner join tablename tt
on t.Branch = tt.Branch and tt.id <> t.id
where t.id = 3
See the demo.
use self join
select t2.id from table_name t1
join table_name t2 on t1.Branch=t2.Branch
where t1.id=3 and t2.id!=3
for data preparation easily i used CTE version below with result
with cte as
(
select 1 as id, 'Delhi' as b
union all
select 2, 'Mumbai'
union all
select 3 , 'Delhi'
union all
select 4 , 'Delhi'
) select t2.id from cte t1 join cte t2 on t1.b=t2.b
where t1.id=3 and t2.id!=3
demo link
here is the output
id
1
4
This query should give you the answer you're after:
SELECT E1.Id
FROM Employee E1
INNER
JOIN Employee E2
ON E1.[Branch] = E2.[Branch]
WHERE E2.Id = 3
AND E1.Id <> 3
It works by joining the Employee table onto itself, by Branch and then:
WHERE E2.Id = 3 - Where the Employee is Id # 3
AND E1.Id <> 3 - excluding any records from the original Employee table where Id is 3
Here's the script I used to create your test data (in SQL Server) for the purposes of validating the query:
CREATE TABLE [Employee]
(
[Id] INT,
[Branch] NVARCHAR(10)
)
INSERT
INTO [Employee]
(
Id,
[Branch]
)
VALUES (1, 'Delhi'),
(2, 'Mumbai'),
(3, 'Delhi'),
(4, 'Delhi'),
(5, 'Mumbai'),
(6, 'Mumbai')

Delete Rows based on two columns

How can I delete rows based on just two column conditions.
Example
Table 1
id name phone
1 aa 123
1 aa 345
1 bb 123
2 aa 456
1 NULL 123
1 123
My Expected output
id name phone
1 bb 123
2 aa 456
My condition to delete: if id and name is same, delete the rows
If one of the value in a condition is null or blank it should also delete the row as given in the input.
Delete from table1 t where exists (
Select * from
(Select id, name from table1 group by id, name having count(*) > 1) t2 where t.id = t2.id and t.name = t2.name)
This should do what you want. You can do the select first for testing purposes, then remove the Select and uncomment out the delete.
-- This joins on the table the set of data that has more then 1 row with duplicate IDs, and names. Then you can delete from here.
--DELETE t1
SELECT *
FROM Table1 T1
INNER JOIN (
-- this gets all the records that have more then 1 ID and Name that are the same.
SELECT ID, name
FROM Table1
GROUP BY ID, name
HAVING COUNT(*) > 1
) ToDelete ON T1.ID = ToDelete.ID
AND T1.name = ToDelete.name
create table #tablea (
id int,
name varchar(3),
phone int
)
insert into #tablea (id, name, phone)
values
(1,'aa','123'),
(1,'aa','345'),
(1,'bb','123'),
(2,'aa','456')
select * from #tablea
delete a
from #tablea a
inner join (
select id, name
from #tablea
group by id, name
having COUNT(*) > 1
) b on a.id = b.id and a.name = b.name
select * from #tablea
drop table #tablea

Return different rows between two tables

Is there a way to check and return all rows that are not common between two tables?
Table 1:
pk name date
102 John 1/1/16
101 Bob 1/1/17
Table 2:
pk name date
102 John 1/1/16
104 Bob 1/1/17
105 Ted 1/1/18
Ideally, I can also limit the query by date. So If I limit by Date < 1/1/18, the result would be:
table pk name date
1 101 Bob 1/1/17
2 104 Bob 1/1/17
select * from table1
union
select * from table2
except
(select * from table1 intersect select * from table2)
select * from table1 t1
where not exsits (
select 1 from table2 t2 where t2.pk = t1.pk
) and t1.Date < '2018/1/1'
union all
select * from table2 t2
where not exsits (
select 1 from table1 t1 where t2.pk = t1.pk
) and t2.Date < '2018/1/1'
You can use EXCEPT for this like
select pk,
name,
date from table1
except
select pk,
name,
date from table2;
(OR) using NOT IN operator along with UNION like
select * from table1 where pk not in (select distinct pk from table2);
union
select * from table2 where pk not in (select distinct pk from table1);
To be more precise with your sample data:
SELECT * FROM
(( SELECT 1 as [table],* FROM
(SELECT * FROM #TABLE_1
EXCEPT
SELECT * FROM #TABLE_2) AS Inner1)
UNION
(SELECT 2 as [table],* FROM
(SELECT * FROM #TABLE_2
EXCEPT
SELECT * FROM #TABLE_1) AS Inner2)) AS Final
WHERE Final.date < '2018-01-01'