How to select k distinct value by a field? - database

How to select all infos from k distinct value of field X?
I have an idea to group by by some field X and then select like this
Table
id name
1 x
2 y
3 x
4 y
5 z
6 w
Group by name:
id name
1 x
3 x
2 y
4 y
5 z
6 w
Select k=3 distinct value of name:
id name
1 x
3 x
2 y
4 y
5 z
Any idea how to write this query?

Try this -
WITH CTE AS (SELECT DISTINCT name
FROM TAB
LIMIT 3)
SELECT * FROM TAB
WHERE NAME IN (SELECT name FROM CTE)
ORDER BY name;

select id, name
from (
select id, name, dense_rank() over (order by name) as ds
from t
) s
where ds <= 3

Related

Select all Id's with column containing all values

What is the select query to achieve the following :
Id
Value
1
A
1
B
2
A
2
C
3
A
3
B
3
C
Expected result : 3
Select All Id's having A and B and C as Value
You could aggregate and count the distinct values:
select Id
from t
where value in ('A','B','C')
group by id
having Count(distinct value) = 3;

Find records with Minimum length data

I have a table #tempTest with data like this:
ID Name
1 A
2 AB
3 ABC
4 ABCD
5 ABCDE
6 ABCDEF
7 X
8 QRWXYZ
Now I need the shortest name from the table.
I've tried this way:
SELECT TOP 1(name) Smallest FROM #tempTest
GROUP BY name
ORDER BY LEN(name)
And that represents:
Smallest
A
But what I need is:
ID Name
1 A
7 X
SELECT TOP 1 WITH TIES (name) Smallest FROM #tempTest
GROUP BY name
ORDER BY LEN(name)
SELECT id, name FROM #tempTest
WHERE LEN(name) = (SELECT MIN(LEN(name)) FROM #tempTest)

SQL Server view for calc ParentId column

I have a table with following sampled rows:
Id CompanyId value
1 X a
2 X b
3 X c
4 X d
5 Y e
6 Y f
7 z g
8 Z h
9 X i
10 X j
I want to have a view with following result :
Id CompanyId ParentId
1 X NULL
2 X NULL
3 X NULL
4 X NULL
5 Y 1
6 Y 1
7 z 5
8 Z 5
9 X 7
10 X 7
On this result calculated ParentId for each row. ParentId for each row equal to Id of first row from previous companyId.
I hope that SQL Server 2012 tag is here for reason :)
;with x as (
select *, lag(companyid) over(order by id) as prev
from #t1
),
y as (
select *, sum(case when prev = companyid then 0 else 1 end) over(order by id) as grp
from x
)
select y.id, y.companyid, min(y1.id)
from y
left join y y1 on y1.grp = y.grp-1
group by y.id, y.companyid

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