开发者社区 问答 正文

根据给定的输入获取上一个和下一个数据

我有带有示例数据的下表:

DummyData

CREATE TABLE DummyData
(
    ID int,
    Dates_Range VARCHAR(50)
);

样本数据:

INSERT INTO DummyData VALUES(1,'2019-01-01');
INSERT INTO DummyData VALUES(1,'2019-01-02');
INSERT INTO DummyData VALUES(1,'2019-01-03');
INSERT INTO DummyData VALUES(NULL,'2019-01-04 - 2019-02-01');
INSERT INTO DummyData VALUES(1,'2019-02-02');

INSERT INTO DummyData VALUES(2,'2019-01-06');
INSERT INTO DummyData VALUES(NULL,'2019-01-07');
INSERT INTO DummyData VALUES(2,'2019-01-08');
INSERT INTO DummyData VALUES(2,'2019-01-09');

INSERT INTO DummyData VALUES(3,'2019-01-02');
INSERT INTO DummyData VALUES(3,'2019-01-03');
INSERT INTO DummyData VALUES(NULL,'2019-01-04 - 2019-01-09');
INSERT INTO DummyData VALUES(3,'2019-01-10');

查询:我需要查找NULLID 之前和之后的n个数字数据。

例如1:我需要从NULLID 之前和之后找到1个数据,然后输出将是:

ID      DRange
-------------------------------
1       2019-01-03
NULL    2019-01-04 - 2019-02-01
1       2019-02-02
2       2019-01-06 
NULL    2019-01-07
2       2019-01-08
3       2019-01-03
NULL    2019-01-04 - 2019-01-09
3       2019-01-10

例如2:我需要在NULLID 前后找到2个数据,然后输出将是:

ID      DRange
-------------------------------
1       2019-01-02
1       2019-01-03
NULL    2019-01-04 - 2019-02-01
1       2019-02-02
2       2019-01-06 
NULL    2019-01-07
2       2019-01-08
2       2019-01-09
3       2019-01-02
3       2019-01-03
NULL    2019-01-04 - 2019-01-09
3       2019-01-10

例如3:我需要从NULLID 之前和之后找到3个数据,然后输出将是:

ID      DRange
-------------------------------
1       2019-01-01
1       2019-01-02
1       2019-01-03
NULL    2019-01-04 - 2019-02-01
1       2019-02-02
2       2019-01-06 
NULL    2019-01-07
2       2019-01-08
2       2019-01-09
3       2019-01-02
3       2019-01-03
NULL    2019-01-04 - 2019-01-09
3       2019-01-10

展开
收起
心有灵_夕 2019-12-10 17:25:30 623 分享 版权
阿里云 AI 助理回答

要实现这个查询,你可以使用窗口函数LEADLAG来获取NULL ID前后指定数量的行。但是,由于你想要基于NULL值动态地选择前后的行数,这需要更复杂的逻辑,可能涉及到自定义函数或者多层子查询。这里提供一个简化版的SQL示例,它适用于固定数量(例如例子中的1个、2个或3个)的情况。对于动态数量的需求,你可能需要在应用层面处理。

示例1:前后各取1个数据

WITH CTE AS (
    SELECT *,
           LAG(Dates_Range) OVER (PARTITION BY ID ORDER BY Dates_Range) AS prev_Date,
           LEAD(Dates_Range) OVER (PARTITION BY ID ORDER BY Dates_Range) AS next_Date
    FROM DummyData
)
SELECT 
    ID, 
    Dates_Range
FROM CTE
WHERE 
    ID IS NULL OR
    (ID = LAG_ID AND prev_Date IS NOT NULL) OR
    (ID = LEAD_ID AND next_Date IS NOT NULL)
ORDER BY Dates_Range;

示例2 & 3:前后各取2个或3个数据

对于这些情况,直接修改上面的逻辑变得复杂,因为我们需要考虑如何动态地调整LAGLEAD的数量。一种可行的方法是创建多个CTE,每个对应不同的偏移量,然后合并结果。但这种做法效率较低且代码冗长。考虑到实际操作中可能需要更灵活的解决方案,建议使用编程语言(如Python、Java等)结合数据库连接库,在应用层面进行处理,这样可以更灵活地控制查询逻辑和输出格式。

如果你的应用环境允许,下面是一个简化的思路:

  1. 确定范围:首先识别出所有ID IS NULL的行。
  2. 扩展范围:对每条NULL记录,向前和向后查询指定数量的非NULL记录。
  3. 合并结果:将查询到的所有记录合并并排序输出。

具体实现时,你可能需要编写一段脚本,根据所需的前后记录数动态生成SQL查询语句,或者执行多次查询后在应用中合并结果。这种方法虽然增加了应用端的复杂度,但提供了更高的灵活性来满足不同数量的需求。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: