2012-05-17 2 views
1

다음과 같이 나는 두 개의 테이블이 있습니다두 개의 테이블을 가입하고 단일 행에 여러 행을 응축

TableOne
- RawDataId INT (PK)
- 타임 스탬프 날짜 시간
- BuildingID INT

TableTwo을
- RawDataId INT (PK/FK)
- MeterId INT (PK)
- 실제 값

MeterId는 고유하지 않으며 여러 번 반복되지만 항상 같은 수입니다. 두 테이블은 아무 문제없이 함께 참여합니다. 상위 15 개 행을 선택하고 타임 스탬프를 주문할 수 있으며, 각 미터의 최신 값 (총 15 개, 타임 스탬프가있는 각각의 값)을 제공합니다. 그러나 이전의 시간 (정확하게 1440과 1439 분 전)부터 각 미터의 Value를 얻어야합니다.

그래서 쿼리를 실행 한 후에는 TableOne 및 TableTwo의 열이 포함 된 테이블이 필요하지만 ValueB 및 ValueC에 대한 두 개의 추가 열 (B는 1440 분 이전의 값 및 C 1439 이전 값)이 필요합니다. 필자는 하루 종일 그리고 어젯밤의 대부분을 가지고 놀았으며 천천히 그 음모를 잃어 가고있다.

도움을 주시면 감사하겠습니다. 감사 인사. 함께 일부 샘플 데이터 I 실제 테이블 스키마 아래에 포함 시켰 업데이트

---.

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 개 레코드 데이터 샘플 : TableTwo위한

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 

샘플 : 검침마다 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 

우표). 나에게 최신 값을 제공하기 위해 TimeStamp로 정렬 된 상위 15 개 레코드를 선택하면 해당 미터의 값을 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 1,439분 전 m의 값으로 상대 추가로 두 개의 열이 필요합니다 타임 스탬프 :

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

데이터의 작은 샘플 "1천4백40분 이전"무엇을 – Kevin

+0

을 의미합니까 당신이 도움이 될 것입니다 결과 모양을 원하는 : 당신은 단지 특정 일을하려는 경우, 당신은이 같은 t 부속을 다시 쓸 수 있을까? 그냥 값을 빼거나 값을 뺀 행을 찾으면됩니까? "이전 시간"을 미리 알고 있습니까, 아니면 이전 행이 필요합니까? (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을 설명 할 여기에 있으리라 믿고있어 귀하의 출력에.

(SELECT TOP 1 * FROM TableOne WHERE BuildingId = @Id ORDER BY TimeStamp DESC) t 
관련 문제