【问题标题】:Firebird Query- Return first row each groupFirebird Query-返回每组的第一行
【发布时间】:2016-05-03 20:42:57
【问题描述】:

在带有“销售”表的 firebird 数据库中,我需要选择所有客户的第一次销售。请参阅下面的示例,该示例显示了表格和所需的查询结果。

---------------------------------------
SALES
---------------------------------------
ID  CUSTOMERID  DTHRSALE
1   25          01/04/16 09:32
2   30          02/04/16 11:22      
3   25          05/04/16 08:10
4   31          07/03/16 10:22
5   22          01/02/16 12:30
6   22          10/01/16 08:45

结果:仅限首次销售,基于销售日期。

ID  CUSTOMERID  DTHRSALE
1   25          01/04/16 09:32
2   30          02/04/16 11:22      
4   31          07/03/16 10:22
6   22          10/01/16 08:45

我已经测试了下面的代码“Select first row in each GROUP BY group?”,但是没有用。

【问题讨论】:

    标签: sql firebird greatest-n-per-group firebird2.5


    【解决方案1】:

    在 Firebird 2.5 中,您可以使用以下查询来执行此操作;这是对 the accepted answer of the question you linked to 第二部分的小修改,根据您的架构和要求量身定制:

    select   x.id,
             x.customerid, 
             x.dthrsale
        from sales x
        join (select customerid,
                     min(dthrsale) as first_sale
                from sales 
            group by customerid) p on p.customerid = x.customerid
                                  and p.first_sale = x.dthrsale
    order by x.id
    

    order by 不是必需的,我只是添加它以使其按照您的问题显示的顺序。

    使用 Firebird 3,您可以使用窗口函数 ROW_NUMBER,链接答案中也对此进行了描述。链接的答案错误地表示第一个解决方案适用于 Firebird 2.1 及更高版本。我现在已经编辑了它。

    【讨论】:

      【解决方案2】:

      这么简单:

      按 CUSTOMERID 从 SALES 组中选择 CUSTOMERID min(DTHRSALE)

      【讨论】:

        【解决方案3】:

        搜索之前没有销售的销售:

        SELECT S1.*
        FROM SALES S1
        LEFT JOIN SALES S2 ON S2.CUSTOMERID = S1.CUSTOMERID AND S2.DTHRSALE < S1.DTHRSALE
        WHERE S2.ID IS NULL
        

        在 (customerid, dthrsale) 上定义一个索引以加快速度。

        【讨论】:

          【解决方案4】:

          在 Firebird 3 中,通过 min sales_date 获取每个客户的第一行:

          SELECT id, customer_id, total, sales_date
          FROM   (
             SELECT id, customer_id, total, sales_date
                  , row_number() OVER(PARTITION BY customer_id ORDER BY sales_date ASC ) AS rn
             FROM   SALES
             ) sub
          WHERE  rn = 1;
          

          İ如果您想获取其他相关列,这是您的自我回答失败的地方。

          select customer_id , min(sales_date) 
                     , id, total  --what about other colums
          from SALES
          group by customer_id
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-06-03
            • 1970-01-01
            • 1970-01-01
            • 2016-01-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多