SQL 子查询搞乱了分组依据
TSQL Sub Queries Are Messing Up Group By
提前感谢您提供的任何帮助。到目前为止,我在这里或其他地方的搜索中都找不到类似的东西,但我敢打赌更多,因为我不知道描述 issue/question.
的标准方法
我正在根据驻留在两个不同 table 中的数据构建查找代码。我们有可以与一个或多个选项相关联的菜单项。在这种情况下,我们正在处理咖喱(项目),它与一种肉(选择)和一种米饭(在同一选择 table 中找到的另一种选择)一起食用。完整的 PLU 是项目级别 SKU 与 2 个选择类别中每个类别的选择级别 SKU 串联而成。完整 PLU 的示例是:
'CuMaBfWh'
其中 'CuMa' 是商品级别的 SKU,'Bf' 和 'Wh' 分别是选择级别的 SKU。我能够在外部查询中使用子查询(不喜欢它)来构建 PLU。问题是这种方法不允许我正确地分组数据。示例 tables、查询、有问题的输出和正确的输出如下。
给定这些 table 中的示例数据:
门票
i_ticket_id
3个
TicketItem
i_ticket_item_id i_ticket_id i_menu_item_id dt_when
1 3 1 '02/08/2015 16:42:00'
2 3 1 '02/08/2015 16:42:00'
3 3 1 '02/08/2015 16:42:00'
4 3 1 '02/08/2015 16:42:00'
菜单项
i_menu_item_id s_mi_sku
1 'CuMa'
选择项
i_choice_item_id i_ticket_item_id i_choice_id
1 1 2
2 1 8
3 2 1
4 2 8
5 3 4
6 4 9
选择
i_choice_id s_choice_sku
1 'Ch'
2 'Bf'
3 'Po'
4 'To'
5 'St'
6 'Ve'
7 'Sh$'
8 'Wh'
9 'Br'
10 'Fr$'
11 'Nr'
正确的输出如下所示:
日期 PLU 数量
---- --- --- ------
2015 年 2 月 8 日 CuMaBfWh 2 19.00
02/08/2015 CuMaChWh 1 9.50
02/08/2015 CuMaToBr 1 9.50
我的问题查询:
SELECT CONVERT(VARCHAR(10), ti.dt_when, 101) [Date],
-- Start building the PLU with the sku from the item level
mi.s_mi_sku
-- Continue building the PLU by adding on the choice sku from the chosen meat
+ (SELECT TOP(1) c1.s_choice_sku
FROM Choices c1
INNER JOIN
ChoiceItem ci1 ON ci1.i_choice_id = c1.i_choice_id AND c1.s_choice_sku IN ('Ch', 'Bf', 'Po', 'To', 'St', 'Ve', 'Sh$')
WHERE ci1.i_ticket_item_id = ti.i_ticket_item_id)
-- Complete the PLU by adding on the choice sku from the chosen rice
+ (SELECT TOP(1) c2.s_choice_sku
FROM Choices c2
INNER JOIN
ChoiceItem ci2 ON ci2.i_choice_id = c2.i_choice_id AND c2.s_choice_sku IN ('Wh', 'Br', 'Fr$', 'Nr')
WHERE ci2.i_ticket_item_id = ti.i_ticket_item_id) [PLU],
SUM(ti.f_ticketitem_share_qty) [Qty],
SUM(ti.c_ticketitem_net_price) [Amount]
FROM Ticket t
INNER JOIN
TicketItem ti on t.i_ticket_id = ti.i_ticket_id
INNER JOIN
MenuItem mi on ti.i_menu_item_id = mi.i_menu_item_id
WHERE ti.dt_when >= '2/8/2015 04:00:00' and ti.dt_when <= '2/9/2015 03:59:00' and mi.s_mi_sku = 'CuMa'
GROUP BY mi.s_mi_sku, ti.dt_when, ti.i_ticket_item_id
产生以下有问题的输出:
日期 PLU 数量
---- --- --- ------
02/08/2015 CuMaBfWh 1 9.50
02/08/2015 CuMaChWh 1 9.50
02/08/2015 CuMaToBr 1 9.50
02/08/2015 CuMaBfWh 1 9.50
我认为这是需要在 'GROUP BY' 子句中包含 ti.i_ticket_item_id 的结果,但我想不出另一种方法来做到这一点。
有什么想法吗?感谢所有建设性的advice/criticism!
谢谢,
大卫
我不明白 ti.f_ticketitem_share_qty
如何适应事物,所以我刚刚添加了一些聚合,以便按预期分组。另请注意,您提供的数据不包括 2 位客户在同一订单上订购相同商品的情况,因此我添加了数据以便分组显示相关内容。
declare @Ticket table (i_ticket_id int)
insert into @Ticket values(3)
declare @TicketItem table (i_ticket_item_id int, i_ticket_id int, i_menu_item_id int, dt_when datetime)
insert into @TicketItem
values
(1,3,1,'02/08/2015 16:42:00'),
(2,3,1,'02/08/2015 16:42:00'),
(3,3,1,'02/08/2015 16:42:00'),
(4,3,1,'02/08/2015 16:42:00'),
(5,3,1,'02/08/2015 16:42:00')
declare @MenuItem table (i_menu_item_id int, s_mi_sku varchar(10))
insert into @MenuItem values (1,'CuMa')
declare @ChoiceItem table (i_choice_item_id int, i_ticket_item_id int, i_choice_id int)
insert into @ChoiceItem
values
(1,1,2),
(2,1,8),
(3,2,1),
(4,2,8),
(5,3,4),
(6,4,9),
(7,5,2),
(8,5,8)
declare @Choices table (i_choice_id int, s_choice_sku varchar(3))
insert into @Choices
values
(1,'Ch'),
(2,'Bf'),
(3,'Po'),
(4,'To'),
(5,'St'),
(6,'Ve'),
(7,'Sh$'),
(8,'Wh'),
(9,'Br'),
(10,'Fr$'),
(11,'Nr')
select
ti.dt_when,
isnull(m.s_mi_sku,'') + isnull(C1.s_choice_sku,'') + isnull(C2.s_choice_sku,'') as PLU,
count(t.i_ticket_id) as QTY
from
@Ticket t
inner join @TicketItem ti
on t.i_ticket_id = ti.i_ticket_id
inner join @MenuItem m
on m.i_menu_item_id = ti.i_menu_item_id
left join
(select
c1.i_ticket_item_id,
sum(case when c1.i_choice_id <=7
then c1.i_choice_id
else 0 end) c1,
sum(case when c1.i_choice_id >=8
then c1.i_choice_id
else 0 end) c2
from
@ChoiceItem c1
group by c1.i_ticket_item_id
) c
on c.i_ticket_item_id = ti.i_ticket_item_id
left join @Choices C1
on C1.i_choice_id = c.c1
left join @Choices C2
on C2.i_choice_id = c.c2
where
ti.dt_when between '2/8/2015 04:00:00' and '2/9/2015 03:59:00'
and m.i_menu_item_id = 1
group by
ti.dt_when,
m.s_mi_sku,
C1.s_choice_sku,
C2.s_choice_sku
提前感谢您提供的任何帮助。到目前为止,我在这里或其他地方的搜索中都找不到类似的东西,但我敢打赌更多,因为我不知道描述 issue/question.
的标准方法我正在根据驻留在两个不同 table 中的数据构建查找代码。我们有可以与一个或多个选项相关联的菜单项。在这种情况下,我们正在处理咖喱(项目),它与一种肉(选择)和一种米饭(在同一选择 table 中找到的另一种选择)一起食用。完整的 PLU 是项目级别 SKU 与 2 个选择类别中每个类别的选择级别 SKU 串联而成。完整 PLU 的示例是:
'CuMaBfWh'
其中 'CuMa' 是商品级别的 SKU,'Bf' 和 'Wh' 分别是选择级别的 SKU。我能够在外部查询中使用子查询(不喜欢它)来构建 PLU。问题是这种方法不允许我正确地分组数据。示例 tables、查询、有问题的输出和正确的输出如下。
给定这些 table 中的示例数据:
门票
i_ticket_id 3个
TicketItem
i_ticket_item_id i_ticket_id i_menu_item_id dt_when 1 3 1 '02/08/2015 16:42:00' 2 3 1 '02/08/2015 16:42:00' 3 3 1 '02/08/2015 16:42:00' 4 3 1 '02/08/2015 16:42:00'
菜单项
i_menu_item_id s_mi_sku 1 'CuMa'
选择项
i_choice_item_id i_ticket_item_id i_choice_id 1 1 2 2 1 8 3 2 1 4 2 8 5 3 4 6 4 9
选择
i_choice_id s_choice_sku 1 'Ch' 2 'Bf' 3 'Po' 4 'To' 5 'St' 6 'Ve' 7 'Sh$' 8 'Wh' 9 'Br' 10 'Fr$' 11 'Nr'
正确的输出如下所示:
日期 PLU 数量 ---- --- --- ------ 2015 年 2 月 8 日 CuMaBfWh 2 19.00 02/08/2015 CuMaChWh 1 9.50 02/08/2015 CuMaToBr 1 9.50
我的问题查询:
SELECT CONVERT(VARCHAR(10), ti.dt_when, 101) [Date],
-- Start building the PLU with the sku from the item level
mi.s_mi_sku
-- Continue building the PLU by adding on the choice sku from the chosen meat
+ (SELECT TOP(1) c1.s_choice_sku
FROM Choices c1
INNER JOIN
ChoiceItem ci1 ON ci1.i_choice_id = c1.i_choice_id AND c1.s_choice_sku IN ('Ch', 'Bf', 'Po', 'To', 'St', 'Ve', 'Sh$')
WHERE ci1.i_ticket_item_id = ti.i_ticket_item_id)
-- Complete the PLU by adding on the choice sku from the chosen rice
+ (SELECT TOP(1) c2.s_choice_sku
FROM Choices c2
INNER JOIN
ChoiceItem ci2 ON ci2.i_choice_id = c2.i_choice_id AND c2.s_choice_sku IN ('Wh', 'Br', 'Fr$', 'Nr')
WHERE ci2.i_ticket_item_id = ti.i_ticket_item_id) [PLU],
SUM(ti.f_ticketitem_share_qty) [Qty],
SUM(ti.c_ticketitem_net_price) [Amount]
FROM Ticket t
INNER JOIN
TicketItem ti on t.i_ticket_id = ti.i_ticket_id
INNER JOIN
MenuItem mi on ti.i_menu_item_id = mi.i_menu_item_id
WHERE ti.dt_when >= '2/8/2015 04:00:00' and ti.dt_when <= '2/9/2015 03:59:00' and mi.s_mi_sku = 'CuMa'
GROUP BY mi.s_mi_sku, ti.dt_when, ti.i_ticket_item_id
产生以下有问题的输出:
日期 PLU 数量 ---- --- --- ------ 02/08/2015 CuMaBfWh 1 9.50 02/08/2015 CuMaChWh 1 9.50 02/08/2015 CuMaToBr 1 9.50 02/08/2015 CuMaBfWh 1 9.50
我认为这是需要在 'GROUP BY' 子句中包含 ti.i_ticket_item_id 的结果,但我想不出另一种方法来做到这一点。
有什么想法吗?感谢所有建设性的advice/criticism!
谢谢, 大卫
我不明白 ti.f_ticketitem_share_qty
如何适应事物,所以我刚刚添加了一些聚合,以便按预期分组。另请注意,您提供的数据不包括 2 位客户在同一订单上订购相同商品的情况,因此我添加了数据以便分组显示相关内容。
declare @Ticket table (i_ticket_id int)
insert into @Ticket values(3)
declare @TicketItem table (i_ticket_item_id int, i_ticket_id int, i_menu_item_id int, dt_when datetime)
insert into @TicketItem
values
(1,3,1,'02/08/2015 16:42:00'),
(2,3,1,'02/08/2015 16:42:00'),
(3,3,1,'02/08/2015 16:42:00'),
(4,3,1,'02/08/2015 16:42:00'),
(5,3,1,'02/08/2015 16:42:00')
declare @MenuItem table (i_menu_item_id int, s_mi_sku varchar(10))
insert into @MenuItem values (1,'CuMa')
declare @ChoiceItem table (i_choice_item_id int, i_ticket_item_id int, i_choice_id int)
insert into @ChoiceItem
values
(1,1,2),
(2,1,8),
(3,2,1),
(4,2,8),
(5,3,4),
(6,4,9),
(7,5,2),
(8,5,8)
declare @Choices table (i_choice_id int, s_choice_sku varchar(3))
insert into @Choices
values
(1,'Ch'),
(2,'Bf'),
(3,'Po'),
(4,'To'),
(5,'St'),
(6,'Ve'),
(7,'Sh$'),
(8,'Wh'),
(9,'Br'),
(10,'Fr$'),
(11,'Nr')
select
ti.dt_when,
isnull(m.s_mi_sku,'') + isnull(C1.s_choice_sku,'') + isnull(C2.s_choice_sku,'') as PLU,
count(t.i_ticket_id) as QTY
from
@Ticket t
inner join @TicketItem ti
on t.i_ticket_id = ti.i_ticket_id
inner join @MenuItem m
on m.i_menu_item_id = ti.i_menu_item_id
left join
(select
c1.i_ticket_item_id,
sum(case when c1.i_choice_id <=7
then c1.i_choice_id
else 0 end) c1,
sum(case when c1.i_choice_id >=8
then c1.i_choice_id
else 0 end) c2
from
@ChoiceItem c1
group by c1.i_ticket_item_id
) c
on c.i_ticket_item_id = ti.i_ticket_item_id
left join @Choices C1
on C1.i_choice_id = c.c1
left join @Choices C2
on C2.i_choice_id = c.c2
where
ti.dt_when between '2/8/2015 04:00:00' and '2/9/2015 03:59:00'
and m.i_menu_item_id = 1
group by
ti.dt_when,
m.s_mi_sku,
C1.s_choice_sku,
C2.s_choice_sku