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 

これは以下を返します。

ここに画像の説明を入力

の 3 つの s がすべて存在する場合にのみ、このクエリで行が返されるようにします。したがって、目的の結果セットには3 が含まれません。cardidhandidhandid

これは現実のモデルです。実際には、#x には 500 のミル レコードが含まれています。

編集

わかりました-実際には、可変数のレコードを持つデータセットで構成される勝者がいます。したがって、元のコードを次のように修正すると、結果セットに1 または3#winnersが含まれてはなりません。また、結果セットに不要な重複レコードがいくつか含まれています。handIdhandId

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 
4

4 に答える 4

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 を参照してください

結果:

| 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 を参照してください

結果:

| HANDID |
----------
|      2 |
|      4 |
于 2012-11-14T11:52:04.810 に答える
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 フィドルのデモ

于 2012-11-14T11:57:18.820 に答える
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
于 2012-11-14T11:49:22.753 に答える
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)

データ構造、インデックス、勝者の数などによっては、膨大な数のレコードに対してパフォーマンスが向上する可能性があるため、ドレッドカーソルソリューションも検討します。

しかし、完全なデータセットがなければ、何とも言えません。

于 2012-11-14T12:00:34.210 に答える