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

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

ただいまの
回答率

90.47%

  • SQL

    2470questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

  • SQL Server

    603questions

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

結合したいテーブルが行数が違うかつ、NULLの入ったテーブルを結合したい

受付中

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,683

NK1994

score 3

前提・実現したいこと

sqlserver 初心者です。
今回はタイトルのごとく、結合したいテーブルが行数が違うかつ、NULLの入ったテーブルを結合したいです。

結合するもの↓
グループコード,店舗997の売上売価
NULL    694.00
0001    47162.00
0003    90980.00
0004    61136.00
0005    23659.00
0006    13819.00
0007    19187.00
0008    86637.00
0009    40476.00
0010    30813.00
0011    8831.00
0013    81441.00
0014    67821.00
0015    23294.00
0016    1690.00
0017    23659.00

グループコード,店舗998の売上売価
NULL    498340.00
0003    742.00
0004    22624.00
0005    1838.00
0006    3738.00
0007    3599.00
0008    32522.00
0010    3954.00
0014    5118.00
0015    3078.00
0016    900.00
0017    4800.00

グループコード,店舗999の売上売価
NULL    7880.00
0001    221761.00
0003    311382.00
0004    224474.00
0005    91251.00
0006    39771.00
0007    28180.00
0008    280208.00
0009    8272.00
0010    79309.00
0011    35958.00
0012    10110.00
0013    234175.00
0014    170795.00
0015    7114.00
0016    45018.00
0017    103056.00

表示結果としては↓を目指しています。

グループコード,店舗997の売上売価,店舗998の売上売価,店舗999の売上売価
NULL     694.00 498340.00 7880.00
0001     47162.00 NULL      221761.00
0003      90980.00         742.00             311382.00
0004         61136.00         22624.00           224474.00
0005         23659.00         1838.00            91251.00
0006         13819.00         3738.00            39771.00
0007         19187.00         3599.00            28180.00
0008         86637.00         32522.00           280208.00
0009         40476.00         NULL               8272.00
0010         30813.00        3954.00             79309.00
0011         8831.00          NULL               35958.00
0012     NULL             NULL               10110.00
0013         81441.00          NULL              234175.00
0014         67821.00         5118.00            170795.00
0015         23294.00         3078.00            7114.00
0016         1690.00          900.00             45018.00
0017         23659.00         4800.00            103056.00

発生している問題・エラーメッセージ・該当のソースコード

そもそも行数が違うテーブルを結合できるかどうかすらわかりません。
第一にそこが知りたいです。

現状の問題としては、joinの仕方が悪いのか、結合条件がわるいのかで数値がうまく表示されません。
店舗998と999の売上売価がNULLになってしまいます。

問題対象のコード↓
select
GRP.グループコード,
SUM(s1. 売上売価) AS 店舗997の売上売価,
SUM(s2. 売上売価) AS 店舗998の売上売価,
SUM(s3. 売上売価) AS 店舗999の売上売価
from 
     (select SYODAY.店舗コード , SYODAY.商品コード, sum(SYODAY.売上売価) as 売上売価
      from SYODAY

      where 日付 = '20141126' and SYODAY.店舗コード = '997'
      group by SYODAY.店舗コード , SYODAY.商品コード

     )as s1 left join SYO on SYO.店舗コード = s1.店舗コード
                         and SYO.商品コード = s1.商品コード                       

left join(select SYODAY.店舗コード , SYODAY.商品コード, sum(SYODAY.売上売価) as 売上売価
          from SYODAY

          where 日付 = '20141126' and SYODAY.店舗コード = '998'
          group by SYODAY.店舗コード , SYODAY.商品コード

           ) as s2 on SYO.店舗コード = s2.店舗コード
                  and SYO.商品コード = s2.商品コード 

left join(select SYODAY.店舗コード , SYODAY.商品コード,sum(SYODAY.売上売価) as 売上売価
          from SYODAY

           where 日付 = '20141126' and SYODAY.店舗コード = '999'
           group by SYODAY.店舗コード , SYODAY.商品コード

           ) as s3 on SYO.店舗コード = s3.店舗コード
                  and SYO.商品コード = s3.商品コード 

