RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1437983
Accepted
another_login
another_login
Asked:2022-08-10 15:16:39 +0000 UTC2022-08-10 15:16:39 +0000 UTC 2022-08-10 15:16:39 +0000 UTC

采样重复序列的初始值

  • 772

我在获取数据时遇到了问题。这里有张桌子:

| ID |                 DDATE | STATUS |
|----|-----------------------|--------|
|  1 | 2000-01-01 01:00:00.0 | aaaaaa |
|  1 | 2000-01-01 02:00:00.0 | aaaaaa |
|  1 | 2000-01-01 03:00:00.0 | aaaaaa |
|  1 | 2000-01-01 04:00:00.0 | aaaaaa |
|  1 | 2000-02-01 05:00:00.0 | bbbbbb |
|  1 | 2000-02-01 06:00:00.0 | cccccc |
|  1 | 2000-02-01 07:00:00.0 | cccccc |
|  1 | 2000-02-01 08:00:00.0 | bbbbbb |
|  1 | 2000-02-01 09:00:00.0 | cccccc |
|  1 | 2000-02-01 10:00:00.0 | cccccc |
|  1 | 2000-02-01 11:00:00.0 | cccccc |
|  1 | 2000-02-01 12:00:00.0 | dddddd |
|  2 | 2000-01-01 13:00:00.0 | aaaaaa |
|  2 | 2000-02-01 14:00:00.0 | aaaaaa |
|  2 | 2000-02-01 15:00:00.0 | aaaaaa |
|  2 | 2000-02-01 16:00:00.0 | aaaaaa |
|  2 | 2000-03-01 17:00:00.0 | bbbbbb |
|  2 | 2000-03-01 18:00:00.0 | cccccc |
|  2 | 2000-03-01 19:00:00.0 | cccccc |
|  2 | 2000-04-01 20:00:00.0 | bbbbbb |
|  2 | 2000-04-01 21:00:00.0 | cccccc |
|  2 | 2000-04-01 22:00:00.0 | cccccc |
|  2 | 2000-04-01 23:00:00.0 | cccccc |
|  2 | 2000-04-01 23:30:00.0 | dddddd |

您需要获取每个 id 的每个状态序列的第一条(及时)记录:

| ID |                 DDATE | STATUS |
|----|-----------------------|--------|
|  1 | 2000-01-01 01:00:00.0 | aaaaaa |
|  1 | 2000-02-01 05:00:00.0 | bbbbbb |
|  1 | 2000-02-01 06:00:00.0 | cccccc |
|  1 | 2000-02-01 08:00:00.0 | bbbbbb |
|  1 | 2000-02-01 09:00:00.0 | cccccc |
|  1 | 2000-02-01 12:00:00.0 | dddddd |
|  2 | 2000-01-01 13:00:00.0 | aaaaaa |
|  2 | 2000-03-01 17:00:00.0 | bbbbbb |
|  2 | 2000-03-01 18:00:00.0 | cccccc |
|  2 | 2000-04-01 20:00:00.0 | bbbbbb |
|  2 | 2000-04-01 21:00:00.0 | cccccc |
|  2 | 2000-04-01 23:30:00.0 | dddddd |

我设法只获得每个 id 的第一个状态,而丢失了重复:

SELECT ID, MIN(DDATE) dd, STATUS FROM Table1
GROUP BY ID, STATUS
ORDER BY ID, dd

请至少告诉我方向。

UPD:可重现的示例http://sqlfiddle.com/#!4/3de9e/1/0。

sql oracle
  • 2 2 个回答
  • 59 Views

