Один запрос для нескольких отборов - даже если один выбор возвращает пустой

Мне нужно сделать несколько операторов выбора, чтобы получить простые данные (только одна строка, содержащая одно или несколько полей для каждого выбора).

Упрощенный пример:

select name, price from article where id=125
select log, email from user where uid=241

Я хочу обработать только один оператор со стороны php (или: Я НЕ хочу готовить несколько операторов, выполнять несколько операторов, перехватывать и обрабатывать исключения для каждого выполнения и, наконец, извлекать результат для каждого оператора...).
Я старался:

select * from (
  (select name, price from article where id=125) as a,
  (select log, email from user where uid=241) as b
)

который прекрасно работает, если каждый подвыбор возвращает значения:

name  |  price  | log  | email
------------------------------------------
dummy |  12,04  | john | john@example.com

Но если один из подвыборов возвращается пустым, весь выбор возвращается пустым.
То, что я хочу: нулевые значения для пустых результирующих подвыборов
Я перепробовал много вещей с ifnull() а также coalesce(), но не смог получить ожидаемый результат (я знаю, как использовать их с нулевыми значениями, но я не нашел способа справиться с ними в случае пустого набора результатов).
Я наконец нашел решение с левыми соединениями:

select * from (
  (select 1) as thisWillNeverReturnEmpty
  left join (select name, price from article where id=125) as a on 1
  left join (select log, email from user where uid=241) as b on 1
)

который отлично работает, даже если один из подзапросов возвращает пустой (или даже оба, следовательно, "select 1").
Другой способ, который я нашел на SO, - это добавить count(*) в каждом подзапросе, чтобы убедиться, что есть значение.

Но все выглядит довольно грязно, и я не могу поверить, что нет простого способа использовать что-то вроде ifnull(), Как правильно это сделать?

1 ответ

Решение

Лучший способ, который я наконец нашел, был:

select * from (
  (select count(*) as nbArt, name, price from article where id=125) as a,
  (select count(*) as nbUser, log, email from user where uid=241) as b
)

Таким образом, ни один подзапрос никогда не возвращает пустое значение, что решает проблему (всегда есть хотя бы "нулевой" счетчик, за которым следуют нулевые значения).

Пример результата, когда статья не найдена:

nbArt  |  name  |  price  |  nbUser  |  log  |  email
----------------------------------------------------------------
  0    |  null  |   null  |    1     |  john | john@example.com
Другие вопросы по тегам