我想编写一个有条件的几列的SQL查询。桌子看起来像这样:
ID Company User
1 Bov LPF
2 Ak LPF
3 Bov LPF
4 Bov ABC
5 Ak ABC
6 ZP ABC
7 REP ABC
8 REP CDE
9 KEK CDE
10 Ak CDE
11 PER CDE
12 Bov BKE
结果必须如下:
例如预期结果:
ID Company User
1 Bov LPF
2 Ak LPF
3 Bov LPF
4 Bov ABC
5 Ak ABC
7 REP ABC
8 REP CDE
10 Ak CDE
11 PER CDE
我应该如何编写查询?
更新:
我正在考虑这样的查询,但这并不能给我正确的结果:
select *
from
(
select *,row_number() over(partition by user,company order by user, company) as row, ROW_NUMBER() over(order by newid()) as total
from
(
select *
from
(
select *, 0 as Bov, sum(iif(Company= 'Ak',1,0)) over (order by newid()) as Ak
FROM table a
where Company = 'Ak'
) as eu
where eu.Ak <= 2
UNION ALL
select *
from
(
select *, sum(iif(company = 'Bov',1,0)) over (order by newid() ) as Bov, 0 as Ak
FROM table a
where Company = 'Bov'
) as nn
where nn.Bov <= 2
UNION ALL
select *, 0 as Bov, 0 as Ak
FROM table a
where Company not in ('Bov','Ak')
) as z
) as z1
where z1.row <= 3
and z1.total <= 9
过滤器<= 2
用于必须返回至少两次结果的公司
过滤器row <= 3
用于每个用户的三行。
过滤器total <= 9
用于必须为9的总行。
对于此查询,我不确定我是否至少有两行适用于Bov,Ak和REP公司。
答案 0 :(得分:0)
select *
from table
group by id
having count(User) <= 3
order by id
这是您需要的吗?
答案 1 :(得分:0)
您可以使用它。
DECLARE @MyTable TABLE (ID INT, Company VARCHAR(10), [User] VARCHAR(10))
INSERT INTO @MyTable VALUES
(1 , 'Bov', 'LPF'),
(2 , 'Ak ', 'LPF'),
(3 , 'Bov', 'LPF'),
(4 , 'Bov', 'ABC'),
(5 , 'Ak ', 'ABC'),
(6 , 'ZP ', 'ABC'),
(7 , 'REP', 'ABC'),
(8 , 'REP', 'CDE'),
(9 , 'KEK', 'CDE'),
(10 , 'Ak ', 'CDE'),
(11 , 'PER', 'CDE'),
(12 , 'Bov', 'BKE')
SELECT ID, Company, [User] FROM
( SELECT *
, ROW_NUMBER() OVER (PARTITION BY [User] ORDER BY (CASE WHEN Company IN ('Bov','REP','Ak') THEN 0 ELSE 1 END) ) RN
, COUNT(*) OVER (PARTITION BY [User]) CmpCnt
, COUNT(CASE WHEN Company IN ('Bov','REP','Ak') THEN 1 END) OVER (PARTITION BY [User]) PriCmpCnt
FROM @MyTable
) T
WHERE
T.CmpCnt > 2
and T.PriCmpCnt > 1
and T.RN < 4
order by ID
结果:
ID Company User
----------- ---------- ----------
1 Bov LPF
2 Ak LPF
3 Bov LPF
4 Bov ABC
5 Ak ABC
7 REP ABC
8 REP CDE
10 Ak CDE
11 PER CDE
答案 2 :(得分:0)
这就是我的处理方式;查看注释以获取解释/让我知道您是否需要更多信息以了解任何内容...
;with cte as
(
select Id
, Company
, [User]
, Row_Number() over (partition by [User] order by randomOrder) PerUserRowNum
, case
when Company in ('BOV','REP', 'AK') then
case
when Row_Number() over (partition by Company order by randomOrder) <= 2 then 1
else 0
end
else 0
end MustInclude
from (select *, newid() randomOrder from SourceData) x
)
select top 9 --total rows is 9
Id, Company, [User]
from cte
where PerUserRowNum <= 3 --show 3 rows per user
and [User] in ( --only the users with at least three rows will be in the result
select [User]
from cte
where PerUserRowNum = 3
)
order by MustInclude desc, newid() --ensure all the stuff we must include is returned, then make up the rest of the results with whatever