web-dev-qa-db-ja.com

同じ1つの列の値に基づいて行を選択しますか?

データベーステーブルの例

film id | scene id | value id
-----------------------------
   0    |     0    |     7
   0    |     1    |     1
   0    |     1    |     0
   1    |     2    |     8
   1    |     2    |     3
   1    |     3    |     1
   2    |     4    |     3
   2    |     4    |     7
   2    |     5    |     2

値idが8または3である行を選択したいのは、両方が同じシーンIDの行にある場合のみです。

私の望ましい結果は:

film id | scene id | value id
-----------------------------
   1    |     2    |     8
   1    |     2    |     3

シーンIDの数でグループ化してみましたが、次のように出力されます。

film id | scene id | value id
-----------------------------
   1    |     2    |     8
   1    |     2    |     3
   2    |     4    |     3

シーンIDの値が複数あるため、最後の行が含まれています。

2
Chris

特定の列が同じであることに基づいて値を選択するには、 [〜#〜] ntile [〜#〜] を見ることができます

順序付けされたパーティションの行を指定された数のグループに分散します。グループには、1から始まる番号が付けられています。各行について、NTILEは行が属するグループの番号を返します。

実際には common_table_expression を含む多くのオプションがあります

あなたの例では:

--==================================================================================
use tempdb
if object_id('tempdb..radhe','U') is not null
   drop table radhe

create table  radhe(
 [Film Id] int not null
,[Scene Id] int not null
,[Value Id]int not null
)


insert into radhe ([Film Id],[Scene Id],[Value Id])
select 
   0    ,     0    ,     7
union all select 
   0    ,     1    ,     1
union all select 
   0    ,     1    ,     0
union all select 
   1    ,     2    ,     8
union all select 
   1    ,     2    ,     3
union all select 
   1    ,     3    ,     1
union all select 
   2    ,     4    ,     3
union all select 
   2    ,     4    ,     7
union all select 
   2    ,     5    ,     2



--I want to select rows 
--where the value id is equal to 8 or 3 
--only if they are both in a row with the same scene id.


--using a cte
;with t8 as (

        SELECT r.[Film Id], r.[Scene Id], r.[Value Id]
        FROM radhe r
        WHERE r.[Value Id]IN (8) 
) ,
t3 as (


        SELECT r.[Film Id], r.[Scene Id], r.[Value Id]
        FROM radhe r
        WHERE r.[Value Id]IN (3) 
)

select t8.* 
from t8
inner join t3
        on t8.[Scene Id] = t3.[Scene Id]
union all
select t3.* 
from t8
inner join t3
        on t8.[Scene Id] = t3.[Scene Id]

--====================================================================

--using NTILE
select r.[Film Id], r.[Scene Id], r.[Value Id]
from
(
SELECT 
    NTILE(2) OVER (ORDER BY [Scene Id]) [NTILE],
    *
FROM Radhe
WHERE [Value Id]IN (3,8) 
) r
where r.NTILE = 1

enter image description here

結果は同じですが、パフォーマンスはどうですか?

enter image description here

this および this を確認してください。

1

現在のサンプルデータの要件は明確です。ただし、非常に多くのシナリオが考えられます。

別のアプローチ、同じサンプルデータ

use tempdb
if object_id('tempdb..radhe','U') is not null
   drop table radhe

create table  radhe(
 [Film Id] int not null
,[Scene Id] int not null
,[Value Id]int not null
)


insert into radhe ([Film Id],[Scene Id],[Value Id])
select 
   0    ,     0    ,     7
union all select 
   0    ,     1    ,     1
union all select 
   0    ,     1    ,     0
union all select 
   1    ,     2    ,     8
union all select 
   1    ,     2    ,     3
union all select 
   1    ,     3    ,     1
union all select 
   2    ,     4    ,     3
union all select 
   2    ,     4    ,     7
union all select 
   2    ,     5    ,     2

別の一時テーブルまたはテーブル変数を作成します。このテーブルでpre insert the desire condition

declare @t table([Scene Id] int not null,[Value Id]int not null)
insert into @t values(2,8),(2,3)

最終クエリ

select r.*
   from radhe r inner join @t t on 
    r.[Scene Id] = t.[Scene Id] and r.[Value Id] = t.[Value Id]

だから私があなたに言ったように、正確な要件と異なるシナリオを知っていれば、それに応じてテーブルを事前に入力します。

正確な要件によっては、制限があります。

0
KumarHarsh