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
我是 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