シリーズ記事ディレクトリ
【SQL開発実技】連載(1):SQLについて絶対に言いたいこと
【SQL開発実技】連載(2):簡単な単一テーブルクエリ
【SQL開発実技】連載(3):SQLに関することsorting
【SQL開発実技】シリーズ(4):実行計画からUNION ALLと空文字列&UNIONとORの注意点を考える
【SQL開発実技】シリーズ(5):IN、EXISTS、実行計画から INNER JOIN 、シナリオを分けて暗記する必要はないオンラインまとめ
【SQL開発実践編】シリーズ(6):実行計画からNOT IN、NOT EXISTS、LEFT JOINの効率を見て、内部と外部の関連付け条件を間違えてはいけない
【SQL開発実技】連載(セブン):重複データ前提で2つのテーブルの差分データと対応するレコード数を比較する方法【SQL開発
】実技】連載(第8回):データ挿入を制限する制約よりも柔軟なデータの挿入方法と、insert文で複数のテーブルを同時に挿入する方法【SQL開発実技】連載(9):
An更新すると、他の列のデータが誤って空に更新されますか? マージ書き換えアップデート!重複データを削除する 5 つの方法を教えてください。
【SQL開発実技】シリーズ(10):文字列の分割、文字列の置換、文字列の出現回数のカウントから始まる
【SQL開発実技】シリーズ(11):いくつかのケースを取り上げて語る translate|regexp_replace| listagg |wmsys.wm_concat|substr|regexp_substr よく使う関数
【SQL開発実技】連載(12):3問(文字列の文字を重複排除した上で文字列をアルファベット順にソートする方法は?どの文字列に数字が含まれているかを識別するには?方法は?)区切られたデータを多値の IN リストに変換するには?)
【SQL開発実技】シリーズ(13):共通の集計関数を議論&()よりもsum()を見て従業員の賃金を積み上げる実行計画【SQL開発実技】シリーズ(14):消費後の残高を計算&累積額を
計算銀行の売上高の合計&各部署の給与上位3名を計算する
【SQL開発実技】シリーズ(十五):最も価値の高い行のデータ情報を探し出し、max/min()の合計を素早く計算する keep ()over()、fisrt_value、last_value、ratio_to_report
【SQL開発実技】シリーズ(16):データウェアハウスでの時間型操作(主)日、月、年、時、分、秒差と時差計算【SQL開発実技
】実技】シリーズ(セブンティーン):データウェアハウスの時間型操作(一次) 2つの日付間の稼働日数を求め、各日付の1週間の出現回数を計算し、現在の記録との差を求めるそして次のレコード 日数
【SQL開発実技】シリーズ(18):データウェアハウスでの時間型操作(上級) INTERVAL、EXTRACTと年がうるう年かどうかの見分け方と週の計算【SQL開発実技編】連載(19)
:データウェアハウスの時間型操作(応用編)で現在の月や年のカレンダーを一つのSQLで印刷する方法は?月の最初と最後の曜日の日付を決定する方法は?
【SQL開発実技】シリーズ(20):データウェアハウスにおける時間型操作(上級編) 四半期の開始時刻と終了時刻の取得と不連続な時間データの数え方【SQL開発実践編】シリーズ(21):データウェアハウスにおける時間型
操作データウェアハウス(上級) 重複する日付範囲を特定し、指定した10分間隔でデータを集計する
【SQL開発実技】シリーズ(22):データウェアハウスのレポートシナリオ ☞ 分析機能の効率は速くなければならないのか Chat 1 実装について話す結果セットのページングとインターレース サンプリングの
【SQL開発実技】連載(23):データウェアハウスレポートシナリオ ☞ データ順列の重複排除方法と最大値・最小値を含むレコードの探し方 再度実行計画を使って、分析機能が苦手
【SQL開発実技】シリーズ(24):データウェアハウスレポートシナリオ☞「行から列」「列から行」をケース実行プランで詳しく解説【SQL開発実技】
シリーズ(25): データウェアハウスのレポートシナリオ ☞ 結果セットの重複データは一度しか表示されず、計算部門の給与差額の効率的な書き方とデータを素早くまとめる方法【SQL開発実技】シリーズ(26):
データ倉庫レポートのシナリオ ☞ 雑談 ROLLUP と UNION ALL がそれぞれグループ合計を行う方法と、どの行が集計の結果行であるかを識別する方法
記事ディレクトリ
序文
この記事の主な内容は、時間型操作の高度な操作についてです. これらの操作は、データ ウェアハウスでのより困難な時間操作のケースでもあります: 今月のカレンダーまたは今年のカレンダーを 1 つの SQL で出力する方法? ? ? 年の特定の曜日に属するすべての日付を数える方法? 特定の月の特定の曜日の最初と最後の日付を決定する方法? ? ?
【SQL開発実技】 この連載はブロガーが昔の知識の復習として書いています. やはりSQL開発はデータ分析シナリオにおいて非常に重要で基本的なものです. 面接ではよくSQL開発やチューニング経験について聞かれます. 読み終わったらそう思う.これを書いて連載でも何か得られるし、今後は安心してSQL面接に臨めますよ~。
1. 1 年のうちの特定の曜日に属するすべての日付を決定する
この例では、指定された年のすべての金曜日を返し、以前に紹介した知識を使用して 1 年全体の情報を列挙し、それをフィルター処理するように要求します。
SQL> with t as
2 (select trunc(sysdate, 'y') + (level - 1) as dy
3 from dual
4 connect by level <=
5 (add_months(trunc(sysdate, 'y'), 12) - trunc(sysdate, 'y')))
6 select dy, to_char(dy, 'day') as 周五 from t where to_char(dy, 'd') = 6;
DY 周五
----------- ---------------------------------------------------------------------------
2023-1-6 星期五
2023-1-13 星期五
2023-1-20 星期五
2023-1-27 星期五
2023-2-3 星期五
2023-2-10 星期五
2023-2-17 星期五
2023-2-24 星期五
2023-3-3 星期五
2023-3-10 星期五
2023-3-17 星期五
2023-3-24 星期五
2023-3-31 星期五
2023-4-7 星期五
2023-4-14 星期五
2023-4-21 星期五
2023-4-28 星期五
2023-5-5 星期五
2023-5-12 星期五
2023-5-19 星期五
2023-5-26 星期五
2023-6-2 星期五
2023-6-9 星期五
2023-6-16 星期五
2023-6-23 星期五
2023-6-30 星期五
2023-7-7 星期五
2023-7-14 星期五
2023-7-21 星期五
2023-7-28 星期五
2023-8-4 星期五
2023-8-11 星期五
2023-8-18 星期五
2023-8-25 星期五
2023-9-1 星期五
2023-9-8 星期五
2023-9-15 星期五
2023-9-22 星期五
2023-9-29 星期五
2023-10-6 星期五
2023-10-13 星期五
2023-10-20 星期五
2023-10-27 星期五
2023-11-3 星期五
2023-11-10 星期五
2023-11-17 星期五
2023-11-24 星期五
2023-12-1 星期五
2023-12-8 星期五
2023-12-15 星期五
2023-12-22 星期五
2023-12-29 星期五
52 rows selected
この例のポイントは、次to_char(dy, 'd')
のようなさまざまなクライアント設定の影響を避けるために、判断に使用することです。
SQL> select to_char(sysdate,'day')as day,to_char(sysdate,'d') as d from dual;
DAY D
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
星期三 4
SQL> alter session set nls_language=american;
Session altered
SQL> select to_char(sysdate,'day')as day,to_char(sysdate,'d') as d from dual;
DAY D
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
wednesday 4
SQL>
パラメータ「day」を使用すると、異なる文字セットによって返される結果が異なることがわかりますが、「d」は影響を受けません。
2. 月の最初と最後の曜日の日付を決定する
この例では、今月の最初の月曜日と最後の月曜日を返す必要があります. 前の月と今月の終わりの 7 日前の次の週の月曜日をそれぞれ見つけることができます.
SQL> select next_day(trunc(sysdate,'mm')-1,2) as 第一周周一,
2 next_day(last_day(trunc(sysdate,'mm'))-7,2) as 最后一周的周一
3 from dual;
第一周周一 最后一周的周一
----------- -----------
2023-2-6 2023-2-27
3. 今月のカレンダーを作成する
今月のカレンダー情報を出力するためのSQLを書く必要があります.
この要求を見ると少し混乱しますか?
それを達成する方法は?? ?
実際には、指定された月のすべての日付を列挙し、対応する週の情報に変換してから、週に応じて「行と列の変換」を行うことができます. ここで行と列を交換する方法を示します.紹介されていないのでpivot/unpivot
、やってcase when
みてください。
SQL> with t as
2 (select trunc(sysdate, 'mm') + (level - 1) as dy
3 from dual
4 connect by level <=
5 (add_months(trunc(sysdate, 'mm'), 1) - trunc(sysdate, 'mm'))),
6 t1 as
7 (select to_char(dy, 'iw') as 所在周,
8 to_char(dy, 'dd') as 日期,
9 to_number(to_char(dy, 'd')) 周几
10 from t)
11 select max(case 周几
12 when 2 then
13 日期
14 end) 周一,
15 max(case 周几
16 when 3 then
17 日期
18 end) 周二,
19 max(case 周几
20 when 4 then
21 日期
22 end) 周三,
23 max(case 周几
24 when 5 then
25 日期
26 end) 周四,
27 max(case 周几
28 when 6 then
29 日期
30 end) 周五,
31 max(case 周几
32 when 7 then
33 日期
34 end) 周六,
35 max(case 周几
36 when 1 then
37 日期
38 end) 周天
39 from t1
40 group by 所在周
41 order by 所在周;
周一 周二 周三 周四 周五 周六 周天
--------------------------------------------------------------------------- --------------------------------------------------------------------------- --------------------------------------------------------------------------- --------------------------------------------------------------------------- --------------------------------------------------------------------------- --------------------------------------------------------------------------- ---------------------------------------------------------------------------
01 02 03 04 05
06 07 08 09 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28
SQL>
4.年間カレンダー
ひと月のカレンダーの書き方は先ほど紹介しました。
一年中だとしたら?やり方が全然違う!! ! 365日を数えてみてください。
ここに小さな問題があり、53 週目のデータの戻り値がto_char(日期,'iw')
間違っていて、最初の週が返されます。
SQL> WITH x AS
2 (SELECT to_date('2013-12-27', 'yyyy-mm-dd') + (LEVEL - 1) AS d
3 FROM dual
4 CONNECT BY LEVEL <= 5)
5 SELECT d, to_char(d, 'day') AS DAY, to_char(d, 'iw') AS iw FROM x;
D DAY IW
----------- --------------------------------------------------------------------------- ---------------------------------------------------------------------------
2013-12-27 星期五 52
2013-12-28 星期六 52
2013-12-29 星期日 52
2013-12-30 星期一 01
2013-12-31 星期二 01
SQL>
このデータは処理する必要case when
が。
SQL>
SQL> WITH x AS
2 (SELECT to_date('2013-12-27', 'yyyy-mm-dd') + (LEVEL - 1) AS d
3 FROM dual
4 CONNECT BY LEVEL <= 5),
5 x1 as
6 (SELECT d,
7 to_char(d, 'day') AS DAY,
8 to_char(d, 'mm') AS mm,
9 to_char(d, 'iw') AS iw
10 FROM x)
11 select d,
12 day,
13 mm,
14 iw,
15 case
16 when mm = 12 and iw = '01' then
17 '53'
18 else
19 iw
20 end as new_iw
21 from x1;
D DAY MM IW NEW_IW
----------- --------------------------------------------------------------------------- --------------------------------------------------------------------------- --------------------------------------------------------------------------- ---------------------------------------------------------------------------
2013-12-27 星期五 12 52 52
2013-12-28 星期六 12 52 52
2013-12-29 星期日 12 52 52
2013-12-30 星期一 12 01 53
2013-12-31 星期二 12 01 53
SQL>
したがって、年次カレンダーは次のようにクエリできます。
SQL> with t as
2 (select trunc(sysdate, 'y') as 本年年初,
3 add_months(trunc(sysdate, 'y'), 12) as 下年初
4 from dual),
5 t1 as
6 (select 本年年初 + (level - 1) as 日期
7 from t
8 connect by level <= 下年初 - 本年年初),
9 t2 as
10 (select 日期,
11 to_char(日期, 'mm') as 月份,
12 to_char(日期, 'iw') 所在周,
13 to_number(to_char(日期, 'd')) as 周几
14 from t1),
15 t3 as
16 (select 日期,
17 月份,
18 case
19 when 月份 = 12 and 所在周 = '01' then
20 '53'
21 else
22 所在周
23 end as 所在周,
24 周几
25 from t2)
26 select case
27 when lag(月份) over(order by 所在周) = 月份 then
28 null
29 else
30 月份
31 end as 月份,
32 所在周,
33 max(case 周几
34 when 2 then
35 日期
36 end) 周一,
37 max(case 周几
38 when 3 then
39 日期
40 end) 周二,
41 max(case 周几
42 when 4 then
43 日期
44 end) 周三,
45 max(case 周几
46 when 5 then
47 日期
48 end) 周四,
49 max(case 周几
50 when 6 then
51 日期
52 end) 周五,
53 max(case 周几
54 when 7 then
55 日期
56 end) 周六,
57 max(case 周几
58 when 1 then
59 日期
60 end) 周天
61 from t3
62 group by 月份, 所在周
63 order by 2;
月份 所在周 周一 周二 周三 周四 周五 周六 周天
--------------------------------------------------------------------------- --------------------------------------------------------------------------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
01 01 2023-1-2 2023-1-3 2023-1-4 2023-1-5 2023-1-6 2023-1-7 2023-1-8
02 2023-1-9 2023-1-10 2023-1-11 2023-1-12 2023-1-13 2023-1-14 2023-1-15
03 2023-1-16 2023-1-17 2023-1-18 2023-1-19 2023-1-20 2023-1-21 2023-1-22
04 2023-1-23 2023-1-24 2023-1-25 2023-1-26 2023-1-27 2023-1-28 2023-1-29
05 2023-1-30 2023-1-31
02 05 2023-2-1 2023-2-2 2023-2-3 2023-2-4 2023-2-5
06 2023-2-6 2023-2-7 2023-2-8 2023-2-9 2023-2-10 2023-2-11 2023-2-12
07 2023-2-13 2023-2-14 2023-2-15 2023-2-16 2023-2-17 2023-2-18 2023-2-19
08 2023-2-20 2023-2-21 2023-2-22 2023-2-23 2023-2-24 2023-2-25 2023-2-26
09 2023-2-27 2023-2-28
03 09 2023-3-1 2023-3-2 2023-3-3 2023-3-4 2023-3-5
10 2023-3-6 2023-3-7 2023-3-8 2023-3-9 2023-3-10 2023-3-11 2023-3-12
11 2023-3-13 2023-3-14 2023-3-15 2023-3-16 2023-3-17 2023-3-18 2023-3-19
12 2023-3-20 2023-3-21 2023-3-22 2023-3-23 2023-3-24 2023-3-25 2023-3-26
13 2023-3-27 2023-3-28 2023-3-29 2023-3-30 2023-3-31
04 13 2023-4-1 2023-4-2
14 2023-4-3 2023-4-4 2023-4-5 2023-4-6 2023-4-7 2023-4-8 2023-4-9
15 2023-4-10 2023-4-11 2023-4-12 2023-4-13 2023-4-14 2023-4-15 2023-4-16
16 2023-4-17 2023-4-18 2023-4-19 2023-4-20 2023-4-21 2023-4-22 2023-4-23
17 2023-4-24 2023-4-25 2023-4-26 2023-4-27 2023-4-28 2023-4-29 2023-4-30
05 18 2023-5-1 2023-5-2 2023-5-3 2023-5-4 2023-5-5 2023-5-6 2023-5-7
19 2023-5-8 2023-5-9 2023-5-10 2023-5-11 2023-5-12 2023-5-13 2023-5-14
20 2023-5-15 2023-5-16 2023-5-17 2023-5-18 2023-5-19 2023-5-20 2023-5-21
21 2023-5-22 2023-5-23 2023-5-24 2023-5-25 2023-5-26 2023-5-27 2023-5-28
22 2023-5-29 2023-5-30 2023-5-31
06 22 2023-6-1 2023-6-2 2023-6-3 2023-6-4
23 2023-6-5 2023-6-6 2023-6-7 2023-6-8 2023-6-9 2023-6-10 2023-6-11
24 2023-6-12 2023-6-13 2023-6-14 2023-6-15 2023-6-16 2023-6-17 2023-6-18
25 2023-6-19 2023-6-20 2023-6-21 2023-6-22 2023-6-23 2023-6-24 2023-6-25
26 2023-6-26 2023-6-27 2023-6-28 2023-6-29 2023-6-30
07 26 2023-7-1 2023-7-2
27 2023-7-3 2023-7-4 2023-7-5 2023-7-6 2023-7-7 2023-7-8 2023-7-9
28 2023-7-10 2023-7-11 2023-7-12 2023-7-13 2023-7-14 2023-7-15 2023-7-16
29 2023-7-17 2023-7-18 2023-7-19 2023-7-20 2023-7-21 2023-7-22 2023-7-23
30 2023-7-24 2023-7-25 2023-7-26 2023-7-27 2023-7-28 2023-7-29 2023-7-30
31 2023-7-31
08 31 2023-8-1 2023-8-2 2023-8-3 2023-8-4 2023-8-5 2023-8-6
32 2023-8-7 2023-8-8 2023-8-9 2023-8-10 2023-8-11 2023-8-12 2023-8-13
33 2023-8-14 2023-8-15 2023-8-16 2023-8-17 2023-8-18 2023-8-19 2023-8-20
34 2023-8-21 2023-8-22 2023-8-23 2023-8-24 2023-8-25 2023-8-26 2023-8-27
35 2023-8-28 2023-8-29 2023-8-30 2023-8-31
09 35 2023-9-1 2023-9-2 2023-9-3
36 2023-9-4 2023-9-5 2023-9-6 2023-9-7 2023-9-8 2023-9-9 2023-9-10
37 2023-9-11 2023-9-12 2023-9-13 2023-9-14 2023-9-15 2023-9-16 2023-9-17
38 2023-9-18 2023-9-19 2023-9-20 2023-9-21 2023-9-22 2023-9-23 2023-9-24
39 2023-9-25 2023-9-26 2023-9-27 2023-9-28 2023-9-29 2023-9-30
10 39 2023-10-1
40 2023-10-2 2023-10-3 2023-10-4 2023-10-5 2023-10-6 2023-10-7 2023-10-8
41 2023-10-9 2023-10-10 2023-10-11 2023-10-12 2023-10-13 2023-10-14 2023-10-15
42 2023-10-16 2023-10-17 2023-10-18 2023-10-19 2023-10-20 2023-10-21 2023-10-22
43 2023-10-23 2023-10-24 2023-10-25 2023-10-26 2023-10-27 2023-10-28 2023-10-29
44 2023-10-30 2023-10-31
11 44 2023-11-1 2023-11-2 2023-11-3 2023-11-4 2023-11-5
45 2023-11-6 2023-11-7 2023-11-8 2023-11-9 2023-11-10 2023-11-11 2023-11-12
46 2023-11-13 2023-11-14 2023-11-15 2023-11-16 2023-11-17 2023-11-18 2023-11-19
47 2023-11-20 2023-11-21 2023-11-22 2023-11-23 2023-11-24 2023-11-25 2023-11-26
48 2023-11-27 2023-11-28 2023-11-29 2023-11-30
12 48 2023-12-1 2023-12-2 2023-12-3
49 2023-12-4 2023-12-5 2023-12-6 2023-12-7 2023-12-8 2023-12-9 2023-12-10
50 2023-12-11 2023-12-12 2023-12-13 2023-12-14 2023-12-15 2023-12-16 2023-12-17
51 2023-12-18 2023-12-19 2023-12-20 2023-12-21 2023-12-22 2023-12-23 2023-12-24
01 52 2023-1-1
12 52 2023-12-25 2023-12-26 2023-12-27 2023-12-28 2023-12-29 2023-12-30 2023-12-31
63 rows selected
SQL>
この例から、with ステートメントを使用すると、思考とコード表示が非常に明確になり、ステップ t、t1、t2、および t3 が期待された目的を達成したかどうかを簡単に確認できることがわかります。 withステートメントの1つ。
要約する
この章で紹介する4つの時間操作のケースはまだ難しいですが、このレベルに達することができれば、時間タイプの操作は簡単に仕事をすることができるはずです〜