【发布时间】:2022-01-20 06:04:01
【问题描述】:
我在 SQL Server 中有一个任务,我需要使用 ID、PRODUCT_ID 和 DATE 列返回 RESULT_DATE 列。任务标准:
-
如果为每个 PRODUCT_ID 填写一次 DATE 列,那么我需要返回唯一的日期(例如 PRODUCT_ID 1 和 3)。假设它的 MIN 日期。
-
如果 DATE 列被填充了多次(例如 PRODUCT_ID 2),那么我需要返回下一个填充的 DATE 行。
数据:
CREATE TABLE #temp (
ID INT,
PRODUCT_ID INT,
[DATE] DATETIME
)
INSERT #temp (ID, PRODUCT_ID, DATE) VALUES
(1, 1, '2008-04-24 00:00:00.000'),
(2, 1, NULL),
(3, 2, '2015-12-09 00:00:00.000'),
(4, 2, NULL),
(5, 2, NULL),
(6, 2, '2022-01-01 13:06:45.253'),
(7, 2, NULL),
(8, 2, '2022-01-19 13:06:45.253'),
(9, 3, '2018-04-25 00:00:00.000'),
(10,3, NULL),
(11,3, NULL)
| ID | PRODUCT_ID | DATE | RESULT_DATE |
|---|---|---|---|
| 1 | 1 | 2008-04-24 00:00:00.000 | 2008-04-24 00:00:00.000 |
| 2 | 1 | NULL | 2008-04-24 00:00:00.000 |
| 3 | 2 | 2015-12-09 00:00:00.000 | 2022-01-01 13:06:45.253 |
| 4 | 2 | NULL | 2022-01-01 13:06:45.253 |
| 5 | 2 | NULL | 2022-01-01 13:06:45.253 |
| 6 | 2 | 2022-01-01 13:06:45.253 | 2022-01-19 13:06:45.253 |
| 7 | 2 | NULL | 2022-01-19 13:06:45.253 |
| 8 | 2 | 2022-01-19 13:06:45.253 | 2022-01-19 13:06:45.253 |
| 9 | 3 | 2018-04-25 00:00:00.000 | 2018-04-25 00:00:00.000 |
| 10 | 3 | NULL | 2018-04-25 00:00:00.000 |
| 11 | 3 | NULL | 2018-04-25 00:00:00.000 |
我尝试了不同的技术,例如使用LEAD 和LAG SQL 函数组合。最新的脚本:(但是还是不行)
SELECT
COALESCE(DATE,
CAST(
SUBSTRING(
MAX(CAST(DATE AS BINARY(4)) + CAST(DATE AS BINARY(4))) OVER ( PARTITION BY PRODUCT_ID ORDER BY DATE ROWS UNBOUNDED PRECEDING)
,5,4)
AS INT)
) AS RESULT_DATE,
*
FROM TABLE
【问题讨论】:
-
为什么要将 [Date] 列转换为二进制,然后再转换为子字符串,然后再转换回日期?请不要使用保留字 (Date) 作为列名或表名 (TABLE)。我不确定你的代码是否真的运行。
-
如果您以 DDL+DML 的形式提供示例数据,您可以更轻松地为人们提供帮助。
-
你好@SteveFord。将 DATE 列名放在 [ ] 中就可以了。但是,代码没有如前所述正常运行。
-
@KonstantinsKovalovs 我知道您可以使用 [] 来转义这些保留字,但它确实使您的代码更难阅读和理解,因此仍然不应该使用保留字。为什么要将日期转换为二进制并将其添加到自身然后转换为 INT 然后在 COALESCE 中使用它根本没有意义。正如 Dale K 提到的,请添加 CREATE TABLE 语句、一些插入以插入测试数据、您正在尝试的查询、您收到的任何错误以及您的预期结果。
-
@SteveFord 我添加了脚本!预期结果在 RESULTS_DATA 列中可见:)
标签: sql sql-server tsql partition dense-rank