SQL初心者でもOK!Redshift Serverlessでデータ分析を始めよう! 「Redshift Serverless」を使った集計のSQL文を詳しく解説

 
YouTubeチャンネル「ルネッサ総合研究所 Webメディア&ラボ」では、AWSのアカウント作成から、Redshiftによるデータ集計・分析までを、丁寧に紹介しています。
 
このページでは、YouTubeの動画「Redshiftによる単純集計とクロス集計」を見ていただいたた方から要望の多かった、データ集計を行う際のSQL文の記述内容と、使用しているコマンドSELECT文、GROUP BY句、JOIN句など、集計に必須のSQL文について解説します(各行ごとの記述内容についてコメントでも解説)。
 

-------------------------
【YouTubeで解説している動画はこちら】
-------------------------
【再生リスト:Amazon Redshiftによるビッグデータ分析
Redshiftによる単純集計とクロス集計 #14 https://youtu.be/edukv5fwNis

 
動画で紹介している3つのSQL文は、いずれもPOSデータをはじめに分析し、店舗ごとの売上や客数などの情報を集計・比較するためのクエリです。
 
これらのSQL文は、POSデータの集計や分析を行う上で非常に一般的なもので、特にROLLUP句やCASE WHEN句、JOIN句などは、複雑な集計を行う際に役立ち、様々なビジネスロジックに応用できます。
 
ぜひ、この解説を参考に、Redshift Serverlessでデータ分析を始めてみませんか?
掲載している内容をサンプルとして活用し、売上データの分析はもちろん、Redshiftを使った様々なデータ集計・分析ができるようになります。

 
-------------------------
【こんな方におすすめ】
-------------------------
・Redshift Serverlessを使ってみたいけど、SQLが初めての方
・売上データを分析して、ビジネスに活かしたい方
・顧客の行動を可視化したい方
 

-------------------------
【学べること】
-------------------------
・Redshift Serverlessの基本的な使い方
・集計に必須のSQL文(SELECT、GROUP BY、JOINなど)
・売上分析による施策の検討方法

 
それでは、詳しく見ていきましょう。
 

-------------------------
【使用データ】
-------------------------
・データの内容:POSデータ
・ファイル形式:CSVファイル(カンマ区切り、UTF-8)
・データサイズ:約1.2GB
・データ件数 :1,000万件
・期間    :1年
-------------------------

-------------------------
【データ項目】
-------------------------
・店舗CD  :storecd
・年月日   :ymd
・販売時刻  :hms
・レシート番号:receipt
・顧客番号  :customer
・年齢    :age
・性別    :sex
・JANCD :jan
・メーカー名 :maker
・商品名   :item
・規格    :standard
・単価    :price
・数量    :quantity
・大分類CD :cate1cd
・中分類CD :cate2cd
・基礎分類CD:cate3cd
-------------------------

 

-------------------------
【SQL文の解説】
-------------------------

 

-------------------------
●単純集計:店舗別売上比較
-------------------------
単純集計:店舗別売上比較

・目的:店舗ごとの売上金額、数量、一品単価、バスケット数、バスケット単価、買上点数、会員数を集計
・特徴:ROLLUP句を用いて、店舗ごとの集計と全店舗の合計も同時に算出

select
    storecd as 店舗CD,                                                                                                               -- 店舗コード
    to_char(sum(abs(price)*quantity), 'fm999,999,999,999') as 売上金額,                                                              -- 期間内の店舗ごとの売上金額
    to_char(sum(quantity), 'fm999,999,999,999') as 数量,                                                                             -- 期間内の店舗ごとの販売数量
    to_char(round(cast(sum(abs(price)*quantity) as decimal)/sum(quantity), 2), 'fm999,999,999,999.9') as 一品単価,                   -- 期間内の店舗ごとの一品あたりの平均単価
    to_char(count(distinct receipt), 'fm999,999,999,999') as バスケット数,                                                           -- 期間内の店舗ごとのレシート数をカウント
    to_char(round(cast(sum(abs(price)*quantity) as decimal)/count(distinct receipt), 2), 'fm999,999,999,999.9') as バスケット単価,   -- 期間内の店舗ごとのバスケットあたりの平均金額
    to_char(round(cast(sum(quantity) as decimal)/count(distinct receipt), 2), 'fm999,999,999,999.9') as 買上点数,                    -- 期間内の店舗ごとのバスケットあたりの平均購入商品数
    to_char(count(distinct customer), 'fm999,999,999,999') as 会員数                                                                 -- 期間内の店舗ごとの会員数
