我有以下在MySQL中运行的查询:
SELECT 'DEMO' client, COUNT(*) n, SUM(PYMT_Total_Paid) actual
FROM Payments
WHERE (PYMT_CLIENT1,PYMT_CLIENT2) IN (('DEMO','SL'))
AND PYMT_DTEPYD ='20150825'
AND PYMT_MISC IN ('PY','RC','ER','RG','SP','BN','BS','SB')
AND PYMT_BEEN_REVERSED != 'Y'
当我在MSSQL中运行它时,它会失败并显示以下消息:
An expression of non-boolean type specified in a context where a condition
is expected, near ','.
如果我从查询中删除(PYMT_CLIENT1,PYMT_CLIENT2) IN (('DEMO','SL')) AND
,它运行正常。因此,当使用IN子句搜索复合键时,MSSQL似乎需要与MySQL不同的语法。
任何关于在何处找到正确语法或正确语法的指针都将受到高度赞赏。 谢谢!
修改
我提供的案例过于简单了。如果查询在IN子句中有多个对,例如,解决方案也应该有效。 ...... IN (('DEMO","SL"),("ED","AUTO"),("ED","PHOTO"))
答案 0 :(得分:3)
你也可以改变
(PYMT_CLIENT1,PYMT_CLIENT2) IN (('DEMO','SL'))
到
EXISTS (SELECT PYMT_CLIENT1,PYMT_CLIENT2 INTERSECT SELECT 'DEMO','SL')
这对空值的处理与结合等式谓词不同,但在你的情况下没有区别,因为右边的两个常量不是空的。
答案 1 :(得分:2)
SQL Server不支持Row Value Constructor。
类似案例UPDATE tab SET (a,b) = ('Yes', 'No')
。
使用T-SQL version
<强>解决方案:强>
1)当条件简单时使用AND
(PYMT_CLIENT1,PYMT_CLIENT2) IN (('DEMO','SL'))
/* becomes */
PYMT_CLIENT1 = 'DEMO' AND PYMT_CLIENT2 = 'SL'
2)第二种情况IN (('DEMO","SL"),("ED","AUTO"),("ED","PHOTO"))
可以解开,如:
WHERE
CASE
WHEN PYMT_CLIENT1 = 'DEMO' AND PYMT_CLIENT2 = 'SL' THEN 1
WHEN PYMT_CLIENT1 = 'ED' AND PYMT_CLIENT2 = 'AUTO' THEN 1
WHEN PYMT_CLIENT1 = 'ED' AND PYMT_CLIENT2 = 'PHOTO' THEN 1
ELSE 0
END = 1
2&#39;)将条件从WHERE移动到INNER JOIN并加入Derived Table:
SELECT
'DEMO' AS client,
COUNT(*) AS n,
SUM(PYMT_Total_Paid) AS actual
FROM Payments p
INNER JOIN (VALUES ('DEMO', 'SL'), ('ED', 'AUTO'), ('ED', 'PHOTO')) AS x(c1, c2)
ON p.PYMT_CLIENT1 = x.c1 AND p.PYMT_CLIENT2 = x.c2
WHERE
(...)
2&#39;&#39;)将Martin Smith solution与派生表结合起来
WHERE
EXISTS
(
SELECT PYMT_CLIENT1,PYMT_CLIENT2
INTERSECT
SELECT c1, c2
FROM (VALUES ('DEMO', 'SL'), ('ED', 'AUTO'), ('ED', 'PHOTO')) AS X(c1, c2)
)
答案 2 :(得分:0)
修改您的查询有点像
SELECT 'DEMO' as client,
COUNT(*) as n,
SUM(PYMT_Total_Paid) as actual
FROM Payments
WHERE PYMT_CLIENT1 IN ('DEMO','SL')
AND PYMT_CLIENT2 IN ('DEMO','SL')
AND PYMT_DTEPYD = '20150825'
AND PYMT_MISC IN ('PY','RC','ER','RG','SP','BN','BS','SB')
AND PYMT_BEEN_REVERSED != 'Y';
答案 3 :(得分:0)
这是正确的逻辑:
WHERE PYMT_CLIENT1 = 'DEMO' AND PYMT_CLIENT2 = 'SL' AND
PYMT_DTEPYD = '20150825' AND
PYMT_MISC IN ('PY', 'RC', 'ER', 'RG', 'SP', 'BN', 'BS', 'SB') AND
PYMT_BEEN_REVERSED <> 'Y';
表达式(a, b) in ((x, y))
正在查看值的对,而不是单独查看每个值。因为IN
列表中只有一个值,所以这相当于单独进行比较。