在SQL中对连续数值的序数编号

huangapple go评论68阅读模式
英文:

Ordinal number on consequent values in SQL

问题

我有这样的表格:

        WITH DATA AS (
          SELECT 45 AS user_id, '2023-07-15' AS date, true AS had_session
          UNION ALL
          SELECT 45, '2023-07-16', false
          UNION ALL
          SELECT 45, '2023-07-17', true
          UNION ALL
          SELECT 45, '2023-07-18', true
          UNION ALL
          SELECT 45, '2023-07-19', true
          UNION ALL
          SELECT 45, '2023-07-20', false
          UNION ALL
          SELECT 45, '2023-07-21', true
          UNION ALL
          SELECT 45, '2023-07-22', true
          UNION ALL
          SELECT 45, '2023-07-23', false
          UNION ALL
          SELECT 45, '2023-07-24', false
          UNION ALL
          SELECT 45, '2023-07-25', false
          UNION ALL
          SELECT 45, '2023-07-26', false
        )
        SELECT *,
               -- ordinal number subquery AS consequente_counter
          FROM DATA
      ORDER BY date

我想要添加一列,其中包含真和假的序数。每当与前一日期的值相比发生变化时,数字将从1开始。由于要求,这必须在标准SQL中完成,不能使用游标或存储过程。

示例

user_id date had_session consequente_number
1126373 7/15/2023 TRUE 1
1126373 7/16/2023 FALSE 1
1126373 7/17/2023 TRUE 1
1126373 7/18/2023 TRUE 2
1126373 7/19/2023 TRUE 3
1126373 7/20/2023 FALSE 1
1126373 7/21/2023 TRUE 1
1126373 7/22/2023 TRUE 2
1126373 7/23/2023 FALSE 1
1126373 7/24/2023 FALSE 2
1126373 7/25/2023 FALSE 3
1126373 7/26/2023 FALSE 4

结果的图像

英文:

I have table like this:

        WITH DATA AS (
          SELECT 45 AS user_id, '2023-07-15' AS date, true AS had_session
          UNION ALL
          SELECT 45, '2023-07-16', false
          UNION ALL
          SELECT 45, '2023-07-17', true
          UNION ALL
          SELECT 45, '2023-07-18', true
          UNION ALL
          SELECT 45, '2023-07-19', true
          UNION ALL
          SELECT 45, '2023-07-20', false
          UNION ALL
          SELECT 45, '2023-07-21', true
          UNION ALL
          SELECT 45, '2023-07-22', true
          UNION ALL
          SELECT 45, '2023-07-23', false
          UNION ALL
          SELECT 45, '2023-07-24', false
          UNION ALL
          SELECT 45, '2023-07-25', false
          UNION ALL
          SELECT 45, '2023-07-26', false
        )
        SELECT *,
               -- ordinal number subquery AS consequente_counter
          FROM DATA
      ORDER BY date

I want to add one more column which will contain ordinal numbers for true and false. The number will start from 1 whenever the value is changed compared to the value of the previous date. Due to requirements, this has to be done in standard SQL, without using cursors or stored procedures.

Example

user_id date had_session consequente_number
1126373 7/15/2023 TRUE 1
1126373 7/16/2023 FALSE 1
1126373 7/17/2023 TRUE 1
1126373 7/18/2023 TRUE 2
1126373 7/19/2023 TRUE 3
1126373 7/20/2023 FALSE 1
1126373 7/21/2023 TRUE 1
1126373 7/22/2023 TRUE 2
1126373 7/23/2023 FALSE 1
1126373 7/24/2023 FALSE 2
1126373 7/25/2023 FALSE 3
1126373 7/26/2023 FALSE 4

Image of the results

答案1

得分: 0

使用以下方法(BigQuery标准SQL)

SELECT * EXCEPT(reset, grp), 
  ROW_NUMBER() OVER(PARTITION BY user_id, grp ORDER BY date) AS consequente_counter
FROM (
  SELECT *, COUNTIF(reset) OVER(PARTITION BY user_id ORDER BY date) grp
  FROM (
    SELECT *,
      IFNULL(had_session != LAG(had_session) OVER(PARTITION BY user_id ORDER BY date), TRUE) reset 
    FROM DATA
  )
)
ORDER BY date

如果应用于你问题中的示例数据 - 输出如下:

在SQL中对连续数值的序数编号

英文:

Use below approach (BigQuery Standard SQL)

SELECT * EXCEPT(reset, grp), 
ROW_NUMBER() OVER(PARTITION BY user_id, grp ORDER BY date) AS consequente_counter
FROM (
SELECT *, COUNTIF(reset) OVER(PARTITION BY user_id ORDER BY date) grp
FROM (
SELECT *,
IFNULL(had_session != LAG(had_session) OVER(PARTITION BY user_id ORDER BY date), TRUE) reset 
FROM DATA
)
)
ORDER BY date

If applied to sample data in your question - output is

在SQL中对连续数值的序数编号

huangapple
  • 本文由 发表于 2023年7月28日 02:15:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76782450.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定