left join CLS on CLS.店舗コード = SYO.店舗コード
              and CLS.クラスコード = SYO.クラスコード
left join BUM on BUM.店舗コード = CLS.店舗コード 
              and BUM.部門コード = CLS.部門コード
left join GRP on GRP.店舗コード = BUM.店舗コード 
              and GRP.グループコード = BUM.グループコード

group by GRP.グループコード
order by GRP.グループコード

このコードのようにサブクエリによる結合をしたいですが、うまく表示されません

グループコード,店舗997の売上売価,店舗998の売上売価,店舗999の売上売価
NULL     694.00 NULL NULL
0001     47162.00 NULL      NULL
0003      90980.00         NULL  NULL
0004         61136.00         NULL               NULL
0005         23659.00         NULL               NULL
0006         13819.00         NULL               NULL
0007         19187.00         NULL              NULL
0008         86637.00         NULL               NULL
0009         40476.00         NULL               NULL
0010         30813.00         NULL              NULL
0011         8831.00          NULL               NULL
0012     NULL             NULL               NULL
0013         81441.00         NULL              NULL
0014         67821.00         NULL              NULL
0015         23294.00         NULL               NULL
0016         1690.00          NULL               NULL
0017         23659.00         NULL              NULL

この結果の店舗998,999のNULLの部分を正しいものを表示させたいです。

試したこと

上のコードのJOINや結合条件をいろいろいじってみましたがうまくいきません。
店舗コードをばらばらに表示するのはうまくいきます。
どうか皆様のお力をお貸しください。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

0

(書いてある各店舗の売り上げの例と動かないSQLの列名・テーブル名は合わさないと回答する側としてはわかりにくいです。)

とりあえず見た感じ、そもそもメインの表が店舗997にあるデータしか集計できていないように見えます。
また、どこまでをNULLにしたいのかも分からないのでパフォーマンスと見た目は度外視して書いてあるSQLをベースに考えてみました

1.店舗997~999で発生している売り上げのグループコードを一覧化しましょう。

select
    売上グループ.グループコード
from
    (
        select 
            GRP.グループコード
        from 
            SYODAY
            LEFT OUTER JOIN SYO ON
                SYO.店舗コード = SYODAY.店舗コード
                and SYO.商品コード = SYODAY.商品コード  
            left join CLS on 
                CLS.店舗コード = SYO.店舗コード
                and CLS.クラスコード = SYO.クラスコード
            left join BUM on 
                BUM.店舗コード = CLS.店舗コード 
                and BUM.部門コード = CLS.部門コード
            left join GRP on 
                GRP.店舗コード = BUM.店舗コード 
                and GRP.グループコード = BUM.グループコード
        where
            日付 = '20141126'
            AND SYODAY.店舗コード IN ('997', '998', '999')
        group by
            GRP.グループコード
    ) 売上グループ


これでほしい回答にあるNULL、0001~0017までの一覧ができます。

2.各店舗の集計(例:店舗997)

select 
    GRP.グループコード
    ,SUM(SYODAY.売上売価) AS 売上売価
from 
    SYODAY
    LEFT OUTER JOIN SYO ON
        SYO.店舗コード = SYODAY.店舗コード
        and SYO.商品コード = SYODAY.商品コード  
    left join CLS on 
        CLS.店舗コード = SYO.店舗コード
        and CLS.クラスコード = SYO.クラスコード
    left join BUM on 
        BUM.店舗コード = CLS.店舗コード 
        and BUM.部門コード = CLS.部門コード
    left join GRP on 
        GRP.店舗コード = BUM.店舗コード 
        and GRP.グループコード = BUM.グループコード
where
    日付 = '20141126'
    AND SYODAY.店舗コード = '997'
group by
    GRP.グループコード

3.それらを結合

select
    売上グループ.グループコード
    ,店舗997売上.売上売価 AS 店舗997売上売価
    ,店舗998売上.売上売価 AS 店舗998売上売価
    ,店舗999売上.売上売価 AS 店舗999売上売価
