Sorry guys, I'm gettin crazy with this...
My table:
ID Name Surname Capital Capital_Group Job Job_Group
---------- -------- ----------- ------------- ------ --------------
1 Michael Jackson LessThan50 Entertainer
1 Michael Jackson Medium Entertainer
2 John Lennon Small Swimmer
3 Clara Clinton Huge Runner
3 Clara Clinton Huge Sportsmen
I just want to get top row from each ID but not based on anything except that it occurs above the rest (it's already sorted). Any help apreciated, my sanity is at stake.
Presuming that your table sorted by Capital in descending order for each id and that id defines a group, the following may do what you want:
select t.*
from mytable as t
where not exists (select 1
from mytable as t2
where t2.id = t.id and t2.capital > t.capital
);
SELECT t.*
FROM mytable AS t
WHERE t.capital = (SELECT MAX(capital)
FROM mytable t2
WHERE t2.id = t.id)
Incidentally, what do you want to do when there are two people with the same id and capital?
with cte
(
select *, row_Number() over(Partition by ID order by Name ) as RowNumber
)
select * from cte
where RowNumber=1
try this, let me know ur comments on this.
SELECT *
FROM yourTable
GROUP BY id
HAVING MAX(Capital)
select distinct ID ,Name ,Surname,Capital from mytable order by ID
select *,row_number() over(order by ID) as RNO into #temp1
select * from #temp as t where RNO not in (select max(RNO) from #temp as tt group by ID )
i think it will help you
Related
how to remove other rows with same Word in the SQL Table column
For example
StudentUserID SessionID
DSteve 101
DSteve 102
CJohn 101
For Reporting purpose we only need first ever row with StudentUserID
You can get the first row that has no overlap with other rows:
select t.*
from t
where not exists (select 1
from t t2
where (t2.name like '%' + t.name + '%' or
t.name like '%' + t2.name + '%'
) and
t2.SessionID < t.SessionID
);
This seems to be technically what you are asking for. It is not clear that this is actually useful.
EDIT:
For your revised question, I'll use a similar query:
select t.*
from t
where not exists (select 1
from t t2
where t2.StudentUserId = t2.StudentuserId and
t2.SessionID < t.SessionID
);
or make it otherwise
WITH b AS (SELECT t.*,
row_number() over(partition by student_name order by student_name ) as _rnk
from t )
SELECT * FROM b WHERE _rnk=1
although the purpose of that reporting is questionable :)
this will give you a unique student name output others will be dropped
but normally you would want to have a unique id for each student because there can be
multiple John Smiths etc.
You can use row_number() :
select t.*
from (select t.*,
row_number() over (partition by StudentUserID order by SessionID) as seq
from table t
) t
where seq = 1;
I have a table without any primary key and I want it all duplicate records
Table --
EmpName City
-------------
Shivam Noida
Ankit Delhi
Mani Gurugram
Shivam Faizabad
Mukesh Noida
and want output like this --
EmpName City
-------------
Shivam Noida
Shivam Faizabad
Mukesh Noida
Thanks in Advance.
I think you want exists:
select t.*
from t
where exists (select 1
from t t2
where (t2.empname = t.empname and t2.city <> t.city) or
(t2.city = t.city and t2.empname <> t.empname)
);
You seem to be looking for all rows where the name or city also appears in another row of the table.
select *
from mytable
where city in (select city from mytable group by city having count(*) > 1)
or empname in (select empname from mytable group by empname having count(*) > 1);
You say there is no primary key. This suggests that there can be duplicate rows (same name and city). This makes it impossible in many DBMS to use EXISTS here to look up the other rows. This is why I am suggesting IN and COUNT.
use exists and or condition
with cte as
(
select 'Shivam' as name, 'Noida' as city union all
select 'Ankit' , 'Delhi' union all
select 'Mani' , 'Gurugram' union all
select 'Shivam' , 'Faizabad' union all
select 'Mukesh' , 'Noida'
) select t1.* from cte t1 where exists ( select 1 from cte t2
where t1.name=t2.name
group by name
having count(*)>1
)
or exists
(
select 1 from cte t2
where t1.city=t2.city
group by city
having count(*)>1
)
output
name city
Shivam Noida
Shivam Faizabad
Mukesh Noida
Do a UNION ALL to put both types of names in one column. (d1)
GROUP BY its result, and use HAVING to return only duplicates (d2).
JOIN:
select EmpName, City
from tablename t1
join (select name from
(select EmpName name from tablename
union all
select City from tablename) d1
group by name
having count(*) > 1) d2
on d2.name in (EmpName, City)
select distinct * from table
where col1 in (select col1 from table group by col1 having count(1) > 1)
or col2 in (select col2 from table group by col2 having count(1) > 1)
Is it possible to get only columns which have different values in SQL SERVER?
TABLE 1
id Name Desig
1 Ali Assistant.Manager
1 Ali Manager
2 John Manager
Now if i want to check status of id 1, it should return Designation(i.e Assistant.Manager & Manager)
Try this:
SELECT T1.Desig
FROM TableName T1 JOIN
(SELECT id,name
FROM TableName
GROUP BY id,name
HAVING COUNT(DISTINCT Desig) > 1) T2
ON T1.id=T2.id AND T1.name=T2.name
Result:
DESIG
Assistant.Manager
Manager
See result in SQL Fiddle.
If id is an identity, as you comment, you can choose the latest row per name like:
select *
from (
select row_number() over (
partition by name
order by id desc) as rn
, *
) as SubQueryAlias
where rn = 1 -- Latest row per name
I'm using Microsoft's SQL Server 2008. I need to aggregate by a foreign key to randomly get a single value, but I'm stumped. Consider the following table:
id fk val
----------- ----------- ----
1 100 abc
2 101 def
3 102 ghi
4 102 jkl
The desired result would be:
fk val
----------- ----
100 abc
101 def
102 ghi
Where the val for fk 102 would randomly be either "ghi" or "jkl".
I tried using NEWID() to get unique random values, however, the JOIN fails since the NEWID() value is different depending on the sub query.
WITH withTable AS (
SELECT id, fk, val, CAST(NEWID() AS CHAR(36)) random
FROM exampleTable
)
SELECT t1.fk, t1.val
FROM withTable t1
JOIN (
SELECT fk, MAX(random) random
FROM withTable
GROUP BY fk
) t2 ON t2.random = t1.random
;
I'm stumped. Any ideas would be greatly appreciated.
I might think about it a little differently, using a special ranking function called ROW_NUMBER().
You basically apply a number to each row, grouped by fk, starting with 1, ordered randomly by using the NEWID() function as a sort value. From this you can select all rows where the row number was 1. The effect of this technique is that it randomizes which row gets assigned the value 1.
WITH withTable(id, fk, val, rownum) AS
(
SELECT
id, fk, val, ROW_NUMBER() OVER (PARTITION BY fk ORDER BY NEWID())
FROM
exampleTable
)
SELECT
*
FROM
withTable
WHERE
rownum = 1
This approach has the added benefit in that it takes care of the grouping and the randomization in one pass.
You can do this not with aggregation but with row_number():
select id, fk, val
from (select t1.*,
row_number() over (partition by fk order by newid()) as seqnum
from withTable t1
) t1
where seqnum = 1
One option is to get the values that are the same fk into a temp table then SELECT TOP 1 ORDER by NEWID()
That should work for you.
suppose I have following sql table
objid firstname lastname active
1 test test 0
2 test test 1
3 test1 test1 1
4 test2 test2 0
5 test2 test2 0
6 test3 test3 1
Now, the result I am interested in is as follows:
objid firstname lastname active
1 test test 0
2 test test 1
4 test2 test2 0
5 test2 test2 0
How can I achieve this?
I have tried the following query,
select firstname,lastname from table
group by firstname,lastname
having count(*) > 1
But this query gives results like
firstname lastname
test test
test2 test2
You've found your duplicated records but you're interested in getting all the information attached to them. You need to join your duplicates to your main table to get that information.
select *
from my_table a
join ( select firstname, lastname
from my_table
group by firstname, lastname
having count(*) > 1 ) b
on a.firstname = b.firstname
and a.lastname = b.lastname
This is the same as an inner join and means that for every record in your sub-query, that found the duplicate records you find everything from your main table that has the same firstseen and lastseen combination.
You can also do this with in, though you should test the difference:
select *
from my_table a
where ( firstname, lastname ) in
( select firstname, lastname
from my_table
group by firstname, lastname
having count(*) > 1 )
Further Reading:
A visual representation of joins from Coding Horror
Join explanation from Wikipedia
SELECT DISTINCT t1.*
FROM myTable AS t1
INNER JOIN myTable AS t2
ON t1.firstname = t2.firstname
AND t1.lastname = t2.lastname
AND t1.objid <> t2.objid
This will output every row which has a duplicate, basing on firstname and lastname.
Here's a little more legible way to do Ben's first answer:
WITH duplicates AS (
select firstname, lastname
from my_table
group by firstname, lastname
having count(*) > 1
)
SELECT a.*
FROM my_table a
JOIN duplicates b ON (a.firstname = b.firstname and a.lastname = b.lastname)
SELECT user_name,email_ID
FROM User_Master WHERE
email_ID
in (SELECT email_ID
FROM User_Master GROUP BY
email_ID HAVING COUNT(*)>1)
nice option get all duplicated value from tables
select * from Employee where Name in (select Name from Employee group by Name having COUNT(*)>1)
This is the easiest way:
SELECT * FROM yourtable a WHERE EXISTS (SELECT * FROM yourtable b WHERE a.firstname = b.firstname AND a.secondname = b.secondname AND a.objid <> b.objid)
If you want to print all duplicate IDs from the table:
select * from table where id in (select id from table group By id having count(id)>1)
I'm surprised that there is no answer using Window function. I just came across this use case and this helped me.
select t.objid, t.firstname, t.lastname, t.active
from
(
select t.*, count(*) over (partition by firstname, lastname) as cnt
from my_table t
) t
where t.cnt > 1;
Fiddle - https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=c0cc3b679df63c4d7d632cbb83a9ef13
The format goes like
select
tbl.relevantColumns
from
(
select t.*, count(*) over (partition by key_columns) as cnt
from desiredTable t
) as tbl
where tbl.cnt > 1;
This format selects whatever columns you require from the table (sometimes all columns) where the count > 1 for the key_columns being used to identify the duplicate rows. key_columns can be any number of columns.
This answer may not be great one, but I think it is simple to understand.
SELECT * FROM table1 WHERE (firstname, lastname) IN ( SELECT firstname, lastname FROM table1 GROUP BY firstname, lastname having count() > 1);
This Query returns dupliacates
SELECT * FROM (
SELECT a.*
FROM table a
WHERE (`firstname`,`lastname`) IN (
SELECT `firstname`,`lastname` FROM table
GROUP BY `firstname`,`lastname` HAVING COUNT(*)>1
)
)z WHERE z.`objid` NOT IN (
SELECT MIN(`objid`) FROM table
GROUP BY `firstname`,`lastname` HAVING COUNT(*)>1
)
Please try
WITH cteTemp AS (
SELECT EmployeeID, JoinDT,
row_number() OVER(PARTITION BY EmployeeID, JoinDT ORDER BY EmployeeID) AS [RowFound]
FROM dbo.Employee
)
SELECT * FROM cteTemp WHERE [RowFound] > 1 ORDER BY JoinDT