【问题标题】:How to concat two fields and use the result in WHERE clause?如何连接两个字段并在 WHERE 子句中使用结果?
【发布时间】:2021-05-18 06:44:36
【问题描述】:

我必须根据日期时间信息获取所有最旧的记录。

数据

Id |  External Id | Date                | Time
1  |  1000        | 2020-08-18 00:00:00 | 02:30:22
2  |  1000        | 2020-08-12 00:00:00 | 12:45:51
3  |  1556        | 2020-08-17 00:00:00 | 10:09:01
4  |  1919        | 2020-08-14 00:00:00 | 18:19:18
5  |  1919        | 2020-08-14 00:00:00 | 11:45:21
6  |  1919        | 2020-08-14 00:00:00 | 15:54:15

预期结果

Id |  External Id | Date                | Time
2  |  1000        | 2020-08-12 00:00:00 | 12:45:51
3  |  1556        | 2020-08-17 00:00:00 | 10:09:01
5  |  1919        | 2020-08-14 00:00:00 | 11:45:21

我目前正在这样做

SELECT *
FROM RUN AS T1
WHERE CONCAT(T1.DATE, T1.TIME) = (
     SELECT MIN(CONCAT(T2.DATE, T2.TIME))
     FROM RUN AS T2
     WHERE T2.EXTERNAL_ID = T1.EXTERNAL_ID
)

这是正确的做法吗?

谢谢你,问候

更新 1:数据类型

DATE 列是datetime

TIME 列是varchar

【问题讨论】:

  • 为什么要分开存储日期和时间?两者之一可以为空还是其他原因是什么?这两列是什么数据类型?你能告诉我们CREATE TABLE声明吗?
  • 这不是我的数据库,所以我不知道...我用两列的详细信息更新了帖子

标签: sql sql-server sql-server-2012 window-functions


【解决方案1】:

可以使用DENSE_RANK()等窗口函数

SELECT ID, External_ID, Date, Time
  FROM 
  (
   SELECT DENSE_RANK() OVER (PARTITION BY External_ID ORDER BY Date, Time) AS dr,
          r.*
     FROM run r 
   ) AS q
 WHERE dr = 1

Demo

【讨论】:

  • 感谢您的评论。但是我面临这个问题:关键字'WHERE'附近的语法不正确。也许是由于数据库的版本? :Microsoft SQL Server 2012?
  • Oracle 不需要为子查询使用别名,但 SQL Server 需要,只需将其别名为 @Royce 。由于这个原因,我刚刚进行了编辑。
  • 感谢您的演示。我只是有一个问题。然后我可以使用q 做一些inner join 对吗?喜欢...) AS q INNER JOIN TABLE2 ON q.External_Id = ... 吗?此外,PARTITION BY 将按 DESC 排序日期和时间,dr = 1 将只记录第一条记录(即最旧的记录)。正确的 ?只是为了确保理解正确的请求。
  • 是的,当然可以使用别名和连续连接,PARTITION BY 代表GROUP BYORDER BY(默认ascending,所以dr1 开始)选择最旧的每当等于 1@Royce 时,每个 External_ID 值对应一个
  • 感谢您的解释,但我不确定是否理解“等于 1”。 DENSE_RANK() 返回一个数字?
猜你喜欢
  • 1970-01-01
  • 2019-08-23
  • 2016-04-05
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多