from
    (
        select 
            GRP.グループコード
        from 
            SYODAY
            LEFT OUTER JOIN SYO ON
                SYO.店舗コード = SYODAY.店舗コード
                and SYO.商品コード = SYODAY.商品コード  
            left join CLS on 
                CLS.店舗コード = SYO.店舗コード
                and CLS.クラスコード = SYO.クラスコード
            left join BUM on 
                BUM.店舗コード = CLS.店舗コード 
                and BUM.部門コード = CLS.部門コード
            left join GRP on 
                GRP.店舗コード = BUM.店舗コード 
                and GRP.グループコード = BUM.グループコード
        where
            日付 = '20141126'
            AND SYODAY.店舗コード IN ('997', '998', '999')
        group by
            GRP.グループコード
    ) 売上グループ
    left outer join
        (
            select 
                GRP.グループコード
                ,SUM(SYODAY.売上売価) AS 売上売価
            from 
                SYODAY
                LEFT OUTER JOIN SYO ON
                    SYO.店舗コード = SYODAY.店舗コード
                    and SYO.商品コード = SYODAY.商品コード  
                left join CLS on 
                    CLS.店舗コード = SYO.店舗コード
                    and CLS.クラスコード = SYO.クラスコード
                left join BUM on 
                    BUM.店舗コード = CLS.店舗コード 
                    and BUM.部門コード = CLS.部門コード
                left join GRP on 
                    GRP.店舗コード = BUM.店舗コード 
                    and GRP.グループコード = BUM.グループコード
            where
                日付 = '20141126'
                AND SYODAY.店舗コード = '997'
            group by
                GRP.グループコード
        ) 店舗997売上 ON 売上グループ.グループコード = 店舗997売上.グループコード
    left outer join
        (
            select 
                GRP.グループコード
                ,SUM(SYODAY.売上売価) AS 売上売価
            from 
                SYODAY
                LEFT OUTER JOIN SYO ON
                    SYO.店舗コード = SYODAY.店舗コード
                    and SYO.商品コード = SYODAY.商品コード  
                left join CLS on 
                    CLS.店舗コード = SYO.店舗コード
                    and CLS.クラスコード = SYO.クラスコード
                left join BUM on 
                    BUM.店舗コード = CLS.店舗コード 
                    and BUM.部門コード = CLS.部門コード
                left join GRP on 
                    GRP.店舗コード = BUM.店舗コード 
                    and GRP.グループコード = BUM.グループコード
            where
                日付 = '20141126'
                AND SYODAY.店舗コード = '998'
            group by
                GRP.グループコード
        ) 店舗998売上 ON 売上グループ.グループコード = 店舗998売上.グループコード
    left outer join
        (
            select 
                GRP.グループコード
                ,SUM(SYODAY.売上売価) AS 売上売価
            from 
                SYODAY
                LEFT OUTER JOIN SYO ON
                    SYO.店舗コード = SYODAY.店舗コード
                    and SYO.商品コード = SYODAY.商品コード  
                left join CLS on 
                    CLS.店舗コード = SYO.店舗コード
                    and CLS.クラスコード = SYO.クラスコード
                left join BUM on 
                    BUM.店舗コード = CLS.店舗コード 
                    and BUM.部門コード = CLS.部門コード
                left join GRP on 
                    GRP.店舗コード = BUM.店舗コード 
                    and GRP.グループコード = BUM.グループコード
            where
                日付 = '20141126'
                AND SYODAY.店舗コード = '999'
            group by
                GRP.グループコード
        ) 店舗999売上 ON 売上グループ.グループコード = 店舗999売上.グループコード

汎用性も何もありませんがとりあえず上記のような感じでどうでしょう?
※テーブル構造や売り上げが無い店舗の部分が0でもいいのであればもう少し整理できます。
また、共通テーブル式も使えるのであれば上記SQLはもう少しシンプルに書けます。

