質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Transact-SQL

Transact-SQLはSybase ASEとMIcrosoft SQLサーバで対応されているSQLの機能拡張版です。

Q&A

解決済

2回答

5430閲覧

T-SQL:日時を比較して最新のデータを取得したい

dera

総合スコア28

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Transact-SQL

Transact-SQLはSybase ASEとMIcrosoft SQLサーバで対応されているSQLの機能拡張版です。

0グッド

0クリップ

投稿2018/03/14 05:58

編集2018/03/14 06:28

お世話になります。

テーブルにint型でUNIX時間を表すデータが大量にあり、
その中から、ある一定期間のデータを引っこ抜きたいと思っています。
しかし、中には年月日時分までは同じで秒だけ違うデータが混入しており、
そういったデータに関しては最新1件(時間が新しい方)のデータを抽出したいです。

テーブルの構成は時間がint、列Aはnumeric(6,2)、列Bはnumeric(6,2)です
下記のサンプルテーブルではデータ数は少ないですが、このような形で大量のデータが
テーブルに保存されています。

--test_tbl
|時間|列A|列B|
|1520905810|5.5|6.6|
|1521003000|1.1|2.2|
|1521003010|3.3|4.4|

現状のSQLは

t

1SELECT 2 (CONVERT(datetime,FORMAT(DATEADD(S,[時間],'19700101 09:00:00'),'yyyy/MM/dd hh:mm:ss'))), 3    列A, 4 列B 5 6FROM test_tbl 7WHERE CONVERT(datetime,FORMAT(DATEADD(S,[時間],'19700101 09:00:00'),'yyyy/MM/dd hh:mm:ss')) BETWEEN '2018-03-01 00:00:00' AND '2018-03-20 11:59:00'

実行結果
--test_tbl
|時間|列A|列B|
|2018-03-13 10:50:10|5.5|6.6|
|2018-03-14 13:50:00|1.1|2.2|
|2018-03-14 13:50:10|3.3|4.4|

こんな感じで、UNIX時間をdatetime型に変換して一定の期間に絞り込むところまでは
できました。ただ、依然として秒のみが違うデータも混入しているので、そこをどうすればいいかがわからない状態です。

最終的にはテーブルが下記のような形になってほしいです。
--test_tbl
|時間|列A|列B|
|2018-03-13 10:50:10|5.5|6.6|
|2018-03-14 13:50:10|3.3|4.4|

拙い説明ではありますが、皆様の知恵をお貸しください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

あんまり効率いいクエリじゃないけどrow_number
秒の切り捨てはfloor(時間/100)で。
↑これだめやねちゃんとformatしましたm(_ _;)m→floor(時間/60)ならいいんかな?

sql

1with test as ( 2 select 1520905810 as 時間,'5.5' as 列A,'6.6' as 列B 3 union all 4 select 1521003000,'1.1','2.2' 5 union all 6 select 1521003010,'3.3','4.4' 7) 8select * 9from ( 10 select *,FORMAT(DATEADD(S,[時間],'19700101 09:00:00'),'yyyy/MM/dd hh:mm:ss') as 日時 11 -- 秒切り捨ての時間降順 12 ,row_number() over(partition by floor(時間/60) order by 時間 desc) as 順番 13 from test 14) as X 15where X.順番=1

投稿2018/03/14 07:54

編集2018/03/14 08:21
sousuke

総合スコア3828

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2018/03/14 08:17 編集

>sousuke さん floor(時間/60)なら大丈夫じゃないでしょうか。 確証が持てなかったので、私はformat()にしましたが。 尚、format()での時間に関する書式指定はhhだと12時間表記になるので、HHの指定である必要があります。
sousuke

2018/03/14 08:20

ホントですね。コピペして使ってました…ご指摘どうも~b
guest

0

ベストアンサー

同じ時分内での最大とする方法もありますが、Window関数の方がコストが低いのでLead()を利用しています。

SQL

1select * 2from ( 3 select *, lead(日時) over (partition by format(日時, 'yyyy/MM/dd HH:mm') order by 日時) as 次秒 4 from ( 5 SELECT *,DATEADD(S,[時間],'19700101 09:00:00') as 日時 6 FROM test_tbl 7 ) step1 8 WHERE 日時 >= '2018-03-01' AND 日時 < '2018-03-21' 9) step2 10where 次秒 is null

投稿2018/03/14 07:35

編集2018/03/14 08:53
sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dera

2018/03/14 08:43 編集

ありがとうございます。やりたいことができました。 私が知らない関数ばかりなのですが、lead関数で現在の行から次の行へアクセスしてるのは調べてわかったのですが、そのあとのover句とpartition by で何をしているのかがイマイチわかりません。 後、UNIX時間からdatetime型には変換できてなかったのは何故でしょうか・・。
sazi

2018/03/14 08:43

partition byで指定した項目が区切りになります。 同じ時分で区切って、その中でソートするってことです。
dera

2018/03/14 08:52

なるほど。そういうことだったのですね。とても勉強になりました。ありがとうございます!
sazi

2018/03/14 09:17

>後、UNIX時間からdatetime型には変換できてなかったのは何故でしょうか・・。 とは、どこの記述について言われてます?
dera

2018/03/15 00:02

日時をformatしているので、てっきりこのSQLを実行した後は、UNIX時間の形からdatetime型に変換された形で表示されるものとばかり思っていました。
sazi

2018/03/15 01:26

ああ、失礼しました。 質問でのSQLの記述上、日付型に直しているのが冗長に見えたので変更していましたが、 CAST()を忘れていました。 以下に変更下さい。 >DATEADD(S,[時間],'19700101 09:00:00' ) DATEADD(S,[時間],CAST('19700101 09:00:00' AS DATETIME))
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問