Sql 仅在所有为真时返回行
我想这比我想象的要容易。 获得以下表格:Sql 仅在所有为真时返回行,sql,sql-server,sql-server-2008,tsql,sql-server-2008-r2,Sql,Sql Server,Sql Server 2008,Tsql,Sql Server 2008 R2,我想这比我想象的要容易。 获得以下表格: create table #x ( handid int, cardid int ) insert into #x values (1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8), (2,2),(2,3),(2,4),(2,300),(2,400),(2,500),(2,8), (3,2),(3,3),(3,4),(3,300),(3,400),(3,7),(3,8), (4,2),(4,300),(4,400),(4,
create table #x
(
handid int,
cardid int
)
insert into #x
values
(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),
(2,2),(2,3),(2,4),(2,300),(2,400),(2,500),(2,8),
(3,2),(3,3),(3,4),(3,300),(3,400),(3,7),(3,8),
(4,2),(4,300),(4,400),(4,500),(4,6),(4,7),(4,8)
create table #winners(cardid int)
insert into #winners values(300),(400),(500)
select a.*
from
#x a
inner join #winners b
on
a.cardid = b.cardid
这将返回以下内容:
我只希望当handid
的三个cardid
s都存在时,此查询返回行。因此,期望的结果集将不包括handid
3
这是现实的典范。
实际上#x包含500个工厂记录
编辑
好的-实际上,有些获奖者是由来自#winners
的数据集组成的,这些数据集的记录数是可变的。因此,将原始代码修改为以下结果集不应包括handId
1或handId
3。我还在结果集中得到一些不需要的重复记录:
create table #x
(
handid int,
cardid int
)
insert into #x
values
(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8000),
(2,2),(2,3),(2,4),(2,300),(2,400),(2,500),(2,8),
(3,2),(3,3),(3,4),(3,300),(3,400),(3,7),(3,8),
(4,2),(4,300),(4,400),(4,500),(4,6),(4,7),(4,8)
create table #winners(winningComb char(1), cardid int)
insert into #winners values('A',300),('A',400),('A',500),('B',8000),('B',400)
select a.*
from
#x a
inner join #winners b
on
a.cardid = b.cardid
您可以将查询更改为
select a.*, count(a.*) as a_count
from
#x a
inner join #winners b
on
a.cardid = b.cardid
group by a.handid
having a_count = 3
您可以使用以下内容:
select handid
from #x
where cardid in (select cardid from #winners)
group by handid
having count(handid) = (select count(distinct cardid)
from #winners);
看
结果:
| HANDID |
----------
| 2 |
| 4 |
| HANDID |
----------
| 2 |
| 4 |
根据您的编辑,以下是返回正确结果的尝试,但我不确定它是否适用于您拥有的较大数据集:
;with cte as
(
select w1.cardid, w1.winningComb, w2.ComboCardCount
from winners w1
inner join
(
select COUNT(*) ComboCardCount, winningComb
from winners
group by winningComb
) w2
on w1.winningComb = w2.winningComb
)
select a.handid
from x a
inner join cte b
on a.cardid = b.cardid
where a.cardid in (select cardid from cte)
group by handid, b.ComboCardCount
having COUNT(a.handid) = b.ComboCardCount
看
结果:
| HANDID |
----------
| 2 |
| 4 |
| HANDID |
----------
| 2 |
| 4 |
试试这个:
with cte as
(select a.*
from
#x a
inner join #winners b
on
a.cardid = b.cardid ),
cte1 as
(select *,ROW_NUMBER() over(partition by handid order by cardid) as row_num
from cte),
cte2 as
(select handid from cte1 where row_num=(select COUNT(*) from #winners) )
select * from cte where handid in (select handid from cte2)
@Bluefleets(+1)方法在数据集性能方面看起来不错;我想有了5亿条记录,性能状况将会改变 我认为OP希望输出的格式稍有不同,对@Bluefleet的代码稍加修改即可产生:
select * from #x where handid in (
select handid
from #x
where cardid in (select cardid from #winners)
group by handid
having count(handid) = (select count(distinct cardid)
from #winners)
)
and cardid in (select cardid from #winners)
我也会考虑可怕的光标解决方案,因为它可以在数据结构、索引、优胜者数量等方面对大量的记录执行得更好。
但是如果没有完整的数据集,我真的不能说。看起来是错误的表设计。可能一个
handid、card1id、card2id、card3id
更适合这个需求。它的名称是关系划分。对于500米记录,您有哪些索引?平均每手有多少件羊毛衫?表中总共有多少种不同的羊毛衫?您通常会尝试匹配多少个?根据这个问题的答案,你可能会比分组人做重复连接更好。看起来我最好编辑操作@马丁史密斯:每手7件羊毛衫。桌子上有52件不同的羊毛衫。#winners
表格将有400万或500万个不同的winningComb
为什么你认为梳子的数量总是3个?@TimSchmelter-我的错Tim因为编辑前的OP不是很清楚+1这在不硬编码预期答案数量的情况下产生了正确的答案-从这里完成问题很简单道歉在人们已经研究了答案之后,我改变了这个问题,但我把额外的复杂性添加到了OP@whytheq你怎么知道赢的组合是什么?他们必须在每个集合中都有所有值吗?#winners
中指定的任何值都是一个成功的组合。。。具体来说,“winningComb A”可能是钻石中的王牌花色,而“winningComb B”可能是两对(钻石和黑桃);那么,有多少种方法可以赢得扑克抽签@whytheq-您需要为每只手添加分数(在handid
所指的任何表格中)。然后你就可以按分数排序,选出前1名。网上有大量关于如何分配扑克手的排名分数的信息。