from posdata                                                                                                                         -- 対象テーブル:POSデータ
where ymd >= 20240301 and ymd < 20250301                                                                                             -- 集計対象期間:2024年3月1日から2025年2月28日まで
group by ROLLUP(storecd)                                                                                                             -- 店舗コードでグループ化、小計(全店舗)算出
order by 店舗CD                                                                                                                      -- 店舗コードを使って昇順でソート

 

-------------------------
●店舗別売上_前年比
-------------------------
店舗別売上-前年比

・目的: 1つ目のSQLで得られた結果を基に、前年同期との比較を行い、売上金額、数量などの増減率を計算
・特徴: 今年度のデータと前年度のデータをJOINして比較

select
    master_store.storename as 店舗名,                                                                                                     -- 店舗マスタテーブルから店舗名を取得
    to_char(thisyear.売上金額, 'fm999,999,999,999') as 当年売上金額,                                                                      -- 当年の売上金額
    to_char(lastyear.売上金額, 'fm999,999,999,999') as 前年売上金額,                                                                      -- 前年の売上金額
    round((cast(thisyear.売上金額 as decimal)/cast(lastyear.売上金額 as decimal))*100, 1) || '%' as 売上金額_前年比,                      -- 売上金額の前年比を計算し、%表示
    to_char(thisyear.数量, 'fm999,999,999,999') as 当年売上数量,                                                                          -- 当年の売上数量
    to_char(lastyear.数量, 'fm999,999,999,999') as 前年売上数量,                                                                          -- 前年の売上数量
    round((cast(thisyear.数量 as decimal)/cast(lastyear.数量 as decimal)) * 100, 1) || '%' as 数量_前年比,                                -- 売上数量の前年比を計算し、%表示
    to_char(round(thisyear.一品単価, 2), 'fm999,999,999,999.9') as 当年一品単価,                                                          -- 当年の一品単価
    to_char(round(lastyear.一品単価, 2), 'fm999,999,999,999.9') as 前年一品単価,                                                          -- 前年の一品単価
    round((cast(thisyear.一品単価 as decimal)/cast(lastyear.一品単価 as decimal)) * 100, 1) || '%' as 一品単価_前年比,                    -- 売上数量の前年比を計算し、%表示
    to_char(thisyear.バスケット数, 'fm999,999,999,999') as 当年バスケット数,                                                              -- 当年のバスケット数
    to_char(lastyear.バスケット数, 'fm999,999,999,999') as 前年バスケット数,                                                              -- 前年のバスケット数
    round((cast(thisyear.バスケット数 as decimal)/cast(lastyear.バスケット数 as decimal)) * 100, 1) || '%' as バスケット数_前年比,        -- バスケット数の前年比を計算し、%表示
    to_char(round(thisyear.バスケット単価, 2), 'fm999,999,999,999.9') as 当年バスケット単価,                                              -- 当年のバスケット単価
    to_char(round(lastyear.バスケット単価, 2), 'fm999,999,999,999.9') as 前年バスケット単価,                                              -- 前年のバスケット単価
    round((cast(thisyear.バスケット単価 as decimal)/cast(lastyear.バスケット単価 as decimal)) * 100, 1) || '%' as バスケット単価_前年比,  -- バスケット単価の前年比を計算し、%表示
    to_char(round(thisyear.買上点数, 2), 'fm999,999,999,999.9') as 当年買上点数,                                                          -- 当年の買上点数
    to_char(round(lastyear.買上点数, 2), 'fm999,999,999,999.9') as 前年買上点数,                                                          -- 前年の買上点数
    round((cast(thisyear.買上点数 as decimal)/cast(lastyear.買上点数 as decimal)) * 100, 1) || '%' as 当年買上点数_前年比,                -- 買上点数の前年比を計算し、%表示
    to_char(thisyear.会員数, 'fm999,999,999,999') as 当年会員数,                                                                          -- 当年の会員数
    to_char(lastyear.会員数, 'fm999,999,999,999') as 前年会員数,                                                                          -- 前年の会員数
    round((cast(thisyear.会員数 as decimal)/cast(lastyear.会員数 as decimal)) * 100, 1) || '%' as 会員数_前年比                           -- 会員数の前年比を計算し、%表示
