SQL: Extract Row ID Based on the Min Value of Another Column - sql-server

I can't seem to get this one. So I have a table like this:
RowID UserID Type Data
1 A A 1
2 A A 2
3 A B 1
4 A B 2
5 B A 1
6 B A 2
7 B B 1
8 B B 2
And I need to group this table by UserID and Type and then return the RowID for the record in each group that holds the MIN value in the Data column.
So for my result set would be:
1
3
5
7

For SQL Server >= 2005, you can do:
select RowID
from (
select RowID,
Rank() over (Partition BY UserID, Type
order by Data) as Rank
from MyTable
) tmp
where Rank = 1
SQL Fiddle Example
For SQL Server < 2005, you can do:
select t.RowID
from MyTable t
inner join (
select UserID, Type, min(Data) as MinData
from MyTable
group by UserID, Type
) tm on t.UserID = tm.UserID and t.Type = tm.Type
and t.Data = tm.MinData
SQL Fiddle Example

Related

How to select the value from the table based on category_id USING SQL SERVER

How to select the value from the table based on category_id?
I have a table like this. Please help me.
Table A
ID Name category_id
-------------------
1 A 1
2 A 1
3 B 1
4 C 2
5 C 2
6 D 2
7 E 3
8 E 3
9 F 3
How to get the below mentioned output from table A?
ID Name category_id
--------------------
1 A 1
2 A 1
4 C 2
5 C 2
7 E 3
8 E 3
Give a row number for each row based on group by category_id and sort by ascending order of ID. Then select the rows having row number 1 and 2.
Query
;with cte as (
select [rn] = row_number() over(
partition by [category_id]
order by [ID]
), *
from [your_table_name]
)
select [ID], [Name], [category_id]
from cte
where [rn] < 3;
Kindly run this query It really help You Out.
SELECT tbl.id,tbl.name, tbl.category_id FROM TableA as tbl WHERE
tbl.name IN(SELECT tbl2.name FROM TableA tbl2 GROUP BY tbl2.name HAVING Count(tbl2.name)> 1)
Code select all category_id from TableA which has Name entries more then one. If there is single entry of any name group by category_id then such data will be excluded. In above example questioner want to eliminate those records that have single Name entity like wise category_id 1 has name entries A and B among which A has two entries and B has single entry so he want to eliminate B from result set.

SQL select Top x records for two columns

I have a table like this
ProjectID PhaseID Comment CommentDate
1 1 a 2/15/2014
1 1 b 5/1/2014
1 2 c 8/15/2014
1 2 d 1/1/2015
2 1 e 1/21/2014
2 2 f 5/15/2014
2 2 g 1/1/2015
How do I get the lastest (Top 1) comment for each project for each phase? For example, for Project 1, phase 1, I should get "b" and "5/1/2014"
Thank you!
select ProjectID,PhaseID,Comment,CommentDate from
(select row_number() over(partition by Project_ID,PhaseID order by CommentDate desc) as rn,* from table) a
where a.rn = 1
This type of query works best when there's an identity column (and values are always inserted in order) but this should get you what you need assuming there's no overlapping commentDates
select t.*
from table t
inner join (
SELECT max(commentDate) as maxDate,
phaseId,
projectId
FROM table
group by phaseId, projectId
) maxComments on t.phaseId = maxComments.phaseId
and t.projectId = maxComments.projectId
and t.commentDate = maxComments.maxDate

Compare previous column value in SQL Server

There is a table with below structure:
ID XID RChange
1 1 1
2 2 1
3 3 1
4 1 0
5 2 0
6 3 1
ID column is an identity column
XID column will have some values repeating
RChange will have either 1 or 0
I need those rows from the table with RChange column value changing from 1 to 0 with same XID
i.e. in the above table, for XID 1 and 2 RChange value has changed from 1 to 0 but for XID 3 it has changed from 1 to 1.
So, I need to write a query which will retrieve
ID XID RChange
4 1 0
5 2 0
So, please help me with your ideas.
You have not included a timestamp so I am assuming the ID column will determine the order.
;WITH byXID AS
(
SELECT ID, XID, RChange, ROW_NUMBER() OVER(PARTITION BY XID ORDER BY ID) rn
FROM Table1
)
SELECT t1.ID, t1.XID, t1.RChange
FROM byXID t1
INNER JOIN byXID t0 ON t1.XID = t0.XID AND t0.rn = t1.rn - 1
WHERE t1.RChange = 0 AND t0.RChange = 1
SQL Fiddle demo
This is another approach:
SELECT t2.ID, t2.XID, t2.RChange
FROM Table1 t1 JOIN Table1 t2
ON t1.XID = t2.XID
WHERE t1.RChange = 1 AND t2.RChange = 0
Sql fiddle demo (Thanks #Ic. for the fiddle)

Get Sum of Count

The View obtains the first three columns. I need to add one more column (totalCount) to the view that obtains the total count:
CId CCId CCount totalCount
1 a 3 6
1 a 3 6
1 b 3 6
1 c 3 6
2 b 2 6
2 b 2 6
2 a 2 6
2 a 2 6
3 v 1 6
How to get the totalCount as 6?
(Business rule for Cid=1 Ccount=3 Cid=2 Ccount=2 Cid=3 Ccount=1 So the totalCount =3+2+1 =6)
SELECT a.CID, a.CCID, a.CCOUNT,
b.TotalCount
FROM Table1 a, (SELECT SUM(DISTINCT cCOunt) TotalCount
FROM Table1) b
SQLFiddle Demo
UPDATE
As Andomar pointed out on the comment, An update has been made on the query,
SELECT a.CID, a.CCID, a.CCOUNT,
b.TotalCount
FROM Table1 a,
(
SELECT SUM(TotalCount) TotalCount
FROM
(
SELECT MAX(cCOunt) TotalCount
FROM Table1
GROUP BY CId
) c
) b
SQLFiddle Demo
With this code I came to the desired result:
select CId
,CCId
,CCount
,(select SUM(a.tcount)
from (select distinct CId ,CCount as tcount
from dbo.Test) as a ) totalcount
from dbo.Test
From your example data, I'm assuming a Cid can only have one, possibly repeated, value of CCount. In that case you can pick a random one (say max) using a group by, and sum those:
select sum(OneCCCount) as TotalCount
from (
select max(CCount) as OneCCCount
from YourTable
group by
CId
) as SubQueryAlias

How we can get two rows before and after for a given id in a table?

I have a table with 10 rows
id values
1 a
2 b
3 c
4 d
5 e
6 f
7 g
8 h
9 i
10 j
I want to get two rows before and two rows after for #id = 5.
How can get?
Edit This should work as expected (hopefully):
select id, value
from [table]
where id-#id >= -2
AND id-#id <= 2
AND id-#id <> 0
Here's the running sql: http://sqlfiddle.com/#!6/ca4e5/3/0
One possible solution:
select *
from table
where id in (3, 4, 6, 7)
If you are using a int variable #id, you can do it like this:
select *
from table
where id in (#id-2, #id-1, #id+1, #id+2)
To select the previous two:
select top 2 *
from tablename
where id < #id
order by id desc
To select the next two:
select top 2 *
from tablename
where id > #id
order by id asc

Resources