我是 SQL 查询的新手,我需要从这个查询开始进行连接:
SELECT b.Name, a.*
FROM a INNER JOIN b ON a.VId = b.Id
WHERE b.SId = 100
AND a.Day >= '2016-05-05'
AND a.Day < '2016-05-09';
并向第一个选定数据(表 c 中的 SCap 和 ECap)添加 2 个列。 根据我的尝试,我的代码如下所示:
SELECT b.Name,a.*,
c.MaxDay,
c.Cap,
FROM a INNER JOIN b
ON a.VId = b.Id
INNER JOIN
(SELECT VId,
MAX(TimestampLocal) AS MaxDay,
CAST (TimestampLocal AS DATE) AS Day,
Cap,
FROM Info
GROUP BY VId,
CAST (TimestampLocal AS DATE),
Cap) AS c
ON a.VId = c.VId
AND a.Day = c.Day
WHERE b.SId = 33
AND a.Day >= '2016-05-05'
AND a.Day < '2016-05-09';
但是我得到的行比需要的多。
我需要给定车辆在日期范围内最早和最新的 TimestampLocal。这将来自 Info 中的两条记录,每条记录都有其正确的 Cap 值。 例如: 我有两个名称,其值在表信息中持续 2 天(名称 1),而名称 2 只有一天:
- Day 1 2016-05-07:
- Name 1: Values at 2:45, 10:10 and 3.10
- Name 2: Values at 5:13 and 8:22
- Day 2 2016-05-09:
- Name 1: Values at 4:13, 6:15 and 9:20
我需要显示(如果我选择 daterange:2016-05-05
到 2016-05-09
)对于 SCap 的名称 1 从 2016-05 开始的值-07 从 2:45 开始,对于 ECap,从 2016-05-09 从 9:20 开始,对于名称 2,对于 SCap,从 2016-05-07 从 5:13 开始,对于 ECap,从 2016-05-07 开始从 8 点 22 分开始。这应该显示在 2 行中。
有没有一种方法可以将这两列添加到我的查询中,而无需为相同名称添加更多行?
编辑! 表 a 我有:
VId | Day
5251 | 05/09/2016
5382 | 05/09/2016
表b:
Id | Name
5251 | N1
5382 | N2
表信息:
VId | TimestampLocal | Cap
5251 | 2016-05-09 11:33:46.2000000 +03:00 | 0
5251 | 2016-05-09 11:37:11.4000000 +03:00 | 7
5251 | 2016-05-09 11:38:11.4000000 +03:00 | 4
5251 | 2016-05-09 11:39:11.7000000 +03:00 | 2
5382 | 2016-05-09 09:30:56.6000000 -04:00 | 5
5382 | 2016-05-09 09:31:56.6000000 -04:00 | 3
我需要显示 - 如果我选择从 2016-05-03
到 2016-05-10
的日期范围:
Id | Name | SCap | ECap
5251 | N1 | 0 | 2
5382 | N2 | 5 | 3
最佳答案
您可以使用 CTE
和 ROW_NUMBER
来检索两条记录:
;WITH Info_CTE AS (
SELECT VId,
CAST (TimestampLocal AS DATE) AS Day,
Cap,
ROW_NUMBER() OVER (PARTITION BY VId
ORDER BY TimestampLocal) AS rn1,
ROW_NUMBER() OVER (PARTITION BY VId
ORDER BY TimestampLocal DESC) AS rn2
FROM Info
)
SELECT b.Name,
a.*,
c.Day,
c.Cap
FROM a
INNER JOIN b ON a.VId = b.Id
INNER JOIN Info_CTE AS c ON a.VId = c.VId AND
a.Day = c.Day AND
1 IN (c.rn1, c.rn2)
WHERE b.SId = 33
AND a.Day >= '2016-05-05'
AND a.Day < '2016-05-09';
如果您希望将 ECap
和 SCap
作为单独的列,则不要使用
c.Cap
你可以使用:
CASE WHEN c.rn1 = 1 THEN c.Cap END AS ECap,
CASE WHEN c.rn2 = 1 THEN c.Cap END AS SCap
关于SQL选择日期范围的第一个值和最后一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37118851/