from
(
    select                                                         -- 当年の売上データを取得するサブクエリ
        coalesce(storecd,0) as 店舗CD,                             -- 店舗コード(NULLの場合は0に置換)
        sum(abs(price)*quantity) as 売上金額,                      -- 売上金額を計算
        sum(quantity) as 数量,                                     -- 数量を計算
        cast(売上金額 as decimal)/数量 as 一品単価,                -- 一品単価を計算
        count(distinct receipt) as バスケット数,                   -- バスケット数を計算
        cast(売上金額 as decimal)/バスケット数 as バスケット単価,  -- バスケット単価を計算
        cast(数量 as decimal)/バスケット数 as 買上点数,            -- 買上点数を計算
        count(distinct customer) as 会員数                         -- 会員数を計算
    from posdata                                                   -- 集計対象データ
    where ymd >= 20240301 and ymd < 20250301                       -- 集計対象期間:2024年3月1日~2025年2月28日
    group by ROLLUP(storecd)                                       -- 店舗コードでグループ化し、小計を算出
) as thisyear
join
(
    select                                                         -- 前年の売上データを取得するサブクエリ
        coalesce(storecd,0) as 店舗CD,                             -- 店舗コード(NULLの場合は0に置換)
        sum(abs(price)*quantity) as 売上金額,                      -- 売上金額を計算
        sum(quantity) as 数量,                                     -- 数量を計算
        cast(売上金額 as decimal)/数量 as 一品単価,                -- 一品単価を計算
        count(distinct receipt) as バスケット数,                   -- バスケット数を計算
        cast(売上金額 as decimal)/バスケット数 as バスケット単価,  -- バスケット単価を計算
        cast(数量 as decimal)/バスケット数 as 買上点数,            -- 買上点数を計算
        count(distinct customer) as 会員数                         -- 会員数を計算
    from posdata                                                   -- 集計対象データ
    where ymd >= 20230301 and ymd < 20240301                       -- 集計対象期間:2023年3月1日~2024年2月28日
    group by ROLLUP(storecd)
) as lastyear
on thisyear.店舗CD = lastyear.店舗CD                               -- 当年と前年のデータで店舗コードを結合
join master_store on thisyear.店舗CD = master_store.storecd        -- 店舗マスタテーブルと結合
order by thisyear.店舗CD                                           -- 店舗コードで昇順にソート

 

-------------------------
●店舗別売上_月別前年比(3か月)
-------------------------
店舗別売上-前年比(月別3か月)

・目的: 2つのSQLと同様に、店舗ごとの売上などを集計し、前年同月比を計算し、月ごとの詳細な比較ができるよう集計
・特徴: CASE WHEN句を用いて、月ごとの売上金額などを算出

