【问题标题】:SQL get only earlier date in repetitive rowsSQL 仅获取重复行中的较早日期
【发布时间】:2021-07-02 03:51:25
【问题描述】:

我有一个 SQL 表包含这样的事务

ID | FK | STATUS | DATE

1  | A  | K1     | 2021-01-01
2  | A  | K1     | 2021-01-15
3  | A  | K2     | 2021-01-30
4  | A  | K2     | 2021-02-03
5  | B  | K1     | 2021-01-12
6  | C  | K1     | 2021-03-30
7  | C  | K3     | 2021-09-15

我们可以看到,一些 FK 有一些不同 STATUS 和不同 DATE 的记录。我想从每个 FK 获取状态为 K1 的第一个/更早的交易日期。

可能是这样的。

ID | FK | STATUS | DATE
1  | A  |   K1   | 2021-01-01
5  | B  |   K1   | 2021-01-12
6  | C  |   K1   | 2021-03-30

我怎样才能得到这样的结果?

注意:我使用的是 MariaDB 版本 10.5.9-MariaDB

【问题讨论】:

  • 您在上面的英文语句中的“and”是模棱两可的。 “来自每个 FK 的状态 = K1 或更早的交易”是什么意思?
  • 原谅我,我已经编辑了问题..
  • @Iwan 共享更新的样本数据,您的预期结果也将更新。 ID 4 将更改为 5,ID 5 将更改为 6

标签: mysql sql mariadb


【解决方案1】:
CREATE TABLE my_table (
  `ID` INTEGER,
  `FK` VARCHAR(1),
  `STATUS` VARCHAR(2),
  `DATE` DATETIME
);

INSERT INTO my_table
  (`ID`, `FK`, `STATUS`, `DATE`)
VALUES
  ('1', 'A', 'K1', '2021-01-01'),
  ('2', 'A', 'K1', '2021-01-15'),
  ('3', 'A', 'K2', '2021-01-30'),
  ('4', 'A', 'K2', '2021-02-03'),
  ('5', 'B', 'K1', '2021-01-12'),
  ('6', 'C', 'K1', '2021-03-30'),
  ('7', 'C', 'K3', '2021-09-15');

查询 #1

SELECT 
    ID, 
    FK, 
    STATUS, 
    DATE 
FROM (
    SELECT 
        *, 
        row_number() over (partition by FK,STATUS order by DATE ASC) rn from my_table 
) t
where STATUS='K1' and rn=1;
ID FK STATUS DATE
1 A K1 2021-01-01 00:00:00
5 B K1 2021-01-12 00:00:00
6 C K1 2021-03-30 00:00:00

View on DB Fiddle

【讨论】:

  • 有些 FK 有一些 STATUS = K1 相同但日期不同的记录。我只想获得日期较早的 K1
  • 如果K1 在该日期不是 FK 的第一行怎么办?
【解决方案2】:
WITH cte_customers AS (
    SELECT 
        ROW_NUMBER() OVER(PARTITION BY fk,status
             ORDER BY 
date
                
        ) row_num, 
        customer_id, 
        fk, 
        status
     FROM 
        sales.customers
) SELECT 
    *
FROM 
    cte_customers
WHERE 
    row_num =1;

【讨论】:

  • 这是一个 sql server 查询检查你是否能够在 Mariadb 中做类似的事情
【解决方案3】:

这可以通过windowing function 解决:

WITH RowNumbers AS (
    SELECT *, 
        row_number() OVER (PARTITION BY FK ORDER BY Date) As rn
    FROM [MyTable]
    WHERE Status = 'K1'
)
SELECT ID, FK, STATUS, DATE
FROM RowNumbers
WHERE rn = 1

MariaDB 10.2 版本中添加了窗口函数。还需要 CTE,因为在处理 WHERE 子句之后 才会计算 row_number()。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 2012-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多