【问题标题】:Select the most recent distinct records of a two column pair选择两列对的最新不同记录
【发布时间】:2017-05-04 23:07:59
【问题描述】:

要求:

我需要从[PriceChanges] 中选择[SKU][Store][Cost][Retail] 作为每个不同的([SKU][Store])组合之一,其中[Date] 是最新的(不超过 2017-04-25)和[Flag]=0。我也只想选择[PriceChanges] 记录,其中[Dept]=100 由通过[SKU] 加入[Items] 确定。

以下是我的表中的一些经过混淆的示例数据,但实际上我希望在我的结果集中提取大约 200 万条唯一记录。

[PriceChanges](示例):

+--------+-------+--------+--------+------------+------+
|  SKU   | Store |  Cost  | Retail |    Date    | Flag |
+--------+-------+--------+--------+------------+------+
| 999999 |  1000 | 4.0850 | 4.09   | 2017-04-19 | 0    |
| 999998 |  1001 | 4.0850 | 4.09   | 2017-04-19 | 1    |
| 999999 |  1000 | 4.0650 | 4.07   | 2017-04-18 | 2    |
+--------+-------+--------+--------+------------+------+

[Items](示例):

+--------+------+
|  SKU   | Dept |
+--------+------+
| 999999 |  100 |
| 999998 |  101 |
+--------+------+

我目前的解决方案:

SELECT s.[SKU],
     s.[Store],
     [Cost],
     [Retail]
FROM [PriceChanges]  s
    RIGHT JOIN
(
   SELECT [SKU],
        [Store],
        [MaxDate] = MAX([Date])
   FROM [PriceChanges]
       LEFT JOIN [Items] ON [PriceChanges].[SKU] = [Items].[SKU]
                                                 AND [Date] < '2017-04-25'
                                                 AND [Dept] = 100
                                                 AND [Flag] = 0
   GROUP BY [SKU],
          [Store]
) m ON m.[SKU] = s.[SKU]
     AND m.[Store] = s.[Store]
     AND m.[MaxDate] = s.[Date];

上述解决方案似乎不起作用,因为根据我们拥有的不同 SKU 和商店的数量,它返回的记录比我预期的多 40%。编写此查询的最有效方法是什么?

【问题讨论】:

  • 请发布所需的结果,并告诉我们您使用的是哪个版本的 sql-server。
  • 请根据您的样本数据使用样本预期结果更新您的问题。您可能想要添加一些额外的示例数据来演示一些边缘情况。例如,是否存在同一个(SKU/商店)组合可以有多个标记为 0 的行的情况?
  • 谢谢@vkp 和@pmbAustin。我正在出门,但会在几个小时内尝试更新您的建议。

标签: sql sql-server


【解决方案1】:

如果您肯定只希望 SKU 和商店返回一行,则可以使用以下查询:

SELECT
   [SKU]
  ,[Store]
  ,[Cost]
  ,[Retail]
FROM (
  SELECT
     p.[SKU]
    ,p.[Store]
    ,p.[Cost]
    ,p.[Retail]
    ,ROW_NUMBER() OVER (PARTITION BY p.[SKU], p.[Store] ORDER BY p.[Date] DESC) as ranker
  FROM [PriceChanges] p
  JOIN [Items] i
    ON p.[SKU] = i.[SKU]
  WHERE 1=1
    AND i.[Dept] = 100
    AND p.[Flag] = 0
    AND p.[Date] < '2017-04-25'
) T
WHERE 1=1
  AND ranker = 1

【讨论】:

【解决方案2】:

试试这个,

SELECT [SKU],
     [Store],
     [Cost],
     [Retail]
FROM
(
   SELECT [SKU],
        [Store],
        [Cost],
        [Retail],
        ROW_NUMBER() OVER(PARTITION BY [SKU],
                                 [Store] ORDER BY [Date] DESC) rn
   FROM PriceChanges PC
   WHERE [Date] <= '2017-04-25'
        AND [Flag] = 0
        AND EXISTS
   (
      SELECT [SKU]
      FROM [Items] i
      WHERE pc.[SKU] = i.[SKU]
           AND [DEPT] = 100
   )
) t4
WHERE rn = 1;

【讨论】:

  • 谢谢,@KumarHarsh。这看起来也很有效(看起来与 Josh 的回答非常相似)。
  • 不,它不相似。我正在使用“Exists”子句。检查性能。
  • 你是对的。我看到您的回答比 Josh 的回答提高了大约 31%。不过,您的答案确实有几个错别字。我刚刚提交了一个编辑来修复它们。如果获得批准,我将切换我接受的答案。
猜你喜欢
  • 1970-01-01
  • 2019-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-29
  • 2015-04-17
相关资源
最近更新 更多