2016-10-14 9 views
2

:私はSQL Serverでデータベーステーブルmytable1を持っている2012年表定義がSQLクエリでグループにselectを追加するには?

Column_name Type  Length Nullable 
ts   datetime 8  no 
s_no  int   4  no 
calls  int   4  yes 

DDLです:そして

CREATE TABLE mytable1(
    ts DATETIME NOT NULL, 
    s_no INT NOT NULL, 
    calls INT 
); 

移入データ

INSERT INTO mytable1 (ts, s_no, calls) 
VALUES 
('2016-10-14 10:04:01.000', 3, 56), 
('2016-10-14 10:04:01.000', 4, 145), 
('2016-10-14 10:09:00.000', 3, 143), 
('2016-10-14 10:09:00.000', 4, 329), 
('2016-10-14 10:14:01.000', 3, 0), 
('2016-10-14 10:14:01.000', 4, 49), 
('2016-10-14 10:19:00.000', 3, 6), 
('2016-10-14 10:19:00.000', 4, 16), 
('2016-10-14 10:24:01.000', 3, 22), 
('2016-10-14 10:24:01.000', 4, 28), 
('2016-10-14 10:29:00.000', 3, 4), 
('2016-10-14 10:29:00.000', 4, 7), 
('2016-10-14 10:34:00.000', 3, 14), 
('2016-10-14 10:34:00.000', 4, 9), 
('2016-10-14 10:38:59.000', 3, 39), 
('2016-10-14 10:38:59.000', 4, 391), 
('2016-10-14 10:44:01.000', 3, 3), 
('2016-10-14 10:44:01.000', 4, 31), 
('2016-10-14 10:49:01.000', 3, 116), 
('2016-10-14 10:49:01.000', 4, 52), 
('2016-10-14 10:54:00.000', 3, 75), 
('2016-10-14 10:54:00.000', 4, 8), 
('2016-10-14 10:59:00.000', 3, 16), 
('2016-10-14 10:59:00.000', 4, 8), 
('2016-10-14 11:04:01.000', 3, 23), 
('2016-10-14 11:04:01.000', 4, 13); 
を使用して作成しました

私は30分のウィンドウにタイムスタンプを分割しようとしているし、それぞれの30分のウィンドウから一番大きいタイムスタンプを選択しようとしています。また、私は30分のタイムスタンプの最高のためにすべての異なるs_no値を選択したいと思います。

既存のクエリ:それは

s_no bucket_window ts 
3  20    2016-10-14 10:29:00.000 
4  20    2016-10-14 10:29:00.000 
3  21    2016-10-14 10:59:00.000 
4  21    2016-10-14 10:59:00.000 
3  22    2016-10-14 11:04:01.000 
4  22    2016-10-14 11:04:01.000 

は今、私はこのクエリを改善し、列にの呼び出しを追加したいとつながる与える:私はこの

select m.s_no, m.bucket_window, max(m.ts) ts 
from (
    select m.*, datepart(hour, m.ts)*2 + floor(datepart(minute, m.ts)/30) bucket_window 
    from mytable1 m 
    where m.ts >= DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0) 
) m 
group by m.s_no, m.bucket_window; 

結果を行うクエリを持っています上記の結果で。この列は、コール以上の結果から s_noとTSの組み合わせがmytable1テーブルから s_noとTSの組み合わせと一致mytable1テーブルのカラムから値を有するべきです。

期待される結果

私が試した何を:

ので、私は今、欲しい結果は、私が参加し使用してみましたが、正しい構文と一緒にクエリを置くことができない

s_no bucket_window ts       calls 
3  20    2016-10-14 10:29:00.000  4 
4  20    2016-10-14 10:29:00.000  7 
3  21    2016-10-14 10:59:00.000  16 
4  21    2016-10-14 10:59:00.000  8 
3  22    2016-10-14 11:04:01.000  23 
4  22    2016-10-14 11:04:01.000  13 

です

select m.s_no, m.bucket_window, max(m.ts) ts, i.calls 
from (
    select m.*, datepart(hour, m.ts)*2 + floor(datepart(minute, m.ts)/30) bucket_window 
    from mytable1 m 
    where m.ts >= DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0) 
) m 
LEFT JOIN mytable1 i 
ON max(m.ts) = i.ts--OR (m.ts) = i.ts 
group by m.s_no, m.bucket_window, i.calls 

期待される結果を得るために、この既存のクエリをどのように変更することができますか教えてください。

この既存のクエリは、長い間プロダクションで使用されており、他の動的に生成されたクエリでサブクエリとして使用されているため、期待した結果を得るために完全に変更したくありません。

答えて

1

はタイで、この1つの

SELECT M1.*, 
(SELECT calls From mytable1 M2 where M2.ts=M1.ts and M2.s_no=M1.s_no) as calls 
FROM 
(
    select m.s_no, m.bucket_window, max(m.ts) ts 
    from (
     select m.*, datepart(hour, m.ts)*2 + floor(datepart(minute, m.ts)/30) bucket_window 
     from mytable1 m 
     where m.ts >= DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0) 
    ) m 
    group by m.s_no, m.bucket_window 
) M1 
+0

わかりやすく答えがわかりました。ありがとうございました。 – 300

0

使用トップ(1)を試してみてください。..ROW_NUMBERによってオーダー()

select top(1) with ties m.s_no, datepart(hour, m.ts)*2 + floor(datepart(minute, m.ts)/30) bucket_window, ts, calls 
from mytable1 m 
where m.ts >= DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0) 
order by row_number() over (partition by m.s_no, datepart(hour, m.ts)*2 + floor(datepart(minute, m.ts)/30) 
      order by ts desc); 
1

[OK]を、これはあなたを助けることができるなら、私は見てみましょう:私はあなたの最初のクエリによって開始されたが、再びmytable1に参加しなくても実行しようとしました

select s_no, bucket_window, ts, c as calls from (
    select s_no, ts, bucket_window, 
     max(ts) over (partition by s_no, bucket_window) maxts,  
     case 
      when ts=max(ts) over (partition by s_no, bucket_window) 
      then calls 
      end c 

      from (
       select m.*, 
         datepart(hour, m.ts)*2 + floor(datepart(minute, m.ts)/30) bucket_window 
        from mytable1 m 
       where m.ts >= DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0) 
        ) x 
     ) y  
    where ts=maxts; 

。 SQL Serverの構文はわかりませんが、rextesterでテストしたところ、うまくいくはずです。

ここでは私がrextesterについて準備した例です:私は利用可能な3つのソリューションをすべて入れました。それらはすべてあなたが求めた答えを与えるようです。

SQL Serverの構文がわからないので、TeradataまたはOracleでクエリを変更するために使用したSQL標準分析関数を使用しました。

+0

文法上のエラーはありませんが、何らかの理由で結果に行が引かれません。 – 300

+0

私の悪い、それはありません。ありがとうございました。 – 300

関連する問題