Select Only the row with smallest id - sql

suppose I have the following table X:
Id Type Name
1 1 Jane
2 2 Mary
3 3 Rose
4 4 Rachel
5 4 Darren
6 4 Jay
What will be the select statement to generate:
Id Type Name
1 1 Jane
2 2 Mary
3 3 Rose
4 4 Rachel
that only the first row for each type will be selected? Appreciate a lot.

A simple method is to use a correlated subquery:
select t.*
from t
where t.id = (select min(t2.id) from t t2 where t2.type = t.type);
Here is the DEMO for the same.

Please try
SELECT t.* FROM test t
INNER JOIN (SELECT MIN(id) id FROM test GROUP BY TYPE) t2 ON t.id = t2.id;

You may use row_number() analytic function if your database supports it.
SELECT Id
,Type
,Name
FROM (
SELECT X.*
,row_number() OVER (
PARTITION BY type ORDER BY Id
) rn
FROM X
) a
WHERE rn = 1;
Demo

Related

Get all the users that has only 1 category in SQL

I have this table with U that represents "User" and C that represents "Category". I need a way to query how many categories a user has and limit that to 1. So basically, I need to get all the users that has only 1 category. How can this be achieved with SQL (PostgreSQL)?
I've tried to find any solution on Stackoverflow for a while now, but without success.
id U C
1 3 5
2 1 3
3 3 5
4 5 2
5 11 5
6 11 5
Expected result:
id U C
1 1 3
2 5 2
That is easy with the HAVING clause:
SELECT max(id), u, max(c)
FROM atable
GROUP BY u HAVING count(c) = 1
You can use window functions for your purpose.
Window Functions
SELECT DISTINCT * FROM(
SELECT a.*,count(c)over(partition by id) as cnt
FROM testtable a
) WHERE CNT=1
If you have no duplicates, you can use not exists:
select t.*
from t
where not exists (select 1 from t t2 where t2.u = t.u and t2.c <> t.c);
If you have duplicates of u/c, just use id:
select t.*
from t
where not exists (select 1 from t t2 where t2.u = t.u and t2.id <> t.id);
If you want to reassign a sequential number, then use row_number() as well:
select row_number() over (order by id) as new_id, t.*
from t
where not exists (select 1 from t t2 where t2.u = t.u and t2.c <> t.c);

SQL select top if columns are same

If I have a table like this:
Id StateId Name
1 1 a
2 2 b
3 1 c
4 1 d
5 3 e
6 2 f
I want to select like below:
Id StateId Name
4 1 d
5 3 e
6 2 f
For example, Ids 1,3,4 have stateid 1. So select row with max Id, i.e, 4.
; WITH CTE AS
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY STATEID ORDER BY ID DESC) AS RN
)SELECT ID, STATEID, NAME FROM CTE WHERE RN = 1
You can use ROW_NUMBER() + TOP 1 WITH TIES:
SELECT TOP 1 WITH TIES
Id,
StateId,
[Name]
FROM YourTable
ORDER BY ROW_NUMBER() OVER (PARTITION BY StateId ORDER BY Id DESC)
Output:
Id StateId Name
4 1 d
6 2 f
5 3 e
Disclaimer: I gave this answer before the OP had specified an actual database, and hence avoided using window functions. For a possibly more appropriate answer, see the reply by #Tanjim above.
Here is an option using joins which should work across most RDBMS.
SELECT t1.*
FROM yourTable t1
INNER JOIN
(
SELECT StateId, MAX(Id) AS Id
FROM yourTable
GROUP BY StateId
) t2
ON t1.StateId = t2.StateId AND
t1.Id = t2.Id
The following using a subquery, to find the maximum Id for each of the states. The WHERE clause then only includes rows with ids from that subquery.
SELECT
[Id], [StateID], [Name]
FROM
TABLENAME S1
WHERE
Id IN (SELECT MAX(Id) FROM TABLENAME S2 WHERE S2.StateID = S1.StateID)

Select Grouped Column Values Where Have Same Id In SQL Server

I have a table like this.
TABLE-1
id Code
-----------------
1 N188
1 N1Z2
1 N222
2 N189
2 N1Z2
2 N1Z3
3 N188
3 A123
3 B321
4 N188
4 A333
4 B444
I want to select id and code only code has N188.Result should like this:
TABLE-2
id Code
---------------
1 N188
1 N1Z2
1 N222
3 N188
3 A123
3 B321
4 N188
4 A333
4 B444
How can I write sql for this in SQL Server?
Thanks
You can use EXISTS for this:
SELECT id, code
FROM table1 t
WHERE EXISTS (
SELECT 1
FROM table1 t2
WHERE t.id = t2.id
AND t2.Code = 'N188'
)
Condensed SQL Fiddle Demo
Using INNER JOIN
SELECT *
FROM tablename A
JOIN (SELECT id
FROM tablename
WHERE code = 'N188') B
ON a.id = b.id
Here is an alternative method that uses window functions:
select id, code
from (select t.*,
sum(case when code = 'N188' then 1 else 0 end) over (partition by id) as cnt_n188
from table t
) t
where cnt_n188 > 0;

Last record based on 2 column values

pass_id retry_id
1 1
1 2
2 1
2 2
2 3
3 1
3 2
Need to pick up record with MAX(retry_id) within MAX(pass_id).
pass_id retry_id
3 2
Thanks in advance!
The easiest way is with order by and just choosing one row:
select t.pass_id, t.retry_id
from (select t.*
from t
order by pass_id desc, retry_id desc
) t
where rownum = 1
Here is a SQLFiddle.
SELECT *
FROM MyTable
WHERE
retry_id = (Select MAX(retry_id) FROM MyTable) AND
pass_id = (Select MAX(pass_id) FROM MyTable)
Not positive on oracle syntax, but something like
SELECT MAX(retry_ID)
FROM Table
WHERE Pass_ID = (SELECT MAX(Pass_ID)
FROM Table)

Make Two Queries into 1 result set with 2 columns

Say I have a table that looks like this:
Person Table
ID AccountID Name
1 6 Billy
2 6 Joe
3 6 Tom
4 8 Jamie
5 8 Jake
6 8 Sam
I have two queries that I know work by themselves:
Select Name Group1 from person where accountid = 6
Select Name Group2 from person where accountid = 8
But I want a single Result Set to look like this:
Group1 Group2
Billy Jamie
Joe Jake
Tom Same
You can use row_number() to assign a distinct value for each row, ans then use a FULL OUTER JOIN to join the two subqueries:
select t1.group1,
t2.group2
from
(
select name group1,
row_number() over(order by id) rn
from yourtable
where accountid = 6
) t1
full outer join
(
select name group2,
row_number() over(order by id) rn
from yourtable
where accountid = 8
) t2
on t1.rn = t2.rn;
See SQL Fiddle with Demo
I agree you should do this client side. But it can be done in T/SQL:
select G1.Name as Group1
, G2.Name as Group2
from (
select row_number() over (order by ID) as rn
, *
from Group
where AccountID = 6
) as G1
full outer join
(
select row_number() over (order by ID) as rn
, *
from Group
where AccountID = 8
) as G2
on G1.rn = G2.rn
order by
coalesce(G1.rn, G2.rn)