Mysql проверить, если таблица имеет какое-либо значение - PullRequest
0 голосов
/ 29 июня 2019

По сути, я пытаюсь получить список покупок из одной таблицы и проверить, есть ли вложения, связанные с покупкой, и отобразить 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

Что я делаю не так?

Ответы [ 2 ]

3 голосов
/ 29 июня 2019

Используйте синтаксис 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
0 голосов
/ 29 июня 2019

Вам нужно 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 равен нулю.

...