2012-05-17 26 views
1

我有兩個表如下:加入兩個表在一起,並在單排冷凝多行

TableOne
- RawDataId INT(PK)
- 時間戳的日期時間
- 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分鐘前,相對於時間戳:

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 
+1

數據的小樣品,你想你的結果看起來將是有益的什麼 – Kevin

+0

什麼是「1440分鐘前面」是什麼意思?只需減去該值,或找到一個已減去其值的行?事先知道「以前的時間」,還是隻需要上一行以及其中的任何時間(1440和1439分鐘就是例子)? –

回答

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 
+0

謝謝吉姆,你讓我走上了正確的軌道。 – Dan

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。

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