我有一个餐馆的MS SQL Server数据库。有一个事务表,显示了订购的饭菜,以及在适用的情况下,每顿饭订购的可选(选择)项目,例如“带薯条”,“带豆子”。
我正试图确定,对于每一个选择项目,什么是主食,它是命令与。
如何编写一个查询,使其无论有多少选择项都能找到合适的主餐?我们可以假设每个选择项都属于同一个主餐,直到新的主餐出现。
预期结果可能如下所示(查询创建的第一列和最后一列,中间列出现在表中):-
| 事务处理内的行|交易ID|行号|课程类别|项目名称|关联主餐|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 1个|一百二十三|小行星123456|主要|牛排|零|
| 第二章|一百二十三|小行星123457|选择|芯片|牛排|
| 三个|一百二十三|小行星123458|选择|豆类|牛排|
| 1个|一百二十四|小行星124567|主要|鱼|零|
| 第二章|一百二十四|小行星124568|选择|豆沙|鱼|
由于同一主餐可能有多个选项,因此类似LAST_VALUE()或LAG()(其中我们滞后1)的选项并不总是给予正确答案(例如:- )
CASE WHEN CourseCategory = 'Choice Items' THEN
LAST_VALUE(ItemName)
OVER(PARTITION BY TransactionID
ORDER BY LineNumber ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
ELSE NULL END AS AssociatedMainMeal
或
CASE WHEN CourseCategory = 'Choice Items' THEN
LAG(ItemName,1,0)
OVER(PARTITION BY TransactionID
ORDER BY LineNumber)
ELSE NULL END AS AssociatedMainMeal
我怀疑ROW_NUMBER()可能在某些地方有用,例如:ROW_NUMBER()OVER(PARTITION BY TransactionID ORDER BY LineNumber)AS RowWithinTxn,因为这会将表分割为单独的事务ID
非常感谢!
2条答案
按热度按时间zaqlnxep1#
要在此处使用条件聚集:
4xrmg8kj2#
假设每个事务可以有很多主餐,那么实际上需要一个
LAG
函数来忽略某些行。在一些RDMBS中有一个IGNORE NULLS
选项,在那里你可以使用如下的内容:不幸的是SQL Server不支持这个,但是Itzik Ben-Gan came up with a nice workaround使用窗口函数。本质上,如果你把你的排序列和数据列组合成一个二进制值,你可以用类似于
LAG
的方式使用MAX
,因为最大二进制值总是前一行,因为排序列是它的一部分。但是,这确实会让阅读变得非常痛苦,因为您必须将两列转换为二进制并将它们组合起来:
那就取最大值
然后删除前4个字符(从linenumber)并转换回varchar:
最后,您只需要显示非主餐的此值
将这些信息结合起来,沿着加上一些示例数据,您最终会得到: