Как получить результат в одной строке для данных

#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.

dbfiddle

Комментарии:

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);