sql server select first row from a group - sql

I have table like this:
a b
1 23
1 2
1 7
2 9
2 11
I want to select the first row(order does not matter) from a "GROUP BY a" query , the result should be
a b
1 23
2 9
I am using SQL SERVER 2008 how to write the query for this?

select a,b
from (
select a,b,row_number() over(partition by a order by b desc) as roworder
from myTable
) temp
where roworder = 1
see http://msdn.microsoft.com/en-us/library/ms186734.aspx

If as you indicated, order doesn't matter, any aggregate function on b would be sufficient.
Example Using MIN
SELECT a, b = MIN(b)
FROM YourTable
GROUP BY
a

Related

SQL query to partition rows into groups where lag (difference between rows) is greater than some value

Suppose I have a table like
id
1
3
4
10
12
19
and I'd like to group the ids (in sorted order) into the same group if they differ by 5 or less, and a new group if they differ by 6 or more. So the output would be:
id
group
1
1
3
1
4
1
10
2
12
2
19
3
Is this possible in SQL? It will be a query in Trino, and I see they have commands like lag and partition. Has anyone made a query like this that can help out?
You can use a cte with lead:
with cte(id, l1) as (
select t.id, abs(coalesce(lead(t.id) over (order by t.id), 0) - t.id) < 6 from tbl t
)
select c.id, (select sum(c1.id < c.id and c1.l1 = 0) from cte c1) + 1 from cte c

Reorder the rows of a table according to the numbers of similar cells in a specific column using SQL

I have a table like this:
D
S
2
1
2
3
4
2
4
3
4
5
6
1
in which the code of symptoms(S) of three diseases(D) are shown. I want to rearrange this table (D-S) such that the diseases with more symptoms come up i.e. order it by decreasing the numbers of symptoms as below:
D
S
4
2
4
3
4
5
2
1
2
3
6
1
Can anyone help me to write a SQL code for it in SQL server?
I had tried to do this as the following but this doesn't work:
SELECT *
FROM (
select D, Count(S) cnt
from [D-S]
group by D
) Q
order by Q.cnt desc
select
D,
S
from
D-S
order by
count(*) over(partition by D) desc,
D,
S;
Two easy ways to approach this:
--==== Sample Data
DECLARE #t TABLE (D INT, S INT);
INSERT #t VALUES(2,1),(2,3),(4,2),(4,3),(4,5),(6,1);
--==== Using Window Function
SELECT t.D, t.S
FROM (SELECT t.*, Rnk = COUNT(*) OVER (PARTITION BY t.D) FROM #t AS t) AS t
ORDER BY t.Rnk DESC;
--==== Using standard GROUP BY
SELECT t.*
FROM #t AS t
JOIN
(
SELECT t2.D, Cnt = COUNT(*)
FROM #t AS t2
GROUP BY t2.D
) AS t2 ON t.D = t2.D
ORDER BY t2.Cnt DESC;
Results:
D S
----------- -----------
4 2
4 3
4 5
2 1
2 3
6 1

PSQL, adding a "step increasing" column

have this values in a table column select a from tab:
a
1
2
3
4
5
6
7
15
16
18
Using a variable=3, how can create column b starting with min(a) and with the following values:
a
b
1
1
2
1
3
1
4
4
5
4
6
4
7
7
15
15
17
15
18
18
something like: for each a (ordered) maintain the value at most for 3, otherwise reset.
Thanks,
AAWNSD
I think you want window functions and groups of three based on arithmetic on a:
select a,
min(a) over (partition by ceiling(a / 3.0)) as b
from tab;
Here is a db<>fiddle.
Hmmm . . . I realize that the above returns "16" for the last row rather than 18. My above interpretation may not be correct. You may be saying that you want groups -- once they start -- to never exceed the group starting value plus 2.
If so, one approach is a recursive CTE:
with recursive tt as (
select a, row_number() over (order by a) as seqnum
from tab
),
cte as (
select a, seqnum, a as grp
from tt
where seqnum = 1
union all
select tt.a, tt.seqnum,
(case when tt.a <= grp + 2 then grp else tt.a end)
from cte join
tt
on tt.seqnum = cte.seqnum + 1
)
select *
from cte;

Smarter GROUP BY

Consider Table like this.
I will call it Test
Id A B C D
1 1 1 8 25
2 1 2 5 35
3 1 3 2 75
4 2 2 2 45
5 3 2 5 26
Now I want rows with max 'Id' Grouped by 'A'
Id A B C D
3 1 3 2 75
4 2 2 2 45
5 3 2 5 26
-
--Work, but I do not want
SELECT MAX(Id), A FROM Test GROUP BY A
--I want but do not work
SELECT MAX(Id), A, B, C, D FROM Test GROUP BY A
--Work but I do not want
SELECT MAX(Id), A, B, C, D FROM Test GROUP BY A, B, C, D
--Work and I want
SELECT old.Id, old.A, new.B, new.C, new.D
FROM(
SELECT
MAX(Id) AS Id, A
FROM
Test GROUP BY A
)old
JOIN Test new
ON old.Id = new.Id
Is there a better way to write last query without join
Most databases support window functions:
select *
from (
select *, row_number() over (partition by a order by id desc) rn
from test
) t
where rn = 1
Most DBMS now support Common Table Expressions (CTE). You can use one.
;with maxa as (
select row_number() over(partition by a order by id desc) rn,
id,a,b,c,d from test
)
select id,a,b,c,d
from maxa
where rn=1

Transact SQL - How to perform additional operation on a result set

I have a simple query:
select id, count(*) n
from mytable
group by id
Is it possible to include also the sum(n) in the same query? So the result would look something like this:
id n
---- -----------
1 12
2 1
3 14
4 1
5 2
6 6
Sum=36
You can use a common table expression to do this:
--
; WITH cte as (SELECT id
,count(*) n
FROM mytable
GROUP BY id)
SELECT id, n FROM cte
UNION ALL
SELECT 'Sum', SUM(n) from cte
You can also use ROLLUP: (this may not be exactly correct syntax)
SELECT id
,count(*) n
FROM mytable
GROUP BY id
WITH ROLLUP