我有两张表如下:
TableOne
- RawDataId int(pk)
- TimeStamp DateTime
- BuildingID int
TableTwo
- RawDataId int(pk / fk)
- MeterId int(pk)
- 价值真实
MeterId不是唯一的并且重复多次(但总是以相同的数量重复)。这两个表连在一起没问题。我能够选择前15行并按时间戳排序,为我提供每个仪表的最新值(总共15个,每个都带有时间戳)。但是,我还需要从之前的时间(恰好是1440和1439分钟前)获得每个仪表的值 - 如果这有意义的话。
因此,在运行查询之后,我需要一个包含TableOne和TableTwo列的表,但是有两个额外的列用于ValueB和ValueC(B早于1440分钟,前面是C 1439)。我整天和昨晚的大部分时间一直玩弄他,我正在慢慢失去这个阴谋。
任何帮助将不胜感激。 谢谢偷看。
---更新
我在下面列出了实际的表格架构以及一些示例数据。
CREATE TABLE [dbo].[TableOne](
[RawDataId] [bigint] IDENTITY(1,1) NOT NULL,
[TimeStamp] [datetime] NOT NULL,
[BuildingId] [int] NULL,
CONSTRAINT [TableOne_PK] PRIMARY KEY CLUSTERED
CREATE TABLE [dbo].[TableTwo](
[MeterId] [bigint] NOT NULL,
[RawDataId] [bigint] NOT NULL,
[Value] [real] NULL,
CONSTRAINT [TableTwo_PK] PRIMARY KEY CLUSTERED
TableOne中最后30条记录的示例数据:
RawDataId, TimeStamp, BuildingId
21677 2012-05-16 00:03:00.000 1
21678 2012-05-16 00:03:00.000 1
21679 2012-05-16 00:03:00.000 1
21680 2012-05-16 00:03:00.000 1
21681 2012-05-16 00:03:00.000 1
21682 2012-05-16 00:03:00.000 1
21683 2012-05-16 00:03:00.000 1
21684 2012-05-16 00:03:00.000 1
21685 2012-05-16 00:03:00.000 1
21686 2012-05-16 00:03:00.000 1
21687 2012-05-16 00:03:00.000 1
21688 2012-05-16 00:03:00.000 1
21689 2012-05-16 00:03:00.000 1
21690 2012-05-16 00:03:00.000 1
21691 2012-05-16 00:03:00.000 1
21662 2012-05-16 00:02:00.000 1
21663 2012-05-16 00:02:00.000 1
21664 2012-05-16 00:02:00.000 1
21665 2012-05-16 00:02:00.000 1
21666 2012-05-16 00:02:00.000 1
21667 2012-05-16 00:02:00.000 1
21668 2012-05-16 00:02:00.000 1
21669 2012-05-16 00:02:00.000 1
21670 2012-05-16 00:02:00.000 1
21671 2012-05-16 00:02:00.000 1
21672 2012-05-16 00:02:00.000 1
21673 2012-05-16 00:02:00.000 1
21674 2012-05-16 00:02:00.000 1
21675 2012-05-16 00:02:00.000 1
21676 2012-05-16 00:02:00.000 1
TableTwo示例:
MeterId, RawDataId, Value
15 21691 7722613
14 21690 908944
13 21689 4982947
12 21688 3821899
11 21687 6
10 21686 0
9 21685 0
8 21684 5761656
7 21683 4240048
6 21682 1541372
5 21681 283223
4 21680 1.298603E+07
3 21679 388137
2 21678 876121
1 21677 0
15 21676 7722615
14 21675 908944
13 21674 4982947
12 21673 3821899
11 21672 5
10 21671 0
9 21670 0
8 21669 5761656
7 21668 4240052
6 21667 1541372
5 21666 283223
4 21665 1.298604E+07
3 21664 388137
2 21663 876122
1 21662 0
每1个表(即时间戳)将表读数写入表中。当选择前15个记录(按TimeStamp排序,为了给我最新的值)时,我还需要获得该仪表1440和1439分钟前的值(相对于最新的TimeStamp)。我希望这更清楚。
到目前为止,我的SQL查询如下所示:
SELECT TOP 15 * FROM (Select TableOne.[RawDataId],
[TimeStamp], BuildingId, MeterId, `enter code here`Value
FROM [TableOne]
INNER JOIN TableTwo ON
TableOne = TableTwo) as PS
ORDER BY [TimeStamp];
查询给了我以下内容,但是我需要额外的两列,其中包含1440和1439分钟之前相对于TimeStamp的值:
RawDataId, TimeStamp, BuildingId, MeterId, Value
21677 2012-05-16 00:03:00.000 1 1 0
21678 2012-05-16 00:03:00.000 1 2 876121
21679 2012-05-16 00:03:00.000 1 3 388137
21680 2012-05-16 00:03:00.000 1 4 1.298603E+07
21681 2012-05-16 00:03:00.000 1 5 283223
21682 2012-05-16 00:03:00.000 1 6 1541372
21683 2012-05-16 00:03:00.000 1 7 4240048
21684 2012-05-16 00:03:00.000 1 8 5761656
21685 2012-05-16 00:03:00.000 1 9 0
21686 2012-05-16 00:03:00.000 1 10 0
21687 2012-05-16 00:03:00.000 1 11 6
21688 2012-05-16 00:03:00.000 1 12 3821899
21689 2012-05-16 00:03:00.000 1 13 4982947
21690 2012-05-16 00:03:00.000 1 14 908944
21691 2012-05-16 00:03:00.000 1 15 7722613
答案 0 :(得分:1)
没有看到数据(也许是查询)样本,很难理解这个问题。如果我理解正确,这应该有效:
SELECT
(
SELECT TOP 1 Value
FROM TableOne t1 join TableTwo t2 ON t1.RawDataId = t2.RawDataId
WHERE t1.RawDataId IN (
SELECT RawDataId FROM TableTwo WHERE MeterId = tbl.MeterId
) and TimeStamp = DATEADD(mi, -1440, tbl.TimeStamp)
) as ValueB,
(
SELECT TOP 1 Value
FROM TableOne t1 join TableTwo t2 ON t1.RawDataId = t2.RawDataId
WHERE t1.RawDataId IN (
SELECT RawDataId FROM TableTwo WHERE MeterId = tbl.MeterId
) and TimeStamp = DATEADD(mi, -1439, tbl.TimeStamp)
) as ValueC
FROM TableTwo tbl
答案 1 :(得分:1)
如果你总是会在1440分钟和1439分钟之前获得价值,那么这样的事情可能有用:
SELECT TOP 15
TableOne.BuildingID
, TableOne.RawDataID
, TableOne.TimeStamp
, TableTwo.MeterID
, TableTwo.Value
, TableTwo1439.Value AS ValueB
, TableTwo1440.Value AS ValueC
FROM TableOne
JOIN TableTwo ON TableOne.RawDataID=TableTwo.RawDataID
JOIN TableTwo TableTwo1439 ON TableTwo.MeterID=TableTwo1439.MeterID
JOIN TableOne TableOne1439 ON TableTwo1439.RawDataID=TableOne1439.RawDataID AND TableOne.TimeStamp=DATEADD(MINUTE,-1439,TableOne1439.TimeStamp)
JOIN TableTwo TableTwo1440 ON TableTwo.MeterID=TableTwo1440.MeterID
JOIN TableOne TableOne1440 ON TableTwo1440.RawDataID=TableOne1440.RawDataID AND TableOne.TimeStamp=DATEADD(MINUTE,-1440,TableOne1440.TimeStamp)
ORDER BY TableOne.Timestamp DESC
否则,您仍然可以使用相同的方法,但可能需要调整它以使用OUTER JOIN而不是......
答案 2 :(得分:0)
如果您使用的是SQL Server 2005或更高版本,则可以尝试以下方法:
WITH data AS (
SELECT
t1.RawDataId,
t1.TimeStamp,
t1.BuildingId,
t2.MeterId,
t2.Value,
x.Diff AS TimeStampId
FROM (SELECT BuildingId, MAX(TimeStamp) AS TimeStamp FROM TableOne GROUP BY BuildingId) t
CROSS JOIN (SELECT 0 UNION ALL SELECT 1440 UNION ALL SELECT 1439) x (Diff)
INNER JOIN TableOne t1 ON t.BuildingId = t1.BuildingId
AND t1.TimeStamp = DATEADD(MINUTE, -x.Diff, t.TimeStamp)
INNER JOIN TableTwo t2 ON t2.RawDataId = t1.RawDataId
)
SELECT
RawDataId,
TimeStamp,
BuildingId,
MeterId,
Value = [0],
Value1440MinAgo = [1440],
Value1439MinAgo = [1439]
FROM data
PIVOT (
MAX(Value) FOR TimeStampId IN ([0], [1440], [1439])
) p
也就是说,我假设您想要考虑各种BuildingIds,因为该列存在于您的输出中。如果您只想要特定的一个,可以像这样重写t
子选择:
(SELECT TOP 1 * FROM TableOne WHERE BuildingId = @Id ORDER BY TimeStamp DESC) t