【问题标题】:SQL Group Row SelectionSQL 组行选择
【发布时间】: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

提前致谢。

【问题讨论】:

    标签: sql excel microsoft-query


    【解决方案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 &lt; 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 的方言。
      猜你喜欢
      • 1970-01-01
      • 2013-06-14
      • 1970-01-01
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      • 2018-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多