我需要在SQL Server中实现以下查询:
select *
from table1
WHERE (CM_PLAN_ID,Individual_ID)
IN
(
Select CM_PLAN_ID, Individual_ID
From CRM_VCM_CURRENT_LEAD_STATUS
Where Lead_Key = :_Lead_Key
)
但是WHERE..IN子句只允许1列。我如何比较2个或更多的列与另一个内部选择?
我需要在SQL Server中实现以下查询:
select *
from table1
WHERE (CM_PLAN_ID,Individual_ID)
IN
(
Select CM_PLAN_ID, Individual_ID
From CRM_VCM_CURRENT_LEAD_STATUS
Where Lead_Key = :_Lead_Key
)
但是WHERE..IN子句只允许1列。我如何比较2个或更多的列与另一个内部选择?
当前回答
简单的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会在输出中给出多行,因此需要distinct。这通常使EXISTS更有效。
注意带有JOIN的SELECT *还包括行限制表中的列
其他回答
为什么使用WHERE EXISTS或DERIVED表,当你可以只做一个普通的内部连接:
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.*。
简单的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会在输出中给出多行,因此需要distinct。这通常使EXISTS更有效。
注意带有JOIN的SELECT *还包括行限制表中的列
Postgres SQL : version 9.6
Total records on tables : mjr_agent = 145, mjr_transaction_item = 91800
1.使用EXISTS[平均查询时间:1.42s]
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.使用两行IN子句[平均查询时间:0.37s]
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.使用inner JOIN模式[平均查询时间:2.9s]
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
所以,我选择了第二种选择。
以某种形式将列连接在一起是一种“hack”,但是当产品不支持多个列的半连接时,有时您别无选择。
内部/外部连接解决方案不工作的例子:
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
)
希望这对你有所帮助:)