#mysql #sql
#mysql #sql
Вопрос:
У меня есть таблица beats
, и для каждого такта в таблице есть несколько строк, содержащих разные цены pricing
.
SELECT b.id, b.name,
(SELECT p.price FROM pricing as p WHERE p.license = 1 AND p.beat_id = b.id) as price_1,
(SELECT p.price FROM pricing as p WHERE p.license = 2 AND p.beat_id = b.id) as price_2
FROM beats as b
WHERE b.added > 0
AND b.active = 1
AND b.deleted = 0
AND price_1 > 0
ORDER BY b.id DESC
LIMIT 50
Я пытаюсь убедиться, что a beat
извлекается только тогда, когда значение price_1
больше 0.
Это не работает, потому что вы не можете использовать результат вложенного оператора SQL в WHERE
предложении, но я пробовал HAVING price_1 > 0
, и это тоже не работает.
Как я могу проверить price_1
и price_2
?
Комментарии:
1. Почему вы используете
GROUP BY
без каких-либо агрегатных функций?2. @Barmar это была ошибка копирования / вставки, я исправил вопрос.
Ответ №1:
Вы можете переместить это условие в having
предложение. Это особенность MySQL и не поддерживается другими базами данных:
SELECT b.id, b.name,
(SELECT p.price FROM pricing as p WHERE p.license = 1 AND p.beat_id = b.id) as price_1,
(SELECT p.price FROM pricing as p WHERE p.license = 2 AND p.beat_id = b.id) as price_2
FROM beats as b
WHERE b.added > 0 AND b.active = 1 AND b.deleted = 0
GROUP BY b.producer
HAVING price_1 > 0
ORDER BY b.id DESC
LIMIT 50;
Комментарии:
1. Ах, правильно, теперь это работает
HAVING
послеGROUP BY
того, как я поместил его чуть раньше. Спасибо за вашу помощь… теперь чувствую себя глупо!2. @JohnRuddell Я всегда принимаю правильные ответы, но на этот вопрос ответили так быстро, что он не позволил мне сделать это сразу.
3. А, ладно, круто.. я просто хотел быть уверенным, потому что есть некоторые люди, которые это делают 🙂
Ответ №2:
Вы можете использовать соединение:
SELECT b.id, b.name, p1.price AS price_1, p2.price AS price_2
FROM beats AS b
JOIN pricing AS p1 ON p1.beat_id = b.id
JOIN pricing AS p2 ON p2.beat_id = b.id
WHERE b.added > 0 AND b.active = 1 AND b.deleted = 0
AND p1.license = 1 AND p1.price > 0
AND p2.licence = 2
GROUP BY b.producer
ORDER BY b.id DESC
LIMIT 50
Ответ №3:
В отсутствие DML для ваших таблиц (например, непонятно, зачем вам это нужно group by b.producer
, учитывая, что b.id
это выглядит как первичный ключ), минимальное изменение заключается в том, чтобы перенести вложенный запрос в подзапрос и выполнить для него внутреннее соединение
SELECT b.id, b.name,
p1.price as price_1,
(SELECT p.price FROM pricing as p WHERE p.license = 2 AND p.beat_id = b.id) as price_2
FROM beats as b
JOIN pricing p1 ON (p1.license = 1 AND p1.beat_id = b.id AND p1.price > 0)
WHERE b.added > 0
AND b.active = 1
AND b.deleted = 0
GROUP BY b.producer
ORDER BY b.id DESC
LIMIT 50
Предполагая, что b.id
это первичный ключ, я бы также отбросил group by b.producer
, и, вероятно, разумно включить запрос price_2 в соединение (хотя, опять же, без дополнительных знаний ваших данных и DML я не могу точно сказать, должно ли это быть внутреннее или левое внешнее соединение).