select
    master_store.storename as 店舗名                                                                                                 -- 店舗名を取得
    ,to_char(thisyear.3月売上金額, 'fm999,999,999,999') as "2024年3月売上金額"                                                      -- 当年3月の売上金額
    ,to_char(lastyear.3月売上金額, 'fm999,999,999,999') as "2023年3月売上金額"                                                      -- 前年3月の売上金額
    ,round((cast(thisyear.3月売上金額 as decimal)/cast(lastyear.3月売上金額 as decimal))*100, 1) || '%' as 前年同月比              -- 売上金額の前年同月比を計算し、%表示
    ,to_char(thisyear.3月数量, 'fm999,999,999,999') as "2024年3月売上数量"                                                          -- 当年3月の売上数量
    ,to_char(lastyear.3月数量, 'fm999,999,999,999') as "2023年3月売上数量"                                                          -- 前年3月の売上数量
    ,round((cast(thisyear.3月数量 as decimal)/cast(lastyear.3月数量 as decimal))*100, 1) || '%' as 前年同月比                      -- 売上数量の前年同月比を計算し、%表示
    ,to_char(round(thisyear.3月一品単価, 2), 'fm999,999,999,999.9') as "2024年3月一品単価"                                          -- 当年3月の一品単価
    ,to_char(round(lastyear.3月一品単価, 2), 'fm999,999,999,999.9') as "2023年3月一品単価"                                          -- 前年3月の一品単価
    ,round((cast(thisyear.3月一品単価 as decimal)/cast(lastyear.3月一品単価 as decimal))*100, 1) || '%' as 前年同月比              -- 一品単価の前年同月比を計算し、%表示
    ,to_char(thisyear.3月バスケット数, 'fm999,999,999,999') as "2024年3月バスケット数"                                              -- 当年3月のバスケット数
    ,to_char(lastyear.3月バスケット数, 'fm999,999,999,999') as "2023年3月バスケット数"                                              -- 前年3月のバスケット数
    ,round((cast(thisyear.3月バスケット数 as decimal)/cast(lastyear.3月バスケット数 as decimal))*100, 1) || '%' as 前年同月比      -- バスケット数の前年同月比を計算し、%表示
    ,to_char(round(thisyear.3月バスケット単価, 2), 'fm999,999,999,999.9') as "2024年3月バスケット単価"                              -- 当年3月のバスケット単価
    ,to_char(round(lastyear.3月バスケット単価, 2), 'fm999,999,999,999.9') as "2023年3月バスケット単価"                              -- 前年3月のバスケット単価
    ,round((cast(thisyear.3月バスケット単価 as decimal)/cast(lastyear.3月バスケット単価 as decimal))*100, 1) || '%' as 前年同月比  -- バスケット単価の前年同月比を計算し、%表示
    ,to_char(round(thisyear.3月買上点数, 2), 'fm999,999,999,999.9') as "2024年3月買上点数"                                          -- 当年3月の買上点数
    ,to_char(round(lastyear.3月買上点数, 2), 'fm999,999,999,999.9') as "2023年3月買上点数"                                          -- 前年3月の買上点数
    ,round((cast(thisyear.3月買上点数 as decimal)/cast(lastyear.3月買上点数 as decimal))*100, 1) || '%' as 前年同月比              -- 買上点数の前年同月比を計算し、%表示
    ,to_char(thisyear.3月会員数, 'fm999,999,999,999') as "2024年3月会員数"                                                          -- 当年3月の会員数
    ,to_char(lastyear.3月会員数, 'fm999,999,999,999') as "2023年3月会員数"                                                          -- 前年3月の会員数
    ,round((cast(thisyear.3月会員数 as decimal)/cast(lastyear.3月会員数 as decimal))*100, 1) || '%' as 前年同月比                  -- 会員数の前年同月比を計算し、%表示
    ,to_char(thisyear.4月売上金額, 'fm999,999,999,999') as "2024年4月売上金額"                                                      -- 当年4月の売上金額
    ,to_char(lastyear.4月売上金額, 'fm999,999,999,999') as "2023年4月売上金額"                                                      -- 前年4月の売上金額
    ,round((cast(thisyear.4月売上金額 as decimal)/cast(lastyear.4月売上金額 as decimal))*100, 1) || '%' as 前年同月比              -- 売上金額の前年同月比を計算し、%表示
    ,to_char(thisyear.4月数量, 'fm999,999,999,999') as "2024年4月売上数量"                                                          -- 当年4月の売上数量
    ,to_char(lastyear.4月数量, 'fm999,999,999,999') as "2023年4月売上数量"                                                          -- 前年4月の売上数量
    ,round((cast(thisyear.4月数量 as decimal)/cast(lastyear.4月数量 as decimal))*100, 1) || '%' as 前年同月比                      -- 売上数量の前年同月比を計算し、%表示
    ,to_char(round(thisyear.4月一品単価, 2), 'fm999,999,999,999.9') as "2024年4月一品単価"                                          -- 当年4月の一品単価
    ,to_char(round(lastyear.4月一品単価, 2), 'fm999,999,999,999.9') as "2023年4月一品単価"                                          -- 前年4月の一品単価
    ,round((cast(thisyear.4月一品単価 as decimal)/cast(lastyear.4月一品単価 as decimal))*100, 1) || '%' as 前年同月比              -- 一品単価の前年同月比を計算し、%表示
    ,to_char(thisyear.4月バスケット数, 'fm999,999,999,999') as "2024年4月バスケット数"                                              -- 当年4月のバスケット数
    ,to_char(lastyear.4月バスケット数, 'fm999,999,999,999') as "2023年4月バスケット数"                                              -- 前年4月のバスケット数
    ,round((cast(thisyear.4月バスケット数 as decimal)/cast(lastyear.4月バスケット数 as decimal))*100, 1) || '%' as 前年同月比      -- バスケット数の前年同月比を計算し、%表示
    ,to_char(round(thisyear.4月バスケット単価, 2), 'fm999,999,999,999.9') as "2024年4月バスケット単価"                              -- 当年4月のバスケット単価
    ,to_char(round(lastyear.4月バスケット単価, 2), 'fm999,999,999,999.9') as "2023年4月バスケット単価"                              -- 前年4月のバスケット単価
    ,round((cast(thisyear.4月バスケット単価 as decimal)/cast(lastyear.4月バスケット単価 as decimal))*100, 1) || '%' as 前年同月比  -- バスケット単価の前年同月比を計算し、%表示
    ,to_char(round(thisyear.4月買上点数, 2), 'fm999,999,999,999.9') as "2024年4月買上点数"                                          -- 当年4月の買上点数
    ,to_char(round(lastyear.4月買上点数, 2), 'fm999,999,999,999.9') as "2023年4月買上点数"                                          -- 前年4月の買上点数
    ,round((cast(thisyear.4月買上点数 as decimal)/cast(lastyear.4月買上点数 as decimal))*100, 1) || '%' as 前年同月比              -- 買上点数の前年同月比を計算し、%表示
    ,to_char(thisyear.4月会員数, 'fm999,999,999,999') as "2024年4月会員数"                                                          -- 当年4月の会員数
    ,to_char(lastyear.4月会員数, 'fm999,999,999,999') as "2023年4月会員数"                                                          -- 前年4月の会員数
    ,round((cast(thisyear.4月会員数 as decimal)/cast(lastyear.4月会員数 as decimal))*100, 1) || '%' as 前年同月比                  -- 会員数の前年同月比を計算し、%表示
    ,to_char(thisyear.5月売上金額, 'fm999,999,999,999') as "2024年5月売上金額"                                                      -- 当年5月売上金額
    ,to_char(lastyear.5月売上金額, 'fm999,999,999,999') as "2023年5月売上金額"                                                      -- 前年5月売上金額
    ,round((cast(thisyear.5月売上金額 as decimal)/cast(lastyear.5月売上金額 as decimal))*100, 1) || '%' as 前年同月比              -- 売上金額の前年同月比を計算し、%表示
    ,to_char(thisyear.5月数量, 'fm999,999,999,999') as "2024年5月売上数量"                                                          -- 当年5月売上数量
    ,to_char(lastyear.5月数量, 'fm999,999,999,999') as "2023年5月売上数量"                                                          -- 前年5月売上数量
    ,round((cast(thisyear.5月数量 as decimal)/cast(lastyear.5月数量 as decimal))*100, 1) || '%' as 前年同月比                      -- 売上数量の前年同月比を計算し、%表示
    ,to_char(round(thisyear.5月一品単価, 2), 'fm999,999,999,999.9') as "2024年5月一品単価"                                          -- 当年5月一品単価
    ,to_char(round(lastyear.5月一品単価, 2), 'fm999,999,999,999.9') as "2023年5月一品単価"                                          -- 前年5月一品単価
    ,round((cast(thisyear.5月一品単価 as decimal)/cast(lastyear.5月一品単価 as decimal))*100, 1) || '%' as 前年同月比              -- 一品単価の前年同月比を計算し、%表示
    ,to_char(thisyear.5月バスケット数, 'fm999,999,999,999') as "2024年5月バスケット数"                                              -- 当年5月バスケット数
    ,to_char(lastyear.5月バスケット数, 'fm999,999,999,999') as "2023年5月バスケット数"                                              -- 前年5月バスケット数
    ,round((cast(thisyear.5月バスケット数 as decimal)/cast(lastyear.5月バスケット数 as decimal))*100, 1) || '%' as 前年同月比      -- バスケット数の前年同月比を計算し、%表示
    ,to_char(round(thisyear.5月バスケット単価, 2), 'fm999,999,999,999.9') as "2024年5月バスケット単価"                              -- 当年5月のバスケット単価
    ,to_char(round(lastyear.5月バスケット単価, 2), 'fm999,999,999,999.9') as "2023年5月バスケット単価"                              -- 前年5月のバスケット単価
    ,round((cast(thisyear.5月バスケット単価 as decimal)/cast(lastyear.5月バスケット単価 as decimal))*100, 1) || '%' as 前年同月比  -- バスケット単価の前年同月比を計算し、%表示
    ,to_char(round(thisyear.5月買上点数, 2), 'fm999,999,999,999.9') as "2024年5月買上点数"                                          -- 当年5月の買上点数
    ,to_char(round(lastyear.5月買上点数, 2), 'fm999,999,999,999.9') as "2023年5月買上点数"                                          -- 前年5月の買上点数
    ,round((cast(thisyear.5月買上点数 as decimal)/cast(lastyear.5月買上点数 as decimal))*100, 1) || '%' as 前年同月比              -- 買上点数の前年同月比を計算し、%表示
    ,to_char(thisyear.5月会員数, 'fm999,999,999,999') as "2024年5月会員数"                                                          -- 当年5月の会員数
    ,to_char(lastyear.5月会員数, 'fm999,999,999,999') as "2023年5月会員数"                                                          -- 前年4月の会員数
    ,round((cast(thisyear.5月会員数 as decimal)/cast(lastyear.5月会員数 as decimal))*100, 1) || '%' as 前年同月比                  -- 会員数の前年同月比を計算し、%表示
