2017-12-11 12 views
-1

3つのテーブルの結合を持つクエリがあります。 3番目の表の列の1つにブール値があります。 。表2と表3はproduct_idで接続され、表3の各product_idは真値と偽値を受信値として関連付けることができます。私はテーブル3の受信値が真の値しか持たない製品に関連付けられているテーブル1のすべてのレコードを返すクエリが必要です。サンプルデータで 私は、私はそれがNOT INを使用して動作させるが、それは(現在は約2000レコードです)私のデータセットと非常に遅い実験午後後GHIすべての行が一致するレコードのみを返すSQL結合

Table 1 - Sale 
ID sale# 
1 ABC 
2 DEF 
3 GHI 

Table 2 PO  Table 1 join Table 2 on Table1.ID = Table 2.SaleID 
ID SaleID 
1 1 
2 1 
3 2 
4 3 
5 3 

Table 3 
ID POID Received Table 2 right join table 3 on Table 2.ID = Table 3.POID 
1 1  True 
2 1  False 
3 2  True 
4 3  False 
5 4  True 
6 5  True 
7 5  True 

を返すようにしたいの下に私はそれがおそらく結合を再作成する必要があるためだと思います。これを達成するためのよりエレガントな方法があるように思えます。

SELECT Distinct Table1.id, Table3.received 
FROM Table3 INNER JOIN (Table2 INNER JOIN Table1 ON Table2.saleID = Table1.id) 
    ON Table3.POID = Table2.id 
WHERE ((Table3.received)=True) and Table1.id NOT IN (
    SELECT Table1.id 
    FROM Table3 INNER JOIN (Table2 INNER JOIN Table1 ON Table2.saleID = Table1.id) 
    ON Table3.POID = Table2.id 
    WHERE ((Table3.received)=False)); 
+2

サンプルデータとコードの一部を提供できる場合は非常に役に立ちます。すなわち、スクリーンショット、コードスニペット、現在のリターンなど。 – StelioK

+0

'私は3テーブルジョインでクエリを持っています.'あなたが作業しているクエリを投稿してください。 –

+0

これまで何を試しましたか?質問する方法を学びます。 https://stackoverflow.com/help/how-to-ask – Eric

答えて

0

私はあなたが

 
select 
    Table1.* 
from 
    Table1 join Table2 on Table1.id = Table2.saleid 
    join table3 on table3.POID = Table2.ID 
where 
    table3.received = true 
+0

残念ながら、これはreceived = trueを持つ値を返します。私は、関連するすべてのテーブル3.received = trueの値だけが必要です。 –

0

まず、唯一の製品は、表3における真の値エントリを持つテーブル3から選択しなければならない必要がある、これはクエリであると信じて、これはPOIDに自己によってジョインを行うことができます。その結果は表2とTABLE1と結合することができ

select 
    Table1.* 
from 
Table1 join Table2 
    on Table1.id = Table2.saleid 
join 
    (select t3.poid 
    from 
    Table3 t3 join Table3 t4 
     on t.POID = Table4.POID) 
    where t3.received = true and t4.received = true) all_true 
on all_true.POID = Table2.ID 
+0

@ D.swatsあなたの問題を解決しましたか? – sia

+0

私は何か間違っているかもしれませんが、テーブル3に参加したテーブル3は、少なくとも1つの真を持っているが、任意の数の偽を持つPOを返します。私はすべてが本当であるところだけを必要とする –

0

あなたが特定のsale#のレコードのcount別名received = Trueの値を持つレコードのcountに等しいことを確認してくださいすることだけですcount-if(明示的にSQLに存在しない) SQLでcount-ifを達成する方法は、...sum(case ... when ... then 1 else 0 end)...です。

サンプルデータセットアップ:

create table dbo.Sale 
    (
     ID int 
     , sale# char(3) 
    ) 

create table dbo.PO 
    (
     ID int 
     , SaleID int 
    ) 

create table dbo.Received 
    (
     ID int 
     , POID int 
     , Received char(5) 
    ) 

insert into dbo.Sale 
values (1, 'ABC'), (2, 'DEF'), (3, 'GHI') 

insert into dbo.PO 
values (1,1), (2,1), (3,2), (4,3), (5,3) 

insert into dbo.Received 
values (1, 1, 'True') 
    , (2, 1, 'False') 
    , (3, 2, 'True') 
    , (4, 3, 'False') 
    , (5, 4, 'True') 
    , (6, 5, 'True') 
    , (7, 5, 'True') 

回答:

; with base as 
    (
     select s.sale# 
     , p.SaleID 
     , r.POID 
     , r.Received 
     from dbo.Sale as s 
     inner join dbo.PO as p on s.ID = p.SaleID 
     inner join dbo.Received as r on p.ID = r.POID 
    ) 
    , all_true as 
    (
     --this sub-query is the filter for Sale#'s of interest 
     select b.sale# 
     from base as b 
     group by b.sale# 
     having sum(case b.Received when 'True' then 1 else 0 end) = count(*) --count-if = count 
    ) 
select b.* 
from base as b 
inner join all_true as t on b.sale# = t.sale# 

出力:

+-------+--------+------+----------+ 
| sale# | SaleID | POID | Received | 
+-------+--------+------+----------+ 
| GHI |  3 | 4 | True  | 
| GHI |  3 | 5 | True  | 
| GHI |  3 | 5 | True  | 
+-------+--------+------+----------+ 
0

ありがとうtarheel あなたは私をトラックに入れます。 True/falseを少し作成し、Sum(受信)=カウント(受信)を追加しました。

SELECT DISTINCT Table1.id 
FROM Table3 INNER JOIN (Table2 INNER JOIN Table1 ON Table2.saleID = Table1.id) ON Table3.POID = Table2.id 
GROUP BY Table1.id 
HAVING (-1*(Sum(Table3.received))=Count([Table3].[received])); 
関連する問題