#mysql #join #mysql-8.0
Вопрос:
У меня есть следующие две таблицы,
Периоды таблицы,
Id Names
1 Simon
2 Davis
Уровень таблицы,
Id sYear days
1 0 0
1 1 21
1 5 30
2 0 0
2 1 26
2 5 30
Схема таблицы не самая лучшая, но я мало что могу с этим поделать.
Мне нужно повторно просмотреть дни для идентификации на основе следующих критериев,
- Если sYear равен 0, верните 0
- Если sYear находится между 1 и 5, верните 21 или 26, если это идентификатор 2 в приведенных выше образцах данных
- если год больше 5, верните 30
Значения столбцов дней различаются для разных идентификаторов, но год всегда равен 0,1 и 5.
Моя попытка выглядит так,
set @sYear = 7;
SELECT
et.id,
names,
CASE
WHEN @sYear = 0 THEN days
WHEN @sYear BETWEEN 1 AND 5 THEN days
WHEN @sYear > 5 THEN days
END as Result
FROM
Periods ep
JOIN
Tier et ON (et.id = ep.id) AND et.id = 2;
что дает такие результаты, как,
id names Result
2 Davis 0
2 Davis 26
2 Davis 30
в то время как требуемый результат,
id names Result
2 Davis 30
поскольку @sYear = 7 больше 5.
Комментарии:
1. Почему каждое
WHEN
условие в вашемCASE
заявлении оцениваетсяdays
как ?2. поскольку значение дней является одним из обязательных значений, которое должно быть возвращено запросом
3. Тогда почему бы и нет
SELECT et.id, names, days FROM ...
?4. Будет намного легче понять, что вы говорите, если вы сможете использовать ссылку dbfiddle, которую я поставил в вопросе. Если ранее не было ясно, что 7-это просто пример, значение для @sYear может быть любым. И et.id = 2 также может быть любым идентификатором.
Ответ №1:
Следующий запрос приведет к результатам, которые вы можете найти в таблицах:
@sYear = 7
ID | дни | имена |
---|---|---|
1 | 30 | Саймон |
2 | 30 | Дэвис |
@sYear = 3
ID | дни | имена |
---|---|---|
1 | 21 | Саймон |
2 | 26 | Дэвис |
@sYear = 0
ID | дни | имена |
---|---|---|
1 | 0 | Саймон |
2 | 0 | Дэвис |
SELECT
et.id, names, days as result
FROM
Tier et,
Periods p
WHERE
et.id = p.id
AND et.days = (CASE
WHEN @sYear = 0 THEN 0
WHEN
@sYear BETWEEN 1 AND 5 AND et.id = 2
THEN
(SELECT
days
FROM
Tier et
WHERE
sYear = 1 AND et.id = 2)
WHEN
@sYear BETWEEN 1 AND 5 AND et.id = 1
THEN
(SELECT
days
FROM
Tier et
WHERE
sYear = 1 AND et.id = 1)
WHEN @sYear > 5 THEN 30
END);
Ответ №2:
Следующий запрос даст именно тот результат, который вы указали в своем вопросе:
@sYear = 7
ID | имена | Результат |
---|---|---|
2 | Дэвис | 30 |
SELECT
et.id, names, days AS result
FROM
Tier et,
Periods p
WHERE
et.id = p.id AND et.id = 2
AND et.days = (CASE
WHEN @sYear = 0 THEN 0
WHEN
@sYear BETWEEN 1 AND 5 AND et.id = 2
THEN
(SELECT
days
FROM
Tier et
WHERE
sYear = 1 AND et.id = 2)
WHEN
@sYear BETWEEN 1 AND 5 AND et.id = 1
THEN
(SELECT
days
FROM
Tier et
WHERE
sYear = 1 AND et.id = 1)
WHEN @sYear > 5 THEN 30
END);