[前][次][番号順一覧][スレッド一覧]

mysql:8667

From: ML account <ML account <ml@xxxxxxxxxx>>
Date: Wed, 28 Jan 2004 02:58:30 +0900
Subject: [mysql 08667] Re: 複数フィールドに対する頻度集計

 こんにちは。

Kenichi-Ashida <ashiken@xxxxxxxxxx>さんの
<200401271528.HID37607.LBJFIOT@xxxxxxxxxx>
"[mysql 08662] 複数フィールドに対する頻度集計"


> あしだ@MySQL初心者です
> ちょっと悩んでいます。

 ビューやサブクエリが使えれば、スマートかどうかは別にしても簡単なのです
けどね。

    CREATE TABLE table1 (
        id INT NOT NULL PRIMARY KEY,
        Field1 varchar(20),
        Field2 varchar(20),
        Field3 varchar(20)
    );

の様なテーブル構造なら、一度テンポラリテーブルに出してから集計する方法が
比較的簡単です。3.23ではUNION操作が使えないと思いますので、ベタな方法で。

    CREATE TABLE tmp000 (FldData varchar(20));
    
    INSERT INTO tmp000 (FldData) SELECT Field1 AS FldData FROM table1 

    INSERT INTO tmp000 (FldData) SELECT Field2 AS FldData FROM table1 

    INSERT INTO tmp000 (FldData) SELECT Field3 AS FldData FROM table1;
    
    SELECT FldData,count(*) AS cnt FROM tmp000 
    WHERE FldData IS NOT NULL GROUP BY FldData 
    ORDER BY cnt DESC;
    
あるいは、

    CREATE TABLE tmp000 (FldData varchar(20),cnt INT);

    INSERT INTO tmp000 (FldData,cnt)
    SELECT Field1 AS FldData,count(*) AS cnt FROM table1 
    GROUP BY FldData

    INSERT INTO tmp000 (FldData,cnt)
    SELECT Field2 AS FldData,count(*) AS cnt FROM table1 
    GROUP BY FldData

    INSERT INTO tmp000 (FldData,cnt)
    SELECT Field3 AS FldData,count(*) AS cnt FROM table1 
    GROUP BY FldData;
    
    SELECT FldData,sum(cnt) AS cnt FROM tmp000 
    WHERE FldData IS NOT NULL GROUP BY FldData 
    ORDER BY cnt DESC;



 [mysql 08565]でも述べた、テーブルの正規化を考慮する事も一案でしょう。

    CREATE TABLE table1 (id INT NOT NULL PRIMARY KEY);
    CREATE TABLE table1s (
        id INT NOT NULL,
        colpos INT NOT NULL,
        coldata VARCHAR(20)
    );

なテーブルがあった場合、

> <Table1>
> [ID] [Field1] [Field2] [Field3]

の表を得るクエリは、

    SELECT table1.id AS ID, T1.coldata AS Field1, T2.coldata AS Field2, 
        T3.coldata AS Field3
    FROM ((table1 LEFT JOIN table1s AS T1 ON table1.id = T1.id)
                  LEFT JOIN table1s AS T2 ON table1.id = T2.id) 
                  LEFT JOIN table1s AS T3 ON table1.id = T3.id
    WHERE T1.colpos=1 AND T2.colpos=2 AND T3.colpos=3
    ORDER BY table1.id;

となり、「希望する集計結果」を得るクエリは、

    SELECT table1s.coldata, count(*) AS cnt
    FROM table1s,table1
    WHERE table1s.coldata IS NOT NULL AND table1.id=table1s.id
    GROUP BY table1s.coldata
    ORDER BY cnt DESC

の様な感じになります。

 表を得るクエリと集計を得るクエリで、どちらが使用頻度が多いのか、どちら
がクエリ実行の時間的な制約がきついのかで、この正規化した方法が妥当なのか、
それとも最初に述べたベタなテーブルでやる方が妥当なのかは変わって来るでし
ょう。

また正規化した方法では、データ挿入/変更時に一貫性を保証する手段(テーブル
のロックまたはトランザクション)が必要となる場合もあるでしょう。




    松枝知直    <tomom@xxxxxxxxxx>
            http://www.argus.ne.jp/~tomom/



[前][次][番号順一覧][スレッド一覧]

      8662 2004-01-27 15:28 [Kenichi-Ashida <ashi] 複数フィールドに対する頻度集計          
->    8667 2004-01-28 02:58 ┗[ML account <ml@xxxxx]                                       
      8668 2004-01-28 11:21  ┗[Kenichi-Ashida <ashi]                                     
      8669 2004-01-28 15:29   ┗[ML account <ml@xxxxx]