SQL - 创建一个列以在案例中使用但不想按它分组

SQL - Creating a column to use in a case but don't want to group by it

我是 SQL 的初学者。我在 Teradata 中使用它。

我想按用餐时间细分餐饮数据。 本质上,首先我要根据餐厅的风格对餐厅进行分类。然后我使用该样式和订购时间按用餐时间对订单计数进行分类。然后我为每个时间段创建单独的列(尝试取消数据透视)。

这是我的代码的简化版本:

SELECT year AS year
, week AS week
, case
    when type like('Q%') then 'Q'
    when type like('T%') then 'T'
    else 'Other'
    end 
    AS style
, restaurant_id AS rest_id
, case WHEN style = 'T' then (
        case
            when cast(order_time as time format 'HH:MI:SS') between '03:00:01' and '11:30:00' then 'Breakfast'
            when cast(order_time as time format 'HH:MI:SS') between '11:30:01' and '16:30:00' then 'Lunch'
            else 'Dinner'
            end
        )
        else (
        case
    when cast(order_time as time format 'HH:MI:SS') between '03:00:01' and '10:00:00' then 'Breakfast'
    when cast(order_time as time format 'HH:MI:SS') between '10:00:01' and '14:59:00' then 'Lunch'
    else 'Dinner'
    end)
    end
    as meal_period
, count(distinct case when meal_period = 'Breakfast' then order_number else null end) as food_count_b
, count(distinct case when meal_period = 'Lunch' then order_number else null end) as food_count_l
, count(distinct case when meal_period = 'Dinner' then order_number else null end) as food_count_d
FROM table1
group by 1,2,3,4,5
order by 1,2,3,4,5

它会产生这样的 table:

year  week  style rest_id  meal_period  food_count_b  food_count_l  food_count_d
2017  1     T     1234     Breakfast    5
2017  1     T     1234     Lunch                      18
2017  1     T     1234     Dinner                                    17
2017  1     Q     9955     Breakfast    8
2017  1     Q     9955     Lunch                      21
2017  1     Q     9955     Dinner                                    24
2017  2     T     1234     Breakfast    4
2017  2     T     1234     Lunch                      20
2017  2     T     1234     Dinner                                    18
2017  2     Q     9955     Breakfast    6
2017  2     Q     9955     Lunch                      29
2017  2     Q     9955     Dinner                                    31

我真正想要的是没有 meal_period 列,我创建它只是为了更容易按用餐时间为他们自己的列划分计数(food_count_b,food_count_l, 和 food_count_d).

理想情况下,我希望我的 table 像这样:

year  week  style rest_id  food_count_b  food_count_l  food_count_d
2017  1     T     1234     5             18            17
2017  1     Q     9955     8             21            24
2017  2     T     1234     4             20            18
2017  2     Q     9955     6             29            31

知道怎么做吗?谢谢!

DECLARE @TMP_TABLE TABLE
(
    idx INT IDENTITY(1, 1) PRIMARY KEY,
    Column1 NVARCHAR(50),
    Column2 NVARCHAR(50),
    Column3 NVARCHAR(50)
)

INSERT INTO @TMP_TABLE (
                           Column1,
                           Column2,
                           Column3
                       )
VALUES (   N'Value1', -- Column1 - nvarchar(50)
           N'Value2', -- Column2 - nvarchar(50)
           N'Value 3'   -- Column3 - nvarchar(50)
       )

SELECT  [idx] = T.idx,
        [Column1] = T.Column1,
        [Column2] = T.Column2,
        [Column3] = T.Column3
FROM @TMP_TABLE T

你有两个选择..

1.) 完全取出 meal_period,然后在您希望保留的其他列中直接使用该列中的逻辑。

例如,更改为:

count(distinct case when meal_period = 'Breakfast' then order_number else null end) as food_count_b

对于这样的事情(我不太明白你的逻辑,但你应该明白这个想法):

count(distinct case when style = 'T' and cast(order_time as time format 'HH:MI:SS') between '03:00:01' and '11:30:00' 
                    then order_number
                    when style <> 'T' and cast(order_time as time format 'HH:MI:SS') between '03:00:01' and '10:00:00'
                    then order_number
                    else null end) as food_count_b

2.) 使整个查询成为派生的 table 然后更改外部 select:

SELECT year, week, style, rest_id, MAX(Food_Count_b), MAX(Food_Count_l), MAX(Food_Count_d)
FROM (
SELECT year AS year
, week AS week
, case
    when type like('Q%') then 'Q'
    when type like('T%') then 'T'
    else 'Other'
    end 
    AS style
, restaurant_id AS rest_id
, case WHEN style = 'T' then (
        case
            when cast(order_time as time format 'HH:MI:SS') between '03:00:01' and '11:30:00' then 'Breakfast'
            when cast(order_time as time format 'HH:MI:SS') between '11:30:01' and '16:30:00' then 'Lunch'
            else 'Dinner'
            end
        )
        else (
        case
    when cast(order_time as time format 'HH:MI:SS') between '03:00:01' and '10:00:00' then 'Breakfast'
    when cast(order_time as time format 'HH:MI:SS') between '10:00:01' and '14:59:00' then 'Lunch'
    else 'Dinner'
    end)
    end
    as meal_period
, count(distinct case when meal_period = 'Breakfast' then order_number else null end) as food_count_b
, count(distinct case when meal_period = 'Lunch' then order_number else null end) as food_count_l
, count(distinct case when meal_period = 'Dinner' then order_number else null end) as food_count_d
FROM table1
group by 1,2,3,4,5
) a
GROUP BY year, week, style, rest_id