WITH 店舗売上 AS (
        select 
            GRP.グループコード
            ,SYODAY.店舗コード
            ,SUM(SYODAY.売上売価) AS 売上売価
        from 
            SYODAY
            LEFT OUTER JOIN SYO ON
                SYO.店舗コード = SYODAY.店舗コード
                and SYO.商品コード = SYODAY.商品コード  
            left join CLS on 
                CLS.店舗コード = SYO.店舗コード
                and CLS.クラスコード = SYO.クラスコード
            left join BUM on 
                BUM.店舗コード = CLS.店舗コード 
                and BUM.部門コード = CLS.部門コード
            left join GRP on 
                GRP.店舗コード = BUM.店舗コード 
                and GRP.グループコード = BUM.グループコード
        where
            日付 = '20141126'
            AND SYODAY.店舗コード IN ('997', '998', '999')
        group by
            GRP.グループコード
            ,SYODAY.店舗コード
     )
SELECT
    売上グループ.グループコード
FROM
    (
        SELECT
            グループコード
        FROM
            店舗売上
        GROUP BY
            グループコード
    ) 売上グループ
    left outer join
        (
            select 
                グループコード
                ,売上売価
            from 
                店舗売上
            where
                店舗コード = '997'
        ) 店舗997売上 ON 売上グループ.グループコード = 店舗997売上.グループコード
    left outer join
        (
            select 
                グループコード
                ,売上売価
            from 
                店舗売上
            where
                店舗コード = '998'
        ) 店舗998売上 ON 売上グループ.グループコード = 店舗998売上.グループコード
    left outer join
        (
            select 
                グループコード
                ,売上売価
            from 
                店舗売上
            where
                店舗コード = '999'
        ) 店舗999売上 ON 売上グループ.グループコード = 店舗999売上.グループコード

試してないので単純なミスもあるかもしれませんがとりあえずヒントにでもなれば・・

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/16 18:46

    アドバイスありがとうございました

    キャンセル

0

select
s1.グループコード,
SUM(s1. 売上売価) AS 店舗997の売上売価,
SUM(s2. 売上売価) AS 店舗998の売上売価,
SUM(s3. 売上売価) AS 店舗999の売上売価
from
(select GRP.グループコード, SYODAY.店舗コード , sum(SYODAY.売上売価) as 売上売価
      from SYODAY
      left join SYO on SYO.店舗コード = SYODAY.店舗コード
                   and SYO.商品コード = SYODAY.商品コード
      left join CLS on CLS.店舗コード = SYO.店舗コード
                   and CLS.クラスコード = SYO.クラスコード
      left join BUM on BUM.店舗コード = CLS.店舗コード 
                   and BUM.部門コード = CLS.部門コード
      left join GRP on GRP.店舗コード = BUM.店舗コード 
                   and GRP.グループコード = BUM.グループコード

      where 日付 = '20141126' and SYODAY.店舗コード = '997' and not GRP.グループコード = 'NULL'
      group by GRP.グループコード,SYODAY.店舗コード ) as s1

left join(select GRP.グループコード, SYODAY.店舗コード , sum(SYODAY.売上売価) as 売上売価
      from SYODAY
      left join SYO on SYO.店舗コード = SYODAY.店舗コード
                   and SYO.商品コード = SYODAY.商品コード
      left join CLS on CLS.店舗コード = SYO.店舗コード
                   and CLS.クラスコード = SYO.クラスコード
      left join BUM on BUM.店舗コード = CLS.店舗コード 
                   and BUM.部門コード = CLS.部門コード
      left join GRP on GRP.店舗コード = BUM.店舗コード 
                   and GRP.グループコード = BUM.グループコード

      where 日付 = '20141126' and SYODAY.店舗コード = '998' 
      group by GRP.グループコード,SYODAY.店舗コード ) as s2 
      on  s1.グループコード = s2.グループコード

left join(select GRP.グループコード, SYODAY.店舗コード , sum(SYODAY.売上売価) as 売上売価
      from SYODAY
      left join SYO on SYO.店舗コード = SYODAY.店舗コード
                   and SYO.商品コード = SYODAY.商品コード
      left join CLS on CLS.店舗コード = SYO.店舗コード
                   and CLS.クラスコード = SYO.クラスコード
      left join BUM on BUM.店舗コード = CLS.店舗コード 
                   and BUM.部門コード = CLS.部門コード
      left join GRP on GRP.店舗コード = BUM.店舗コード 
                   and GRP.グループコード = BUM.グループコード

      where 日付 = '20141126' and SYODAY.店舗コード = '999' 
      group by GRP.グループコード,SYODAY.店舗コード ) as s3
      on  s1.グループコード = s3.グループコード
