2012-11-14 76 views
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 

这将返回以下:

enter image description here

我只希望这个查询时所有三个cardid S的存在一个handid返回行。所以期望的结果集不包括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 
+0

看起来像错误的桌子设计。可能是'handid,card1id,card2id,card3id'会更适合这个需求。 – Oded

+1

这是关系部门的名称。 500米记录你有什么指标?每只手平均有多少只cardids?表中共有多少种不同的cardids?你通常会尝试匹配多少个?根据这个问题的答案,你可能会更好地做重复连接而不是一组。 –

+0

看起来像我最好**编辑** OP! – whytheq

回答

6

您可以使用这样的事情:

select handid 
from #x 
where cardid in (select cardid from #winners) 
group by handid 
having count(handid) = (select count(distinct cardid) 
         from #winners); 

SQL Fiddle with Demo

结果:

| 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 

SQL Fiddle with Demo

结果:

| HANDID | 
---------- 
|  2 | 
|  4 | 
+0

+1这会产生正确的答案而不硬编码预期答案的数量 - 从这里完成问题的微不足道 – amelvin

+0

在人们已经改变了问题之后的道歉一直在寻找答案,但我在OP – whytheq

+0

@whytheq中增加了额外的复杂性,你怎么知道获胜组合是什么?他们是否必须拥有每组中的所有价值? – Taryn

1

您可以将查询更改为

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 
+1

为什么你认为cardids的数量总是3? –

+0

@TimSchmelter - 我的错Tim在编辑之前的OP不是很清楚 – whytheq

3

试试这个:

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) 


SQL fiddle demo

1

@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) 

我也会考虑的恐惧光标的解决方案 - 因为它可以在更好的表现大量的记录取决于数据结构,索引,获奖者数量等等。

但没有完整的数据集我真的不能说。

相关问题