Возвращает значение по умолчанию, если строки не найдены
У меня есть следующий оператор select, чтобы захватить следующий запланированный элемент для потока. Если нет соответствующей строки, я хочу, чтобы она возвращала значение по умолчанию. Здесь строка, которую я использую:
SELECT `file` FROM `show`, `schedule`
WHERE `channel` = 1 AND `start_time` <= UNIX_TIMESTAMP()
AND `start_time` > UNIX_TIMESTAMP()-1800 AND `show`.`id` = `schedule`.`file`
ORDER BY `start_time` DESC LIMIT 1
Это должно взять последний запланированный элемент, но не раньше, чем за 30 минут до запроса. Однако, если пользователь ничего не планирует, я хочу значение по умолчанию, так что что-то действительно играет в потоке. Я пробовал следующее:
SELECT COALESCE(`file`, 'default.webm') FROM `show`, `schedule`...
и
SELECT IFNULL(`file`, 'default.webm') FROM `show`, `schedule`
Однако он всегда возвращает пустой результат, если строки не найдены. Как я могу вернуть значение по умолчанию вместо?
Ответы
Ответ 1
Один из способов сделать это
SELECT IFNULL(MIN(`file`), 'default.webm') `file`
FROM `show`, `schedule`
WHERE `channel` = 1 AND `start_time` <= UNIX_TIMESTAMP()
AND `start_time` > UNIX_TIMESTAMP()-1800 AND `show`.`id` = `schedule`.`file`
ORDER BY `start_time` DESC LIMIT 1
Поскольку вы возвращаете только одну строку, вы можете использовать агрегатную функцию, в этом случае MIN()
, которая гарантирует, что вы получите NULL
, если не выбрана запись. Затем IFNULL()
или COALESCE()
выполнит свою работу.
Ответ 2
В случаях, когда ожидается только одна строка результатов, просто используйте UNION
с жестко заданными значениями во втором предложении SELECT
, которое имеет такое же количество столбцов, что и исходный SELECT.
Для OP:
(SELECT `file` FROM `show`, `schedule`
WHERE `channel` = 1 AND `start_time` <= UNIX_TIMESTAMP()
AND `start_time` > UNIX_TIMESTAMP()-1800 AND `show`.`id` = `schedule`.`file`
ORDER BY `start_time` DESC LIMIT 1) UNION (SELECT 'default.webm') LIMIT 1;
Запрет любых синтаксических ошибок, набор результатов будет обслуживать одну строку с одним столбцом с именем file
.
В качестве более общего примера:
(SELECT Col1,Col2,Col3 FROM ExampleTable WHERE ID='1234')
UNION (SELECT 'Def Val','none','') LIMIT 1;
В любом случае:
-
Если в первом SELECT нет строк, набор результатов будет заполнен значениями из второго SELECT.
-
Если одна строка найдена в первом SELECT, в наборе результатов предлагаются первые значения SELECT, а значения второго SELECT опущены.
* Вам не нужно назначать имя столбца/псевдоним для вторых значений SELECT, если вы хотите использовать одни и те же столбцы (в том же порядке) из первого SELECT.
* UNION не требует, чтобы имена столбцов из двух единых запросов были идентичными, на самом деле вы можете назначить разные имена столбцов второму запросу SELECT, если это поможет вашему делу. (Код обработки вашего набора результатов должен соответствовать этим разным именам столбцов.)
(SELECT Col1,Col2,Col3 FROM ExampleTable WHERE ID='1234')
UNION (SELECT 'Def Val' AS `Fallback1`,'none' AS `Fallback2`,'' AS `Fallback3`) LIMIT 1;
Мое мнение таково, что это очень легко читать и не похоже на налоговый запрос.
Ответ 3
Для обработки более широкого круга случаев вам понадобится условная логика. Это доступно только в хранимых процедурах в MySQL, поэтому вам нужно будет обернуть этот код в процедуру и вызвать его:
if exists (
SELECT `file` FROM `show`, `schedule`
WHERE `channel` = 1 AND `start_time` <= UNIX_TIMESTAMP()
AND `start_time` > UNIX_TIMESTAMP()-1800 AND `show`.`id` = `schedule`.`file`
) then
SELECT `file` FROM `show`, `schedule`
WHERE `channel` = 1 AND `start_time` <= UNIX_TIMESTAMP()
AND `start_time` > UNIX_TIMESTAMP()-1800 AND `show`.`id` = `schedule`.`file`
ORDER BY `start_time` DESC LIMIT 1
; else
select `DefaultValue` as `file`
; end if