进行了多次搜索并能够编写除此之外的所有JOIN查询。我有3个表,看起来像:
TABLE - accounts
account_id | account_email
1 | aa@bb.com
2 | cc@dd.com
TABLE - products
product_id | product_name
1 | name1
2 | name2
TABLE - licenses
license_id | account_id | product_id | license_code
1 | 1 | 1 |
2 | 1 | 2 |
3 | 0 | 1 | abc123
我知道account_email
,product_id
和license_code
(这可能是空的)变量,需要检查客户是否拥有所选产品的许可(按account_email
搜索或license_code
)。
问题是account_id
有时可能为0(换句话说,客户端有许可证,但客户端的配置文件未存储在帐户表中)。
尝试使用这个,但它返回错误的(重复的)结果:
SELECT * FROM licenses
INNER JOIN products ON licenses.product_id=products.product_id AND products.product_id='X'
INNER JOIN accounts ON licenses.account_id=accounts.account_id AND accounts.account_email='XYZ' OR licenses.license_code='ZZZ'
问题:如何重写查询,以便我可以在account_email
或license_code
字段找到记录?简而言之,如果account_id
不是0(配置文件存在),我应该看到3个表(帐户,产品,许可证)中的数据。如果account_id
为0,我应该看到来自2个表的数据(来自accounts表的值应该显示为空/ null)。
毋庸置疑,account_email
和license_code
字段是唯一的。
答案 0 :(得分:0)
您只需要调整括号即可。但是,我会使用单独的WHERE
子句:
SELECT *
FROM licenses l INNER JOIN
products p
ON l.product_id = p.product_id INNER JOIN
accounts a
ON l.account_id = a.account_id
WHERE p.product_id = 'X' AND
(a.account_email='XYZ' OR l.license_code = 'ZZZ')
您可以将过滤器保留在ON
子句中 - 这没有任何问题。我只想将连接条件与过滤条件分开。重要的部分是括号,因此ON
子句不被解释为:
ON (l.account_id = a.account_id AND a.account_email = 'XYZ') OR
licenses.license_code = 'ZZZ'
这是没有parens的解释。
答案 1 :(得分:0)
经过一些代码修改和测试后,这里的代码完美无缺。它是一个经过修改的Gordon Linoff代码(当只知道license_code时,原始代码不起作用,并且电子邮件地址不为人所知)。所以大部分学分归功于戈登·林诺夫的努力。
SELECT *
FROM licenses l JOIN
products p
ON l.product_id = p.product_id LEFT JOIN
accounts a
ON l.account_id = a.account_id
WHERE p.product_id = 'X' AND
(a.account_email='XYZ' OR l.license_code = 'ZZZ')