10

テーブルの結合に問題があります。テーブルの例を次に示します。

表 A: ( 30 行)

╔════╦════════════╦═════════════╗
║ ID ║ 名前 ║ 説明 ║
╠════╬════════════╬═════════════╣
║ 1 ║ タイプ ║ Unicode アート ║
║ 2 ║ ヘッダー ║ スプレッドシート ║
║ 3 ║ 自動位置合わせ ║ オフ ║
╚════╩════════════╩═════════════╝

表 B: ( 100 行 )

╔════╦════════════╦═════════════╦══════════
║ ID ║ 名前 ║ 説明 ║ TableA ║
╠════╬════════════╬═════════════╬═════════
║ 1 ║ タイプ ║ Unicode アート ║ 1 ║
║ 2 ║ ヘッダー ║ スプレッドシート ║ 1 ║
║ 3 ║ 自動位置合わせ ║ オフ ║ 2 ║
.

表 C: ( 8000 行 )

╔════╦════════════╦═════════════╦══════════
║ ID ║ 記事 ║ テキスト ║ TableB ║
╠════╬════════════╬═════════════╬═════════
║ 1 ║ タイプ ║ Unicode アート ║ 1 ║
║ 2 ║ ヘッダー ║ スプレッドシート ║ 1 ║
║ 3 ║ 自動位置合わせ ║ オフ ║ 2 ║
.

テーブル D: ( 100 000 行とカウント )

╔════╦═══════════╦════════════╦═════════════╦═════ ════╗
║ ID ║ 日付 ║ クリック数 ║ インプレッション数 ║ TableC ║
╠════╬═══════════╬════════════╬═════════════╬═════ ════╣
║ 1 ║ 20120814 ║ 10 ║ 3 ║ 1 ║
║ 2 ║ 20120815 ║ 13 ║ 5 ║ 1 ║
║ 3 ║ 20120816 ║ 15 ║ 10 ║ 2 ║
╚════╩═══════════╩════════════╩═════════════╩═════ ════╝

表 E: ( 200 000 行とカウント )

╔════╦═══════════╦════════════╦═══════════╦═══════ ══╗
║ ID ║ 日付 ║ ビュー ║ 訪問者 ║ TableC ║
╠════╬═══════════╬════════════╬═══════════╬═══════ ══╣
║ 1 ║ 20120814 ║ 10 ║ 3 ║ 1 ║
║ 2 ║ 20120815 ║ 13 ║ 5 ║ 1 ║
║ 3 ║ 20120816 ║ 15 ║ 10 ║ 2 ║
║ 4 ║ 20120817 ║ 8 ║ 7 ║ 2 ║
║ 5 ║ 20120818 ║ 9 ║ 4 ║ 2 ║
╚════╩═══════════╩════════════╩═══════════╩═══════ ══╝

単一の SQL ステートメントでこのテーブルをクエリします。

選択する
       名前、
       説明、
       SUM(D.クリック),
       SUM(D.インプレッション),
       SUM(E.ビュー),
       SUM(訪問者数)
から
       あ
       左結合B
         ON A.ID=B.TableA
       左結合 C
         ON B.ID=C.TableB
       左結合 D
         ON C.ID=D.TableC 
       LEFT JOIN E
         ON C.ID=E.TableC
グループ化
       援助

問題は、クエリがテーブル D とテーブル E に対して無効な SUM を返すことですが
、個々のクエリでテーブル D とテーブル E をクエリすると、正しい値が得られます。

選択する
       名前、
       説明、
       SUM(D.クリック),
       SUM(D.インプレッション)
から
       あ
       左結合B
         ON A.ID=B.TableA
       左結合 C
         ON B.ID=C.TableB
       左結合 D
         ON C.ID=D.TableC
グループ化
       援助

EDIT 1:
RIGHT JOIN、JOIN、LEFT OUTER JOIN を試しましたが、どれも機能しませんでした。
もちろん、間違った場所でそれらを使用した可能性があります。
しかし、「すべて含まれている」値を取得した最初のステートメントでは
、実際よりも何千倍も高く乗算されます。

4

2 に答える 2

9

D テーブルと E テーブルの両方を平坦化する必要があります。次に、A と B は C の単なるルックアップであると仮定するため、A で GROUP BY を実行する必要はありません: http://www.sqlfiddle.com/#!2/fccf1/8

A と B が C の情報の要約にどのように関連しているか (まだ) わからないので、ノイズ (A と B) を削除しました。

これを試して:

SELECT
       C.Article,
       C.Text,

       COALESCE(D.ClicksSum,0) AS ClicksSum,
       COALESCE(D.ImpressionsSum,0) AS ImpressionsSum,

       COALESCE(E.ViewsSum,0) AS ViewsSum,
       COALESCE(E.VisitorsSum,0) AS VisitorsSum
FROM 
       C

       LEFT JOIN 
       (
         SELECT TableC, SUM(Clicks) AS ClicksSum, SUM(Impressions) AS ImpressionsSum
         FROM D
         GROUP BY TableC
       ) D ON C.ID=D.TableC

       LEFT JOIN 
       (
         SELECT TableC, SUM(Views) AS ViewsSum, SUM(Visitors) AS VisitorsSum
         FROM E
         GROUP BY TableC       
       ) E ON C.ID=E.TableC