group by s1.グループコード

0001    47162.00    NULL    221761.00
0003    90980.00    742.00    311382.00
0004    61136.00    22624.00    224474.00
0005    23659.00    1838.00    91251.00
0006    13819.00    3738.00    39771.00
0007    19187.00    3599.00    28180.00
0008    86637.00    32522.00    280208.00
0009    40476.00    NULL    8272.00
0010    30813.00    3954.00    79309.00
0011    8831.00    NULL    35958.00
0013    81441.00    NULL    234175.00
0014    67821.00    5118.00    170795.00
0015    23294.00    3078.00    7114.00
0016    1690.00    900.00    45018.00
0017    23659.00    4800.00    103056.00

これで表示したいことができました

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/17 12:19

    これだと目指したいと書いてあるパターンの0012が抜けてますがそれでよかったということでしょうか?

    キャンセル

0

SELECT T1.グループコード
,SUM(T1.店舗997の売上売価) AS 店舗997の売上売価
,SUM(T1.店舗998の売上売価) AS 店舗998の売上売価
,SUM(T1.店舗999の売上売価) AS 店舗999の売上売価
FROM
(SELECT ISNULL(グループコード,'0000') AS グループコード,売上売価 AS 店舗997の売上売価,0 AS 店舗998の売上売価,0 AS 店舗999の売上売価 FROM 店舗997の売上売価
UNION ALL
SELECT ISNULL(グループコード,'0000') AS グループコード,0 AS 売上売価 AS 店舗997の売上売価,売上売価 AS 店舗998の売上売価,0 AS 店舗999の売上売価 FROM 店舗998の売上売価
UNION ALL
SELECT ISNULL(グループコード,'0000') AS グループコード,0 AS 売上売価 AS 店舗997の売上売価,0 AS 店舗998の売上売価,売上売価 AS 店舗999の売上売価 FROM 店舗999の売上売価
) T1
GROUP BY T1.グループコード

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

関連した質問

  • 解決済

    MySQLで売り上げ集計表を取得するクエリについて

    MySQLで売り上げ集計表を取得するクエリについて質問です。 テーブル構成は次の通りです。 ★顧客テーブル 顧客ID 顧客名 (その他カラム省略) ★注文テーブル 注文no(ナ

  • 解決済

    mysql 合計値 最低値 最高値 の抽出の仕方

    お世話になっております。 考えが詰まってしまったのでまた質問させていただきます。 以下の3つのテーブルの抽出についてなのですが、 m_kyouka --------------

  • 解決済

    SQLのサブクエリを使用した結合で

    前提・実現したいこと 下記SQLをサブクエリなしで実現したい ソースコード Oracle 11g SELECT    A.ID,   A.TYPE,

  • 解決済

    FROM句のサブクエリについて

    前提・実現したいこと はじめまして、sqlserver 初心者です。 今サブクエリを勉強しているのですが、FROM句だけは別名をつけてJOINしなければならないので難しいです。

  • 受付中

    ユニークアイテムの推移を集計

    下記のようなテーブルがあるときに、直近1日間,7日間,30日間に購入されたproductの ユニーク数を日毎に集計したいと思っています。 テーブルイメージ create

  • 解決済

    SQLで欲しいレコードの書き方がわかりません

    oracle初心者です。 下記のテーブルから対象のidを取得するSQLがわかりません。 どなたかご教示いただけると助かります。 TABLE1 id(外部キー), grou

  • 解決済

    SQL文でGROUP BYによる件数合計の合成出力の方法

    SQLのGroup by を使った件数カウントで行き詰まっていますので、ぜひお教え下さい。 部登録テーブル 生徒コード 性別コード 部コード 1101     1    

  • 解決済

    sqlの結果を列にして集計データを表示したい

    下記のSQLを実行して月ごとに3回以上エントリーしたユーザ を表示するようにしたのですがこの時、月に何回表示されたかをSQLの結果で列で表示したいのですが、重複が完全に削除されて

同じタグがついた質問を見る

  • SQL

    2470questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

  • SQL Server

    603questions

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