SQL 组行选择
Posted
技术标签:
【中文标题】SQL 组行选择【英文标题】:SQL Group Row Selection 【发布时间】:2018-01-12 19:28:18 【问题描述】:您好,我有以下查询以从我的系统中获取所有定价。 我需要将所有这些选择分组,然后我需要选择第二个最新日期以获得前一天的定价。问题是前一天的定价不是今天 - 1 天。例如,对于某个 stock_id,它可能是今天 - 5 天。我正在通过 excel 中的 microsoft 查询执行此任务,因此无法使用 row_number()。
查询将输出以下内容:
MS_CODE LOCATION_CODE MFG_CODE GROUP_CODE STOCK_ID EFFECTIVE_DATE PRICE
COKE 12 23 HTG 23 01/12/2018 1.00
COKE 12 23 HTG 23 01/11/2018 0.99
COKE 12 23 HTG 23 01/10/2018 1.05
PEPSI 12 23 HTG 23 01/12/2018 1.10
PEPSI 12 23 HTG 23 01/11/2018 1.00
PEPSI 12 23 HTG 23 01/10/2018 0.60
我需要输出的是:
MS_CODE LOCATION_CODE MFG_CODE GROUP_CODE STOCK_ID EFFECTIVE_DATE PRICE
COKE 12 23 HTG 23 01/11/2018 0.99
PEPSI 12 23 HTG 23 01/11/2018 1.00
我当前的查询是:
SELECT
dbo.PRICE_BOOK.ms_code,
dbo.PRICE_BOOK.location_code,
dbo.PRICE_BOOK.mfg_code,
dbo.PRICE_BOOK.group_code,
dbo.PRICE_BOOK.stock_id,
dbo.PRICE_BOOK.effective_date,
dbo.PRICE_BOOK.price
FROM dbo.PRICE_BOOK
提前致谢。
【问题讨论】:
【参考方案1】:如果我理解正确,这样的事情应该可以工作:
SELECT pb.ms_code,
pb.location_code,
pb.mfg_code,
pb.group_code,
pb.stock_id,
MAX(effective_date) effective_date,
price
FROM dbo.PRICE_BOOK pb
JOIN (SELECT MAX(effective_date) as dte,
ms_code,
location_code,
mfg_code,
group_code,
stock_id
FROM dbo.PRICE_BOOK
GROUP BY ms_code,
location_code,
mfg_code,
group_code,
stock_id) pb2 on pb.ms_code = pb2.ms_code
and pb.location_code = pb2.location_code
and pb.mfg_code = pb2.mfg_code
and pb.group_code = pb2.group_code
and pb.stock_id = pb2.stock_id
and pb.effective_date < pb2.dte
GROUP BY pb.ms_code,
pb.location_code,
pb.mfg_code,
pb.group_code,
pb.stock_id,
price
根据一些谷歌搜索,语法似乎是有效的,但我们会看到。如果stock_id
不足以确定正确的日期,则可能需要向内部选择/加入添加更多内容。
【讨论】:
以下 ms_code、location_code、mfg_code、group_code、stock_id 的每个组合可以有不同的日期和不同的价格。我一直在尝试编辑您的查询 2 小时,但没有成功。有什么想法吗? 亚伦我也没有试图抓住最大我试图抓住第二个最新的有效日期。请注意,在我的示例中,我的输出是第 11 次而不是第 12 次。 @jeffpro 这将获取倒数第二个日期。内部查询获取真正的最大日期并连接到日期小于的外部查询(pb.effective_date < pb2.dte
)。然后外部查询最大化日期,现在是第二高的,因为我们知道它小于真正的最大值。我编辑了答案并在我认为您需要的地方添加了连接条件。【参考方案2】:
考虑一个相关的计数子查询来产生一个row_num,稍后用于选择组中的第二行。
SELECT main.ms_code,
main.location_code,
main.mfg_code,
main.group_code,
main.stock_id,
main.effective_date,
main.price
FROM
(SELECT t.ms_code,
t.location_code,
t.mfg_code,
t.group_code,
t.stock_id,
t.effective_date,
t.price,
(SELECT COUNT(*) FROM dbo.PRICE_BOOK sub
WHERE sub.ms_code = t.ms_code
AND sub.location_code = t.location_code
AND sub.mfg_code = t.mfg_code
AND sub.group_code = t.group_code
AND sub.stock_id = t.stock_id
AND sub.effective_date >= t.effective_date) AS row_num
FROM dbo.PRICE_BOOK t) AS main
WHERE main.row_num = 2;
【讨论】:
【参考方案3】:使用 MS SQL。这将选择第二个最近的日期。我假设 dbo.PRICE_BOOK.effective_date 是日期字段。
SELECT * FROM
(SELECT
dbo.PRICE_BOOK.ms_code,
dbo.PRICE_BOOK.location_code,
dbo.PRICE_BOOK.mfg_code,
dbo.PRICE_BOOK.group_code,
dbo.PRICE_BOOK.stock_id,
dbo.PRICE_BOOK.effective_date,
ROW_NUMBER() OVER (ORDER BY dbo.PRICE_BOOK.effective_date) AS ROWNUM,
dbo.PRICE_BOOK.price
FROM dbo.PRICE_BOOK
ORDER BY dbo.PRICE_BOOK.effective_date DESC
) AS TEMP
WHERE ROWNUM = MAX(ROWNUM)-1
GROUP BY ms_code,
location_code,
mfg_code,
group_code,
stock_id,
effective_date,
ROWNUM,
price
【讨论】:
问题是“我正在通过 microsoft 查询在 excel 中执行此任务,因此无法使用 row_number()。” MS查询中也不能使用OVER 还有其他想法吗? 确实 MS SQL Query 使用 JET/ACE SQL 引擎(MS Access 数据库),这是一种不同于 MS SQL Server 的方言。以上是关于SQL 组行选择的主要内容,如果未能解决你的问题,请参考以下文章