我是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';
并向第一个选定数据添加2个列(表c中的SCap和ECap)。 根据我的尝试,我的代码如下所示:
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
我需要显示(如果我选择日期范围:2016-05-05
至2016-05-09
),名称1为SCap,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行显示。
有没有办法可以将这两列添加到我的查询中,而不会为同一个名称添加更多行?
EDIT! 表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
答案 0 :(得分:0)
您可以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
答案 1 :(得分:0)
首先,获取给定日期的每个id的最大和最小时间戳。然后连接两次,一次使用最大时间戳值,然后使用每个id到tblinfo的最小时间戳值,以获取这些行的开始和结束值。
添加带有日期过滤器的where
子句,以过滤特定日期。
with maxandmin as
(select vid
,max(timestamplocal) maxtime
,min(timestamplocal) mintime
from tblinfo
group by vid,cast(timestamplocal as date))
select m.vid,b.name,i1.cap as Scap,i2.cap as Ecap
from maxandmin m
join tblinfo i1 on m.vid=i1.vid and m.mintime = i1.timestamplocal
join tblinfo i2 on m.vid=i2.vid and m.maxtime = i2.timestamplocal
join tableb b on b.id=m.vid
答案 2 :(得分:0)
经过一些进一步的调查后,我找到了一个解决方案,这就是我设法做的事情:
SELECT b.Id,
b.Name,
c.S_Time,
c.E_Time,
s.Cap AS S_Cap,
e.Capa AS E_Cap,
FROM b
INNER JOIN (SELECT VId,
MIN(TimestampLocal) AS S_Time,
MAX(TimestampLocal) AS E_Time
FROM Info
where CAST (TimestampLocal AS DATE) >='2016-04-05'
and CAST (TimestampLocal AS DATE) <'2016-05-10'
GROUP BY VId
) AS c
ON b.Id = c.VId
INNER JOIN Info AS s
ON s.VId = c.VId
AND s.TimestampLocal = c.S_Time
INNER JOIN Info AS e
ON e.Vd = c.VId
AND e.TimestampLocal = c.E_Time
WHERE b.SId = 100