SELECT bill.bill_id, bill.bill_ref
FROM bill
LEFT JOIN bill_item ON (bill.bill_id = bill_item.bill_id)
WHERE bill_item.job_sales_id = :job_sales_id and
bill.billing_type = "INV"
我想将以下内容添加到我的条件中:
IF bill.bill_ref = "",
bill.bill_ref NOT IN
(SELECT cn_inv FROM bill a WHERE a.billing_type = "CN")
我该如何编码?
bill table:
bill_id | bill_ref | billing_type | cn_inv
--------+----------+--------------+-------
1 | INV001 | INV |
2 | | INV |
3 | INV002 | INV |
4 | CN001 | CN | INV002
------------------------------------------
bill_item table:
bill_id | item_code | sales_id
--------+-----------+----------
1 | item001 | 10
1 | item002 | 11
2 | item001 | 13
3 | item001 | 13
4 | item001 | 13
给出时:
sales_id为13,返回rowCount等于0
sales_id为10,返回rowCount等于1
sales_id为11,返回rowCount等于0.
答案 0 :(得分:3)
不清楚应该返回什么结果。如果规范是排除 bill
中匹配行的行,我们可以使用带有相关子查询的NOT EXISTS
。
如果我们只希望在bill_ref
为非NULL且不是空字符串时应用排除...
SELECT b.bill_id
, b.bill_ref
FROM bill b
JOIN bill_item i
ON i.bill_id = b.bill_id
AND i.job_sales_id = :job_sales_id
WHERE b.billing_type = 'INV'
AND b.bill_ref IS NOT NULL
AND NOT EXISTS ( SELECT 1
FROM bill a
WHERE a.cn_inv = b.bill_ref
AND a.cn_inv <> ''
AND a.billing_type = 'CN'
)
请注意,这会排除bill_ref
具有NULL值的行。可以调整查询,以便返回NULL值为bill_ref的行。
我们也可以使用反连接模式返回等效结果......
SELECT b.bill_id
, b.bill_ref
FROM bill b
JOIN bill_item i
ON i.bill_id = b.bill_id
AND i.job_sales_id = :job_sales_id
-- anti-join exclude rows that have a match
LEFT
JOIN bill a
ON a.billing_type = 'CN'
AND a.cn_inv <> ''
AND a.cn_inv = b.bill_ref
WHERE a.cn_inv IS NULL
AND b.billing_type = 'INV'
AND b.bill_ref IS NOT NULL
在OP查询中,WHERE子句中的条件要求job_sales_id
表中的bill_item
为非NULL。这种情况否定了&#34;外在性&#34; LEFT加入。所以它等同于INNER联接。
此答案中的查询保留了该行为。 (对于LEFT
的连接,删除了bill_item
关键字,我们可以将条件从WHERE子句重定位到ON子句。)