选择具有 MAX(Date) 但没有得到明显回报的记录
Posted
技术标签:
【中文标题】选择具有 MAX(Date) 但没有得到明显回报的记录【英文标题】:Select records with a MAX(Date) but don't get distinct return 【发布时间】:2013-07-29 08:14:53 【问题描述】:我正在加入表格,我的代码如下所示:
SELECT P.*
FROM (
SELECT ABC.StockCode
,ABC.Supplier
,ABC.Price
,MAX(ABC.OrigReceiptDate) ReceiptDate
FROM (
SELECT GRND.StockCode
,GRND.Supplier
,OrigReceiptDate
,(GRND.OrigGrnValue / GRND.QtyReceived) AS Price
FROM [SysproCompanyR].[dbo].[GrnDetails] GRND
WHERE QtyReceived > 0
) ABC
GROUP BY ABC.StockCode
,ABC.Supplier
,ABC.Price
) P
WHERE P.StockCode IN (
SELECT StockCode
FROM [SysproCompanyR].[dbo].[InvMaster]
)
ORDER BY P.StockCode
,P.Price
然而结果集是:
我的问题是我需要获取最新购买的股票代码及其价格...但是由于价格不同,我得到了重复的值,以帮助金发女郎>
【问题讨论】:
【参考方案1】:试试这个:
WITH CTE
AS
(
SELECT
ABC.StockCode,
ABC.Supplier,
ABC.Price,
ABC.OrigReceiptDate AS ReceiptDate,
ROW_NUMBER() OVER(PARTITION BY ABC.Supplier
ORDER BY ABC.OrigReceiptDate DESC) AS RN
FROM
(
SELECT GRND.StockCode, GRND.Supplier,OrigReceiptDate,
(GRND.OrigGrnValue /GRND.QtyReceived) as Price
FROM [SysproCompanyR].[dbo].[GrnDetails] GRND
Where QtyReceived > 0
) AS ABC
INNER JOIN [SysproCompanyR].[dbo].[InvMaster] AS m
ON ABC.StockCode = m.StockCode
)
SELECT
StockCode,
Supplier,
Price,
ReceiptDate
FROM CTE
WHERE RN = 1;
这应该为您提供每个供应商最近购买的股票代码及其价格。
【讨论】:
您的 RowNumber 部分不会创建我见过的唯一行号,所以我有多个具有相同编号的 RN 列不知道这是否会发生...... @user1546143, 是的,这是因为PARTITION BY ABC.Supplier
每个供应商都有其顺序取决于日期的排序,例如供应商 0203004 将具有从 1 到 n ,然后 0204260
将具有从 1 到 n 按日期降序排列,过滤器 WHERE RN = 1
将消除所有并保留第一个为最大日期。你试过了吗?
嗨,是的,我有,但是我的重复结果返回大约 3600 条记录,而你的只返回 154 条,但在我的返回列表中,我有你没有的股票代码...
@user1546143 你可能想partition by
股票代码,而不是供应商。
@user1546143 - 能否请您发布一些示例数据和所需的输出,请不要轻易处理图片,这将非常有帮助。【参考方案2】:
在 WHERE 子句中使用 EXISTS 和相关子查询的更多选项
SELECT P.*
FROM (
SELECT GRND.StockCode, GRND.Supplier, GRND.OrigReceiptDate, (GRND.OrigGrnValue / GRND.QtyReceived) AS Price
FROM [SysproCompanyR].[dbo].[GrnDetails] AS GRND
WHERE QtyReceived > 0
) P
WHERE P.StockCode IN (
SELECT StockCode
FROM [SysproCompanyR].[dbo].[InvMaster]
)
AND EXISTS(
SELECT 1
FROM [SysproCompanyR].[dbo].[GrnDetails] AS GRND2
WHERE GRND.StockCode = GRND2.StockCode
AND GRND.Supplier = GRND2.Supplier
HAVING MAX(GRND2.OrigReceiptDate) = GRND.OrigReceiptDate
)
ORDER BY P.StockCode, P.Price
【讨论】:
【参考方案3】:我相信这种形式的查询更容易理解并且易于维护:
;WITH ABC AS (
SELECT
GRND.StockCode,
GRND.Supplier,
OrigReceiptDate,
Price = (GRND.OrigGrnValue / GRND.QtyReceived),
FROM [SysproCompanyR].[dbo].[GrnDetails] GRND
WHERE QtyReceived > 0
),
P AS (
SELECT
ABC1.StockCode,
lastOne.Supplier,
lastOne.Price,
ReceiptDate = lastOne.OrigReceiptDate
FROM
(SELECT DISTINCT StockCode FROM ABC) ABC1
CROSS APPLY(
SELECT TOP 1
Supplier,
Price,
OrigReceiptDate
FROM ABC
WHERE StockCode = ABC1.StockCode
ORDER BY OrigReceiptDate DESC
) lastOne
)
SELECT *
FROM P
WHERE
StockCode IN (
SELECT StockCode
FROM [SysproCompanyR].[dbo].[InvMaster])
ORDER BY
StockCode,
Price
【讨论】:
感谢@Mahmoud Gamal 的快速回复,这很有效,但由于某种原因,它遗漏了很多股票代码。我的结果重复返回大约 3600 条记录,而你的只返回 154 条记录,但在我的返回列表我有你没有的股票代码...@Ozren 它抱怨 olumn 'lastOne.Supplier' 在选择列表中无效,因为它既不包含在聚合函数或 GROUP BY 子句中。猜猜它需要按类分组中的那一列【参考方案4】:我认为你可以这样做:
SELECT a.*
FROM( SELECT StockCode,
Supplier,
OrigGrnValue/QtyReceived) AS Price,
OrigReceiptDate AS ReceiptDate
ROW_NUMBER() OVER (PARTITION BY StockCode, Supplier, OrigGrnValue/QtyReceived ORDER BY OrigReceiptDate DESC) as rown
FROM GrnDetails
WHERE QtyReceived > 0 ) a
WHERE a.rown = 1
AND a.StockCode EXISTS (SELECT StockCode
FROM [SysproCompanyR].[dbo].[InvMaster] m
WHERE m.StockCode = a.StockCode)
ORDER BY a.StockCode,
a.Price
【讨论】:
以上是关于选择具有 MAX(Date) 但没有得到明显回报的记录的主要内容,如果未能解决你的问题,请参考以下文章