基本上我想做的是从一张桌子上获得一份购买清单,并检查是否有与购买相关的附件,并显示1
或0
是否存在/是否找不到附件。
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
我在做什么错了?
答案 0 :(得分:3)
始终使用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的优先级高于逗号运算符(,),因此联接表达式t1,t2 JOIN t3被解释为(t1,(t2 JOIN t3)),而不是((t1,t2)JOIN t3)。这会影响使用ON子句的语句,因为该子句只能引用联接操作数中的列,并且优先级会影响对这些操作数的解释。
有关更多详细信息和示例,请参见手册的该部分。
以下是使用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
答案 1 :(得分:0)
您需要一个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。