3 Запрос по столбцу и создание новой таблицы - PullRequest
0 голосов
/ 18 октября 2019

У меня есть студенты, и эти студенты едят утром и вечером. Я хочу напечатать количество блюд, которое каждый студент ест утром и вечером.

Если количество блюд, которые студент ест утром, больше одного, я хочу напечатать число в таблице иИдентификатор продукта.

FoodType когда 1 (утро) и когда 2 (вечер)

StudentId FoodId FoodType
    3       1       1
    3       2       1
    3       3       1
    3       4       2
    4       3       1
    4       1       2
    4       2       2
    4       4       2
    5       4       2
    5       1       1
    6       1       1
    6       2       1
    6       3       2
    6       4       2

Проба;

StudentId  MorningFoodCountOrId  EveningFoodCountOrId
    3             3 meals                 4
    4             3                       3 meals
    5             4                       1
    6             2 meals                 2 meals

Ответы [ 2 ]

0 голосов
/ 18 октября 2019

Использовать условную агрегацию. Логика, которая решает, будем ли мы печатать количество записей или их значение, не интуитивна, но я бы сформулировал это следующим образом:

select 
    studentId, 
    case when sum(case when foodtype = 1 then 1 else 0 end) = 1
        then max(case when foodtype = 1 then foodId end) 
        else sum(case when foodtype = 1 then 1 else 0 end)
    end MorningFoodCountOrId
    case when sum(case when foodtype = 2 then 1 else 0 end) = 1
        then max(case when foodtype = 2 then foodId end) 
        else sum(case when foodtype = 2 then 1 else 0 end)
    end EveningFoodCountOrId
from mytable
group by studentId

Ваша RDMBS должна быть в состоянии оптимизировать запрос, не вычисляя условные суммыдважды.

Примечание: вы не указали, какую RDMBS вы используете. Если это MySQL, то можно немного сократить условные суммы следующим образом:

select 
    studentId, 
    case when sum(foodtype = 1) = 1
        then max(case when foodtype = 1 then foodId end) 
        else sum(foodtype = 1)
    MorningFoodCountOrId
    case when sum(foodtype = 2) = 1
        then max(case when foodtype = 2 then foodId end) 
        else sum(foodtype = 2)
    EveningFoodCountOrId
from mytable
group by studentId
0 голосов
/ 18 октября 2019

Вот ваш запрос, select sum() и case.. сделают это

select t1.studentid
    , case when t1.m <= 1 then t2.FoodId else concat(t1.m, ' meals') end MorningFoodCountOrId  
    , case when t1.e <= 1 then t3.FoodId else concat(t1.e, ' meals') end EveningFoodCountOrId

from(
    select studentid
      , sum(case when FoodType = 1 then 1 else 0 end) as m       
      , sum(case when FoodType = 2 then 1 else 0 end) as e        
    from tableA
    group by studentid) t1
left join tableA t2 on t2.studentId = t1.studentId and t1.m = 1 and t2.FoodType = 1
left join tableA t3 on t3.studentId = t1.studentId and t1.e = 1 and t3.FoodType = 2
order by t1.studentid 

see dbfiddle

in postgresql

, case when t1.m <= 1 then t2.FoodId::text else concat(t1.m, ' meals') end MorningFoodCountOrId  
, case when t1.e <= 1 then t3.FoodId::text else concat(t1.e, ' meals') end EveningFoodCountOrId
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...