from
(
select                                                                                                                               -- 当年の売上データを取得するサブクエリ
        coalesce(storecd,0) as 店舗CD                                                                                                -- 店舗コード(NULLの場合は0に置換)
        ,sum(case when (ymd >= 20240301 and ymd <= 20240331) then abs(price)*quantity else 0 end) as "3月売上金額"                  -- 3月売上金額を計算 (CASE WHENを使って月別に集計)
        ,sum(case when (ymd >= 20240401 and ymd <= 20240430) then abs(price)*quantity else 0 end) as "4月売上金額"                  -- 4月売上金額
        ,sum(case when (ymd >= 20240501 and ymd <= 20240531) then abs(price)*quantity else 0 end) as "5月売上金額"                  -- 5月売上金額
        ,sum(case when (ymd >= 20240301 and ymd <= 20240331) then quantity else 0 end) as "3月数量"                                 -- 3月売上数量を計算 (CASE WHENを使って月別に集計)
        ,sum(case when (ymd >= 20240401 and ymd <= 20240430) then quantity else 0 end) as "4月数量"                                 -- 4月売上数量
        ,sum(case when (ymd >= 20240501 and ymd <= 20240531) then quantity else 0 end) as "5月数量"                                 -- 5月売上数量
        ,cast(3月売上金額 as decimal)/3月数量 as "3月一品単価"                                                                    -- 3月一品単価を計算 (CASE WHENを使って月別に集計)
        ,cast(4月売上金額 as decimal)/4月数量 as "4月一品単価"                                                                    -- 4月一品単価
        ,cast(5月売上金額 as decimal)/5月数量 as "5月一品単価"                                                                    -- 5月一品単価
        ,count(distinct case when (ymd >= 20240301 and ymd <= 20240331) then receipt else null end) as "3月バスケット数"            -- 3月バスケット数を計算 (CASE WHENを使って月別に集計。DISINCTで重複を除外)
        ,count(distinct case when (ymd >= 20240401 and ymd <= 20240430) then receipt else null end) as "4月バスケット数"            -- 4月バスケット数
        ,count(distinct case when (ymd >= 20240501 and ymd <= 20240531) then receipt else null end) as "5月バスケット数"            -- 5月バスケット数
        ,cast(3月売上金額 as decimal)/3月バスケット数 as "3月バスケット単価"                                                      -- 3月バスケット単価を計算 (CASE WHENを使って月別に集計)
        ,cast(4月売上金額 as decimal)/4月バスケット数 as "4月バスケット単価"                                                      -- 4月バスケット単価
        ,cast(5月売上金額 as decimal)/5月バスケット数 as "5月バスケット単価"                                                      -- 5月バスケット単価
        ,cast(3月数量 as decimal)/3月バスケット数 as "3月買上点数"                                                                -- 3月買上点数を計算 (CASE WHENを使って月別に集計)
        ,cast(4月数量 as decimal)/4月バスケット数 as "4月買上点数"                                                                -- 4月買上点数
        ,cast(5月数量 as decimal)/5月バスケット数 as "5月買上点数"                                                                -- 5月買上点数
        ,count(distinct case when (ymd >= 20240301 and ymd <= 20240331) then customer else null end) as "3月会員数"                 -- 3月会員数を計算 (CASE WHENを使って月別に集計。DISINCTで重複を除外)
        ,count(distinct case when (ymd >= 20240401 and ymd <= 20240430) then customer else null end) as "4月会員数"                 -- 4月会員数
        ,count(distinct case when (ymd >= 20240501 and ymd <= 20240531) then customer else null end) as "5月会員数"                 -- 5月会員数
    from posdata                                                                                                                     -- 集計対象テーブル
    where ymd >= 20240301 and ymd <= 20240531                                                                                        -- 集計対象期間:2024年3月1日~5月31日のデータ
    group by ROLLUP(storecd)                                                                                                         -- 店舗コードでグループ化し、小計を算出
) as thisyear
join
(
select                                                                                                                               -- 前年の売上データを取得するサブクエリ
        coalesce(storecd,0) as 店舗CD
        ,sum(case when (ymd >= 20230301 and ymd <= 20230331) then abs(price)*quantity else 0 end) as "3月売上金額"
        ,sum(case when (ymd >= 20230401 and ymd <= 20230430) then abs(price)*quantity else 0 end) as "4月売上金額"
        ,sum(case when (ymd >= 20230501 and ymd <= 20230531) then abs(price)*quantity else 0 end) as "5月売上金額"
        ,sum(case when (ymd >= 20230301 and ymd <= 20230331) then quantity else 0 end) as "3月数量"
        ,sum(case when (ymd >= 20230401 and ymd <= 20230430) then quantity else 0 end) as "4月数量"
        ,sum(case when (ymd >= 20230501 and ymd <= 20230531) then quantity else 0 end) as "5月数量"
        ,cast(3月売上金額 as decimal)/3月数量 as "3月一品単価"
        ,cast(4月売上金額 as decimal)/4月数量 as "4月一品単価"
        ,cast(5月売上金額 as decimal)/5月数量 as "5月一品単価"
        ,count(distinct case when (ymd >= 20230301 and ymd <= 20230331) then receipt else null end) as "3月バスケット数"
        ,count(distinct case when (ymd >= 20230401 and ymd <= 20230430) then receipt else null end) as "4月バスケット数"
        ,count(distinct case when (ymd >= 20230501 and ymd <= 20230531) then receipt else null end) as "5月バスケット数"
        ,cast(3月売上金額 as decimal)/3月バスケット数 as "3月バスケット単価"
        ,cast(4月売上金額 as decimal)/4月バスケット数 as "4月バスケット単価"
        ,cast(5月売上金額 as decimal)/5月バスケット数 as "5月バスケット単価"
        ,cast(3月数量 as decimal)/3月バスケット数 as "3月買上点数"
        ,cast(4月数量 as decimal)/4月バスケット数 as "4月買上点数"
        ,cast(5月数量 as decimal)/5月バスケット数 as "5月買上点数"
        ,count(distinct case when (ymd >= 20230301 and ymd <= 20230331) then customer else null end) as "3月会員数"
        ,count(distinct case when (ymd >= 20230401 and ymd <= 20230430) then customer else null end) as "4月会員数"
        ,count(distinct case when (ymd >= 20230501 and ymd <= 20230531) then customer else null end) as "5月会員数"
    from posdata
    where ymd >= 20230301 and ymd <= 20230531
    group by ROLLUP(storecd)
) as lastyear
on thisyear.店舗CD = lastyear.店舗CD                                                                                                 -- 当年と前年のデータで店舗コードを結合
join master_store on thisyear.店舗CD = master_store.storecd                                                                          -- 店舗マスタテーブルと結合
order by thisyear.店舗CD                                                                                                             -- 店舗コードで昇順にソート

 
 