2 个回答

  • Voted
  1. Andrew Nikolaev
    2022-08-10T18:02:49Z2022-08-10T18:02:49Z

    为了避免重复,这里只做一个查询是不够的,你需要一个循环。我试图在 PL\SQL 中实现这一点,但不知何故,由于缺乏经验,我遇到了很多错误。我用TSQL写了一个概念,如果我能把它翻译成Oracle,那么一切都会如其所愿

    -- Это исходная таблица
    CREATE TABLE #Table1 (ID INT, DDATE DATETIME, SSTATUS VARCHAR(255))
    
    INSERT #Table1 (ID, DDATE, SSTATUS) VALUES
    (  1 , '2000-01-01 01:00:00.0' , 'aaaaaa'),
    (  1 , '2000-01-01 02:00:00.0' , 'aaaaaa'),
    (  1 , '2000-01-01 03:00:00.0' , 'aaaaaa'),
    (  1 , '2000-01-01 04:00:00.0' , 'aaaaaa'),
    (  1 , '2000-02-01 05:00:00.0' , 'bbbbbb'),
    (  1 , '2000-02-01 06:00:00.0' , 'cccccc'),
    (  1 , '2000-02-01 07:00:00.0' , 'cccccc'),
    (  1 , '2000-02-01 08:00:00.0' , 'bbbbbb'),
    (  1 , '2000-02-01 09:00:00.0' , 'cccccc'),
    (  1 , '2000-02-01 10:00:00.0' , 'cccccc'),
    (  1 , '2000-02-01 11:00:00.0' , 'cccccc'),
    (  1 , '2000-02-01 12:00:00.0' , 'dddddd'),
    (  2 , '2000-01-01 13:00:00.0' , 'aaaaaa'),
    (  2 , '2000-02-01 14:00:00.0' , 'aaaaaa'),
    (  2 , '2000-02-01 15:00:00.0' , 'aaaaaa'),
    (  2 , '2000-02-01 16:00:00.0' , 'aaaaaa'),
    (  2 , '2000-03-01 17:00:00.0' , 'bbbbbb'),
    (  2 , '2000-03-01 18:00:00.0' , 'cccccc'),
    (  2 , '2000-03-01 19:00:00.0' , 'cccccc'),
    (  2 , '2000-04-01 20:00:00.0' , 'bbbbbb'),
    (  2 , '2000-04-01 21:00:00.0' , 'cccccc'),
    (  2 , '2000-04-01 22:00:00.0' , 'cccccc'),
    (  2 , '2000-04-01 23:00:00.0' , 'cccccc'),
    (  2 , '2000-04-01 23:30:00.0' , 'dddddd')
    
    -- Это промежуточная таблица с полем IDENTITY (AUTO_INCREMENT) с отсортированными данными по ID и DDATE
    CREATE TABLE #Table2 (RowNum INT IDENTITY, ID INT, DDATE DATETIME, SSTATUS VARCHAR(255))
    
    INSERT INTO #Table2 (ID, DDATE, SSTATUS)
    SELECT t.ID, t.DDATE, t.SSTATUS FROM #Table1 t ORDER BY t.ID, t.DDATE
    
    -- Результирующая таблица
    CREATE TABLE #Table3 (ID INT, DDATE DATETIME, SSTATUS VARCHAR(255))
    
    DECLARE @CurrentRowNum INT
    DECLARE @CurrentId INT = NULL
    DECLARE @CurrenDate DATETIME = NULL
    DECLARE @CurrentStatus VARCHAR(255) = NULL
    
    DECLARE @OldId INT = NULL
    DECLARE @OldStatus VARCHAR(255) = NULL
    
    -- Начнём с минимальной записи, ей будет соответствовать 
    -- пара минимального ID и DDATE
    SELECT @CurrentRowNum = MIN(RowNum) FROM #Table2 t
    
    -- Циклом бежим по всем записям, пока не кончатся
    WHILE @CurrentRowNum IS NOT NULL
    BEGIN
        SELECT
            @CurrentId = t.ID,
            @CurrenDate = t.DDATE,
            @CurrentStatus = t.SSTATUS 
        FROM #Table2 t
        WHERE t.RowNum = @CurrentRowNum
        
        -- Ищем различие с предыдущей записью по ID или по STATUS
        IF @CurrentId <> ISNULL(@OldId, 0) OR @CurrentStatus <> ISNULL(@OldStatus, '')
        BEGIN
            INSERT #Table3 (ID, DDATE, SSTATUS) SELECT @CurrentId, @CurrenDate, @CurrentStatus
            
            SELECT
                @OldId = @CurrentId,
                @OldStatus = @CurrentStatus 
        END
        
        SELECT @CurrentRowNum = MIN(RowNum) FROM #Table2 t WHERE t.RowNum > @CurrentRowNum
    END
    
    -- Выводим необходимый результат
    SELECT * FROM #Table3 t ORDER BY t.ID, t.DDATE
    
    DROP TABLE #Table1
    DROP TABLE #Table2
    DROP TABLE #Table3
    

    但是一个请求的解决方案,我在 Oracle g12 上检查了它,一切正常:

    SELECT 
        SQ3.ID,
        SQ3.DDATE,
        SQ3.SSTATUS
    FROM 
    (
        SELECT  
            (CASE WHEN SQ.RowNumber = 1 THEN SQ.ID ELSE SQ2.ID END) AS ID,
            (CASE WHEN SQ.RowNumber = 1 THEN SQ.DDATE ELSE SQ2.DDATE END) AS DDATE,
            (CASE WHEN SQ.RowNumber = 1 THEN SQ.SSTATUS ELSE SQ2.SSTATUS END) AS SSTATUS,
            (CASE WHEN (SQ.SSTATUS <> SQ2.SSTATUS) OR SQ.RowNumber = 1 THEN 1 ELSE 0  END) AS IsChangeStatus
        FROM
        (
            SELECT 
                ROW_NUMBER() OVER ( ORDER BY t1.ID, t1.DDATE ) AS RowNumber, 
                t1.* 
            FROM Table1 t1
        ) SQ
        LEFT JOIN 
        (
            SELECT 
                ROW_NUMBER() OVER ( ORDER BY t1.ID, t1.DDATE ) AS RowNumber,
                t1.* 
            FROM Table1 t1   
        ) SQ2 ON SQ.RowNumber + 1 = SQ2.RowNumber
     ) SQ3
     WHERE SQ3.IsChangeStatus = 1
     ORDER BY SQ3.ID, SQ3.DDATE
    
    • 2
  2. Best Answer
    another_login
    2022-08-10T23:56:36Z2022-08-10T23:56:36Z

    决定这样:

    我创建了一个中间表,对所有行Table1进行编号(对行进行编号时,按 id 和日期排序):

    CREATE TABLE TABLE2 (
      "RowNum" NUMBER GENERATED ALWAYS AS IDENTITY (
      MAXVALUE 1000),
      ID       NUMBER,
      DDATE    DATE,
      SSTATUS  NVARCHAR2(50)
    );
    
    INSERT INTO TABLE2 (ID, DDATE, SSTATUS)
    SELECT ID, DDATE, SSTATUS FROM Table1 ORDER BY ID, DDATE;
    

    然后我创建了一个空的 TABLE3:

    CREATE TABLE TABLE3 (
      ID       NUMBER,
      DDATE    DATE,
      SSTATUS  NVARCHAR2(50)
    );
    

    在循环中,我在那里插入了必要的行:

    DECLARE
      laststatus VARCHAR2(50) := 'st';
      currentst VARCHAR2(50);
      currentid NUMBER;
      currentdate DATE;
    
    BEGIN
      FOR i IN 1..74 -- тут костыль на моё количество строк в TABLE2
      LOOP
        BEGIN
          SELECT ID, DDATE, SSTATUS INTO currentid, currentdate, currentst FROM TABLE2 WHERE "RowNum" = i;
          IF currentst != laststatus THEN
            INSERT INTO TABLE3 (ID, DDATE, SSTATUS) VALUES (currentid, currentdate, currentst);
          END IF;
        END;
        laststatus := currentst;
      END LOOP;
    END;
    
    • 0

相关问题

  • 通过 OUT 参数从过程结果输出

  • ON 关键字附近的语法错误 - SQL

  • 多表查询中的 Count() 聚合函数

  • 根据时间更改单元格中的日期

  • phpMyAdmin 中的错误 #1064 SQL 查询

  • Qt:包含变量的数据库查询

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5