出力:

|    ARTICLE |        TEXT | CLICKSSUM | IMPRESSIONSSUM | VIEWSSUM | VISITORSSUM |
----------------------------------------------------------------------------------
|       Type | Unicode Art |        23 |              8 |       23 |           8 |
|     Header | Spreadsheet |        15 |             10 |       32 |          21 |
| Auto Align |         Off |         0 |              0 |        0 |           0 |

sqlfiddle の投稿でこれらのスキーマを手動で入力しなかったことに注意してください。sqlfiddle のText to DDLを使用します。

http://sqlfiddle.comが大好きです。そのText to DDLは、ASCII アートからデータを解析することもできます ツ</p>


(コメントから)より明確な目的を見ると、これがそれかもしれません:http://www.sqlfiddle.com/#!2/fccf1/13

SELECT
       A.Name, A.Description,

       COALESCE(SUM(D.ClicksSum),0) AS ClicksSum,
       COALESCE(SUM(D.ImpressionsSum),0) AS ImpressionsSum,

       COALESCE(SUM(E.ViewsSum),0) AS ViewsSum,
       COALESCE(SUM(E.VisitorsSum),0) AS VisitorsSum
FROM 
       C

       LEFT JOIN 
       (
         SELECT TableC, SUM(Clicks) AS ClicksSum, SUM(Impressions) AS ImpressionsSum
         FROM D
         GROUP BY TableC
       ) D ON C.ID=D.TableC

       LEFT JOIN 
       (
         SELECT TableC, SUM(Views) AS ViewsSum, SUM(Visitors) AS VisitorsSum
         FROM E
         GROUP BY TableC       
       ) E ON C.ID=E.TableC

       RIGHT JOIN B ON B.ID = C.TableB
       RIGHT JOIN A ON A.ID = B.TableA

GROUP BY A.ID

出力:

|       NAME | DESCRIPTION | CLICKSSUM | IMPRESSIONSSUM | VIEWSSUM | VISITORSSUM |
----------------------------------------------------------------------------------
|       Type | Unicode Art |        38 |             18 |       55 |          29 |
|     Header | Spreadsheet |         0 |              0 |        0 |           0 |
| Auto Align |         Off |         0 |              0 |        0 |           0 |

上記のアプローチでもデカルト積が生成される可能性があり、SubCategory(B) を平坦化してから Category(A) にグループ化します: http://www.sqlfiddle.com/#!2/fccf1/19

SELECT 
  A.Name, A.Description,
  COALESCE(SUM(B.ClicksSum),0) AS ClicksSum,
  COALESCE(SUM(B.ImpressionsSum),0) AS ImpressionsSum,
  COALESCE(SUM(B.ViewsSum),0) AS ViewsSum,
  COALESCE(SUM(B.VisitorsSum),0) AS VisitorsSum
FROM A
LEFT JOIN
(

  SELECT 
    B.ID, B.TableA,
    SUM(C.ClicksSum) AS ClicksSum,
    SUM(C.ImpressionsSum) AS ImpressionsSum,
    SUM(C.ViewsSum) AS ViewsSum,
    SUM(C.VisitorsSum) AS VisitorsSum
  FROM B
  LEFT JOIN
  (

    SELECT
      C.TableB,

      D.ClicksSum,
      D.ImpressionsSum,

      E.ViewsSum,
      E.VisitorsSum
    FROM 
    C

    LEFT JOIN 
    (
      SELECT TableC, SUM(Clicks) AS ClicksSum, SUM(Impressions) AS ImpressionsSum
      FROM D
      GROUP BY TableC
    ) D ON C.ID=D.TableC

    LEFT JOIN 
    (
      SELECT TableC, SUM(Views) AS ViewsSum, SUM(Visitors) AS VisitorsSum
      FROM E
      GROUP BY TableC       
    ) E ON C.ID=E.TableC

  ) C ON C.TableB = B.ID
  GROUP BY B.ID

) B ON B.TableA = A.ID
GROUP BY A.ID

出力:

|       NAME | DESCRIPTION | CLICKSSUM | IMPRESSIONSSUM | VIEWSSUM | VISITORSSUM |
----------------------------------------------------------------------------------
|       Type | Unicode Art |        38 |             18 |       55 |          29 |
|     Header | Spreadsheet |         0 |              0 |        0 |           0 |
| Auto Align |         Off |         0 |              0 |        0 |           0 |
于 2012-08-19T12:14:11.197 に答える
1

テーブル D とテーブル E の両方が、テーブル C によって残りのテーブルにリンクされています。したがって、最初のクエリでは、テーブル D のすべての行のデカルト積にテーブル E のすべての行を掛けたデカルト積が得られ、SUM 関数はこのデカルト積を集計します。おそらく、テーブル A だけでなく、テーブル C でもグループ化する必要があります。

于 2012-08-19T12:06:00.993 に答える