Select a grouped table (by Id) filtered by a datetime column according to NULL and MAX(date) values

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

Select a grouped table (by Id) filtered by a datetime column according to NULL and MAX(date) values

问题

想象一下,我有一个包含很多列的表,但必须通过Id和EndDate进行筛选后返回。

| Id | EndDate | ... |
| -------- | -------- |
| 1 | NULL |
| 1 | 01.01.2022 15:25 |
| 1 | 01.01.2022 15.24 |
| 2 | 15.01.2022 10:00 |
| 2 | 15.01.2022 11:00 |
| 2 | 17.01.2022 00:00 |
| 3 | NULL |
| 3 | 10.10.2022 22:12 |
| 4 | 18.05.2022 17:15 |
| 4 | 18.05.2022 17:17 |
| 4 | 19.05.2022 00:00 |

结果表必须如下:

| Id | EndDate | ... |
| -------- | -------- |
| 1 | NULL |
| 2 | 17.01.2022 00:00 |
| 3 | NULL |
| 4 | 19.05.2022 00:00 |

必须选择具有特定Id的记录,要么具有NULL EndDate值,要么具有MAX值。正如在结果表中所见,Id = 1的记录具有NULL EndDate,因此必须选择该记录,Id = 4的记录没有NULLable EndDate,因此必须返回MAX(EndDate)值。

我尝试了不同的联接和UNIONing方案,但似乎很困难。此外,我考虑了使用CTE表进行某些操作,但似乎不相关。关键是找到一个最佳解决方案,因为结果表将与另一个表连接在一起。
如果至少有一个关于如何获得所需结果的想法,我将不胜感激。

英文:

Imagine that I have a table with pretty many columns in there, but that has to be returned filtered just by Id and EndDate.

| Id | EndDate | ... |
| -------- | -------- |
| 1 | NULL |
| 1 | 01.01.2022 15:25 |
| 1 | 01.01.2022 15.24 |
| 2 | 15.01.2022 10:00 |
| 2 | 15.01.2022 11:00 |
| 2 | 17.01.2022 00:00 |
| 3 | NULL |
| 3 | 10.10.2022 22:12 |
| 4 | 18.05.2022 17:15 |
| 4 | 18.05.2022 17:17 |
| 4 | 19.05.2022 00:00 |

The resulting table must be the following:

| Id | EndDate | ... |
| -------- | -------- |
| 1 | NULL |
| 2 | 17.01.2022 00:00 |
| 3 | NULL |
| 4 | 19.05.2022 00:00 |

The record with a specific Id must be picked either having a NULL EndDate value or MAX value otherwise. As it's seen on the resulting table, record with Id = 1 has NULL EndDate so then it must be picked, record with Id = 4 doesn't have a NULLable EndDate, so the value with MAX(EndDate) must be returned.

I was trying different scenarios with joining and UNIONing, but it seems desperate. Also, I considered something with CTE tables, but it seems irrelevant. The point is also get an optimal solution, because resulting table are considered to be joined to another table.
If there will be at least an idea of how to get a desired result, I would be appreciate.

答案1

得分: 2

你可以在一个通用表达式中使用 ROW_NUMBER 来定义优先级。只需将 NULL 替换为一个遥远的日期,如 9999-12-31,然后你可以按日期排序。

WITH cte
AS
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY ISNULL(EndDate,'99991231') DESC) AS RN
    FROM dbo.myTable
)
SELECT *
FROM cte
WHERE cte.RN = 1;
英文:

You can use ROW_NUMBER in a common table expression to define the priority. Just replace the NULL with a date far in the future like 9999-12-31, then you can just order the date.

WITH cte
AS
(
	SELECT *, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY ISNULL(EndDate,'99991231') DESC) AS RN
	FROM dbo.myTable
)
SELECT *
FROM cte
WHERE cte.RN = 1;

答案2

得分: 1

使用简单的聚合和CASE表达式,其中您检查每个Id是否存在任何null日期:

SELECT Id,
       CASE WHEN COUNT(*) = COUNT(EndDate) THEN MAX(EndDate) END AS EndDate
FROM tablename
GROUP BY Id;

仅当所有日期均不为null时,条件COUNT(*) = COUNT(EndDate)才满足。<br/>

查看演示。<br/>

英文:

With simple aggregation and a CASE expression where you check if there are any null dates for each Id:

SELECT Id,
       CASE WHEN COUNT(*) = COUNT(EndDate) THEN MAX(EndDate) END AS EndDate
FROM tablename
GROUP BY Id;

The condition COUNT(*) = COUNT(EndDate) is satisfied only if all dates are not null.<br/>

See the demo.<br/>

huangapple
  • 本文由 发表于 2023年2月7日 03:41:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75365834.html
匿名

发表评论

匿名网友

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

确定