1

我有两个表如下:

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

表二示例:

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 次将仪表读数写入表中(因此有时间戳)。When select the top 15 records (sorted by TimeStamp, to give me the latest values), I also need to get the values of that meter 1440 and 1439 minutes ago (relative to the latest 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 分钟前:

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
4

3 回答 3

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...

于 2012-05-17T15:01:12.603 回答
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
于 2012-05-17T14:56:43.847 回答
0

If you are using SQL Server 2005 or later version, you could try something like this:

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

That is, I'm assuming here you want to account for various BuildingIds, since that column is present in your output. If you only want a specific one, you could rewrite the t subselect like this:

(SELECT TOP 1 * FROM TableOne WHERE BuildingId = @Id ORDER BY TimeStamp DESC) t
于 2012-05-18T07:49:31.400 回答