-------------------------
【使用している主なコマンドの解説】
-------------------------

 

●SELECT文
・目 的:データベースからデータを取り出す
・使い方:SELECT 項目名 FROM テーブル名
・構 文:SELECT column1, column2, …
       FROM table_name
       WHERE condition;
       *column1, column2, …: 取得したいカラム名を指定
       *table_name: データを取得するテーブル名
       *WHERE condition: 取得するデータの条件を指定

●FROM句
・目 的:データを取得する対象のテーブルの指定
・使い方:FROM テーブル名

●WHERE句
・目 的:取得するデータを絞り込むための条件の指定
・使い方:WHERE 条件式
・例  :where ymd >= 20240301 and ymd < 20250301
       ※ymdカラムの値が2024年3月1日以降かつ2025年3月1日未満のデータを取得

●GROUP BY句
・目 的:データをグループ化し、各グループの集計
・使い方:GROUP BY 項目名
・例  :group by ROLLUP(storecd)
       ※storecdカラムでグループ化し、さらに全店舗の合計も算出

●ROLLUP句
・目 的:GROUP BY句と併用し、階層的な集計(グループ階層を作成し、小計や合計を計算)
・例  :上記の例のように、店舗ごとの集計と全店舗の合計を同時に算出

●SUM関数
・目 的:数値型のデータの合計を計算
・使い方:SUM(カラム名)

