基本上我要做的是从一个表获取购买列表,并检查是否存在与购买并显示1
或0
的任何附件,如果有/ISN<找到一个附件。>
SELECT
CONCAT('#', LPAD(a.id, 5, '0')) as 'code',
a.id, a.value_total, DATE_FORMAT(a.date, '%d/%m/%Y') as 'date',
b.name as 'store',
CASE WHEN a.notes IS NOT NULL
THEN 1
ELSE 0
END AS notes
FROM
tb_purchase a,
tb_store b
WHERE a.id_store = b.id
AND a.id = :id_purchase // This line can be removed to get all the purchases or leave here to get just one with that specific ID
然后,我有一个名为ts_purchase_att
的表,在其中存储了购买和附件之间的附件关系。该表具有此结构:
id_purchase | id_attachment
32 | 47
32 | 127
33 | 68
38 | 97
我不需要获取附件,只需检查至少有一个与该购买有关的附件。
我尝试使用这样的东西,但它不起作用
LEFT JOIN
( SELECT 1 FROM ts_purchase_att c WHERE c.id_purchase = a.id ) as attachment
我在做什么错?
始终如一地使用JOIN
语法,自1992年以来一直是标准化。不要使用过时的逗号风格的连接。在您的情况下,混合两种语法样式正在引起真正的问题。
原因是JOIN
操作的优先级高于,
加入。因此,当您进行此类查询时:
FROM a, b LEFT OUTER JOIN c ON a.id = c.id_purchase
它首先尝试评估b LEFT OUTER JOIN c
,但是您在联接条件下引用了第一个表a
。MySQL甚至还没有使该表格别名,因此它返回属于a
的列的引用。
此处记录:https://dev.mysql.com/doc/refman/8.0/en/join.html
JOIN比逗号运算符(,(具有更高的优先级,因此JOIN表达式T1,T2 JOIN T3被解释为(T1,T2 JOIN T3((,而不是((T1,T2(JOIN T3(。这会影响使用AN子句的陈述,因为该子句只能指连接操作数中的列,并且优先级会影响对这些操作数的解释。
有关更多详细信息和示例,请参见手册的该部分。
以下是使用JOIN
语法结合内部连接的外部连接的方法:
SELECT IF(c.id_purchase IS NULL, 0, 1) AS attachment_found
FROM tb_purchase a,
INNER JOIN tb_store b ON a.id_store = b.id
LEFT OUTER JOIN ts_purchase_att c ON a.id = c.id_purchase
您需要一个LEFT JOIN
:
SELECT DISTINCT
CONCAT('#', LPAD(a.id, 5, '0')) as 'code',
a.id, a.value_total, DATE_FORMAT(a.date, '%d/%m/%Y') as 'date'
CASE
WHEN b.id IS NOT NULL THEN 1
ELSE 0
END AS notes
FROM tb_purchase a LEFT JOIN tb_store b
ON a.id_store = b.id
当表Tb_store中没有匹配时,B.ID为null。