回答:
サブクエリから派生テーブルを作成し、table1をこの派生テーブルに結合できます。
select * from table1 LEFT JOIN
(
Select CM_PLAN_ID, Individual_ID
From CRM_VCM_CURRENT_LEAD_STATUS
Where Lead_Key = :_Lead_Key
) table2
ON
table1.CM_PLAN_ID=table2.CM_PLAN_ID
AND table1.Individual=table2.Individual
WHERE table2.CM_PLAN_ID IS NOT NULL
代わりにWHERE EXISTS構文を使用する必要があります。
SELECT *
FROM table1
WHERE EXISTS (SELECT *
FROM table2
WHERE Lead_Key = @Lead_Key
AND table1.CM_PLAN_ID = table2.CM_PLAN_ID
AND table1.Individual_ID = table2.Individual_ID)
あなたがテーブルを作成する唯一の人である場合、これは関係がないかもしれませんが、テーブルの1つが一意の行を含まない可能性がある場合、いくつかの解決策は問題のコードから異なる数の出力行を与えます。
2つの列のあるインを見ると、2つの意味があると想像できます。
シナリオ1はかなり簡単で、2つのINステートメントを使用するだけです。
ほとんどの既存の回答に沿って、シナリオ2の前述のアプローチと追加のアプローチの概要(および簡単な判断)をここに示します。
@mrdennyによって提供されているように、EXISTSはあなたが探しているものとまったく同じように聞こえます。これが彼の例です。
SELECT * FROM T1
WHERE EXISTS
(SELECT * FROM T2
WHERE T1.a=T2.a and T1.b=T2.b)
これは非常に簡潔に参加する方法ですが、残念ながらSQLサーバーを含むほとんどのSQL方言は現在サポートしていません。
SELECT * FROM T1
LEFT SEMI JOIN T2 ON T1.a=T2.a and T1.b=T2.b
@cataclysmで言及されているように、2つのINステートメントを使用することでも同じことができますが、おそらく他のソリューションよりも優れているでしょう。ただし、注意が必要なのはコードの重複です。別のテーブルから選択したり、whereステートメントを変更したりする場合、ロジックに不整合が生じるリスクが高まります。
基本的な解決策
SELECT * from T1
WHERE a IN (SELECT a FROM T2 WHERE something)
AND b IN (SELECT b FROM T2 WHERE something)
コードの重複のないソリューション(これは通常のSQL Serverクエリでは機能しないと思います)
WITH mytmp AS (SELECT a, b FROM T2 WHERE something);
SELECT * from T1
WHERE a IN (SELECT a FROM mytmp)
AND b IN (SELECT b FROM mytmp)
内部結合をフィルターとして使用することをお勧めしないのは、実際には右側のテーブルで重複を許可すると、左側のテーブルで重複が発生することが多いためです。そしてさらに悪いことに、左のテーブルが実際に一意である必要がない(または選択した列で一意である必要がない)場合でも、最終結果が明確になることがあります。さらに、左側のテーブルに存在しない列を実際に選択する機会が与えられます。
SELECT T1.* FROM T1
INNER JOIN
(SELECT DISTINCT a, b FROM T2) AS T2sub
ON T1.a=T2sub.a AND T1.b=T2sub.b
最も一般的な間違い:
機能的な問題は、列で発生する可能性のあるセパレータを使用する場合、結果が100%正確であることを確認するのが難しいことです。技術的な問題は、この方法では型変換が頻繁に発生し、インデックスが完全に無視されるため、パフォーマンスが恐ろしいものになる可能性があることです。これらの問題にもかかわらず、私はまだそれを小さなデータセットのアドホッククエリにまだ使用していることを認めなければなりません。
SELECT * FROM T1
WHERE CONCAT(a,"_",b) IN
(SELECT CONCAT(a,"_",b) FROM T2)
列が数値の場合、一部のSQL方言では、最初に列を文字列にキャストする必要があります。SQLサーバーがこれを自動的に行うと思います。
まとめ:SQLでこれを行うには多くの方法があります。安全な選択を使用すると、驚きを避け、長期的に見て時間と頭痛の種を節約できます。
select * from tab1 where (col1,col2) in (select col1,col2 from tab2)
注:
Oracleは、選択された1つ以上の列がNULLである行を無視します。これらの場合、NVL -Funktionを使用してNULLを特別な値(値に含めてはならない)にマップすることをお勧めします。
select * from tab1
where (col1, NVL(col2, '---') in (select col1, NVL(col2, '---') from tab2)
where (colA,colB) in (... some list of tuples...)いますが、他のデータベースが同じことをするかどうかはわかりません。知りたいです。
単純なEXISTS句が最もクリーンです
select *
from table1 t1
WHERE
EXISTS
(
Select * --or 1. No difference...
From CRM_VCM_CURRENT_LEAD_STATUS Ex
Where Lead_Key = :_Lead_Key
-- correlation here...
AND
t1.CM_PLAN_ID = Ex.CM_PLAN_ID AND t1.CM_PLAN_ID = Ex.Individual_ID
)
相関関係に複数の行がある場合、JOINは出力に複数の行を与えるため、区別する必要があります。これにより、通常、EXISTSがより効率的になります。
SELECT *JOINを使用すると、行制限テーブルの列も含まれることに注意してください。
通常の内部結合を実行できるだけなのに、WHERE EXISTSまたはDERIVED TABLESを使用する理由:
SELECT t.*
FROM table1 t
INNER JOIN CRM_VCM_CURRENT_LEAD_STATUS s
ON t.CM_PLAN_ID = s.CM_PLAN_ID
AND t.Individual_ID = s.Individual_ID
WHERE s.Lead_Key = :_Lead_Key
(CM_PLAN_ID、Individual_ID)のペアがステータステーブルで一意でない場合は、代わりにSELECT DISTINCT t。*が必要になることがあります。
Postgres SQL : version 9.6
Total records on tables : mjr_agent = 145, mjr_transaction_item = 91800
1. EXISTS[平均クエリ時間:1.42秒]での使用
SELECT count(txi.id)
FROM
mjr_transaction_item txi
WHERE
EXISTS ( SELECT 1 FROM mjr_agent agnt WHERE agnt.agent_group = 0 AND (txi.src_id = agnt.code OR txi.dest_id = agnt.code) )
2. 2行IN句での使用[平均クエリ時間:0.37秒]
SELECT count(txi.id) FROM mjr_transaction_item txi
WHERE
txi.src_id IN ( SELECT agnt.code FROM mjr_agent agnt WHERE agnt.agent_group = 0 )
OR txi.dest_id IN ( SELECT agnt.code FROM mjr_agent agnt WHERE agnt.agent_group = 0 )
3. INNNER JOINパターンでの使用[平均クエリ時間:2.9秒]
SELECT count(DISTINCT(txi.id)) FROM mjr_transaction_item txi
INNER JOIN mjr_agent agnt ON agnt.code = txi.src_id OR agnt.code = txi.dest_id
WHERE
agnt.agent_group = 0
だから、私は2番目のオプションを選びました。
ANDステートメントではなくステートメントを使用したいと思うでしょうOR。
ORステートメントはおそらく重複を引き起こします。私の場合は、同じ含まれている任意の行が存在していないsrc_idとdest_id一列には。したがって、私の場合、重複は発生しません。
クエリ:
select ord_num, agent_code, ord_date, ord_amount
from orders
where (agent_code, ord_amount) IN
(SELECT agent_code, MIN(ord_amount)
FROM orders
GROUP BY agent_code);
上記のクエリはmysqlで機能しました。次のリンクを参照してください->
https://www.w3resource.com/sql/subqueries/multiplee-row-column-subqueries.php
1つのテーブルが必要な場合は、次のクエリを使用します
SELECT S.*
FROM Student_info S
INNER JOIN Student_info UT
ON S.id = UT.id
AND S.studentName = UT.studentName
where S.id in (1,2) and S.studentName in ('a','b')
そして次の通りテーブルデータ
id|name|adde|city
1 a ad ca
2 b bd bd
3 a ad ad
4 b bd bd
5 c cd cd
その後、次のように出力します
id|name|adde|city
1 a ad ca
2 b bd bd
id in (1,2) and studentName in ('a','b')とは完全に同じではありません(id, studentName) in ((1,'a'),(2,'b'))。id = 2とname = 'a'を持つレコードを考えてください。もちろん、IDが一意の場合、効果は減少しますが、IDが一意の場合、名前をフィルタリングする必要はまったくありません。
いくつかの形式で列を連結することは「ハック」ですが、製品が複数の列の準結合をサポートしていない場合は、選択できない場合があります。
内部/外部結合ソリューションが機能しない例:
select * from T1
where <boolean expression>
and (<boolean expression> OR (ColA, ColB) in (select A, B ...))
and <boolean expression>
...
クエリが本質的に簡単でない場合、通常の内部/外部結合を実行するためにベーステーブルセットにアクセスできないことがあります。
この「ハック」を使用する場合は、フィールドを組み合わせるときに、フィールドの間に十分な区切り文字を追加して、誤解を避けるようにしてください。たとえば、 ColA + ":-:" + ColB
私はこのように簡単に創設しました
Select *
from table1
WHERE (convert(VARCHAR,CM_PLAN_ID) + convert(VARCHAR,Individual_ID))
IN
(
Select convert(VARCHAR,CM_PLAN_ID) + convert(VARCHAR,Individual_ID)
From CRM_VCM_CURRENT_LEAD_STATUS
Where Lead_Key = :_Lead_Key
)
この助けを願っています:)
CM_PLAN_ID = 45およびIndividual_ID = 3その後、連結業績で453-場合と区別がつかないCM_PLAN_ID = 4とIndividual_ID = 53...私は思ってもみなかったトラブルを求めて
45_3orを任意の特殊文字と連結することもできますが、45:3それでも良い解決策ではありません。もちろん、@ mrdennyが言うように、列で変換が行われたため、インデックスは使用されません。