●COUNT関数
・目 的:データの数を数える。
・使い方:COUNT(*)         (すべての行を数える)
       COUNT(DISTINCT カラム名) (指定したカラムの異なる値の数を数える)

●TO_CHAR関数
・目 的:数値データを文字列に変換
・例  :to_char(sum(abs(price)*quantity), ‘fm999,999,999,999’)
       ※売上金額を3桁区切りで表示

●ROUND関数
・目 的:小数点以下を丸める
・使い方:ROUND(数値, 小数点以下の桁数)

●CAST関数
・目 的:データ型を変換
・使い方:CAST(値 AS データ型)

●JOIN句
・目 的:複数のテーブルのデータを結合
・使い方:JOIN テーブル名 ON 結合条件
・例  :join master_store on thisyear.店舗CD = master_store.storecd
       ※thisyearテーブルとmaster_storeテーブルを店舗CDで結合する。

●COALESCE関数
・目 的:NULL値を他の値に置換
・使い方:COALESCE(値1, 値2)

●CASE WHEN句
・目 的:複数の条件分岐
・使い方:CASE WHEN 条件1 THEN 値1
       WHEN 条件2 THEN 値2
       ELSE 値3
       END
・例  :sum(case when(ymd >= 20240301 and ymd <= 20240331)
       then abs(price)*quantity else 0 end)
       ※ymdが2024年3月の場合、売上金額を計算し、それ以外は0とする

●ORDER BY
・目 的:結果を特定の項目で昇順または降順にソート
・使い方:ORDER BY 項目名 ASC/DESC

●その他
・abs(price): 絶対値を計算することで、マイナス値の価格を正の値に変換
・distinct :重複するデータを排除し、一意な値だけを数える
・別   名: ASキーワードを使って、カラムやテーブルに別名を付けることが可能
・演算子  : +, -, *, /, >, <, =などの演算子を用いて条件式や計算式を記述


=========================

■ Amaozn Redshift
  高速でシンプルかつ費用対効果の高いデータウェアハウスサービス
  https://aws.amazon.com/jp/redshift/
■ Z-Adam
  大量データの分析に最適な環境と高速集計を実現する新世代統計集計システム
  https://www.zetta.co.jp/products/z-adam/

=========================

■ データサイエンティスト育成支援サービス[スタビジ/スタアカ]
  人気のデータサイエンス系eラーニングコンテンツによる人材育成
  法人・自治体向け「データサイエンティスト育成支援サービス」
  https://www.zetta.co.jp/bigdata/dsis/
■ スタアカ(ご紹介YouTube)
  データサイエンスを学ぶならスタビジアカデミー(スタアカ)!
  https://www.youtube.com/watch?v=F5Erqilyhfs
■ スタアカ
  AIデータサイエンス特化スクール
  https://toukei-lab.com/achademy/
■ スタビジ(Webメディア)
  ビジネスに活かせるデータサイエンス(Statistics business)を発信するメディア
  https://toukei-lab.com/
■ スタビジ(YouTube)
  誰でもAIデータサイエンス by ウマたん
  https://www.youtube.com/@aiby8596
■ Udemy:ウマたん(上野佑馬)
  AI、データサイエンス、デジタルマーケティング、プログラミングを学ぶなら
  https://www.udemy.com/user/shang-ye-you-ma/