3

このようなテーブルがあります。

+----+---------+-------------+
| id | user_id | screenWidth |
+----+---------+-------------+
|  1 |       1 |        1366 |
|  2 |       1 |        1366 |
|  3 |       1 |        1366 |
|  4 |       1 |        1366 |
|  5 |       2 |        1920 |
|  6 |       2 |        1920 |
|  7 |       3 |        1920 |
|  8 |       4 |        1280 |
|  9 |       5 |        1280 |
| 10 |       6 |        1280 |
| 11 |       7 |        1890 |
| ...|   ...   |     ...     |
| ...|   ...   |     ...     |
| ...|   ...   |     ...     |
| 100|       6 |        1910 |
+----+---------+-------------+

多くの screenWidths がありますが、それらの 90% は 5 つの値のいずれかと同じです。

次のようなクエリを使用します。

SELECT      screenwidth
        ,   COUNT(DISTINCT user_id) AS screenwidthcount
FROM        screenwidth
GROUP BY    screenwidth
ORDER BY    screenwidthcount;

(値の最初の出現のみをカウントするにはどうすればよいですか?からの感謝)

screenWidth が発生した回数は、ユーザーごとに 1 回だけカウントされます。

最も人気のある screenWidths をカウントし、「その他」と呼ばれるカテゴリ内の他のすべてを収集する方法はありますか? つまり、上記のクエリが大量の行を返す代わりに、6 を返します。現在、6 番目は、残りの値の合計で other と呼ばれていますか?

4

3 に答える 3

3

これを行う1つの方法があります。次のスクリプトは、この質問への回答に基づいて作成されましたMySQLのランク関数

クエリは、個別のカウントがコンピュータであるすべての行にランキングを割り当てます。式に2の値を割り当てましたCASE。これは、スクリプトが上位2つの画面幅を表示し、残りがその他にクラブされることを意味します。要件に応じて値を変更する必要があります。99999他のすべての行をグループ化するために値をハードコーディングしました。

これを行うためのより良い方法があるかもしれませんが、これは私がそれを機能させることができる方法の1つです。

SQL Fiddleでデモを表示するには、ここをクリックしてください。

スクリプト

CREATE TABLE screenwidth 
(
    id INT NOT NULL
  , user_id INT NOT NULL
  , screenwidth INT NOT NULL
);

INSERT INTO screenwidth (id, user_id, screenwidth) VALUES
  (1, 1, 1366),
  (2, 2, 1366),
  (3, 2, 1366),
  (4, 2, 1366),
  (5, 3, 1366),
  (6, 1, 1920),
  (7, 2, 1920),
  (8, 1, 1440),
  (9, 2, 1440),
  (10, 3, 1440),
  (11, 4, 1440),
  (12, 1, 1280),
  (13, 1, 1024),
  (14, 2, 1024),
  (15, 3, 1024),
  (16, 3, 1024),
  (17, 3, 1024),
  (18, 1, 1366);

SELECT screenwidth
    , SUM(screenwidthcount) AS screenwidth_count
FROM
(
    SELECT      CASE    
                    WHEN @curRank < 2 THEN screenwidth 
                    ELSE 'Other' 
                END AS screenwidth
            ,   screenwidthcount
            ,   @curRank := 
                (   CASE 
                        WHEN @curRank < 2 THEN @curRank + 1 
                        ELSE 99999
                    END
                ) AS rank
    FROM
    (
        SELECT      screenwidth
                ,   COUNT(DISTINCT user_id) AS screenwidthcount
        FROM        screenwidth
        GROUP BY    screenwidth
        ORDER BY    screenwidthcount DESC
    ) T1
                ,   (SELECT @curRank := 0) r
) T2
GROUP BY    screenwidth
ORDER BY    rank;

出力

SCREENWIDTH SCREENWIDTH_COUNT
----------- -----------------
1440               4
1024               3
Other              6
于 2012-04-29T16:11:42.910 に答える
1

これを試して:

select

  case when rank <= 5 then rank else 'Other' end as screenwidth, 

  sum(screenwidthcount) as screenwidthcount,

  least(rank,6) as LimitRank

from
(
  SELECT
  *, (@r := @r + 1) as rank
  FROM
  (
    SELECT      screenwidth
            ,   COUNT(DISTINCT user_id) AS screenwidthcount

    FROM        tbl

    GROUP BY    screenwidth
    ORDER BY    screenwidthcount desc, screenwidth desc
  ) AS X
  cross join (select @r := 0 as init ) rx
) as y

group by LimitRank

データサンプル:

CREATE TABLE tbl
    (id int, user_id int, screenWidth int);

INSERT INTO tbl
    (id, user_id, screenWidth)
VALUES
    (1, 1, 1366),
    (2, 1, 1366),
    (3, 1, 1366),
    (4, 1, 1366),
    (5, 2, 1920),
    (6, 2, 1920),
    (7, 3, 1920),
    (8, 4, 1280),
    (9, 5, 1280),
    (10, 6, 1280),
    (11, 7, 1890),
    (12, 9, 1890),
    (13, 9, 1890),
    (13, 9, 1024),
    (13, 9, 800),
    (100, 6, 1910);

出力:

SCREENWIDTH SCREENWIDTHCOUNT    LIMITRANK
1280        3                   1
1920        2                   2
1890        2                   3
1910        1                   4
1366        1                   5
Other       2                   6

ライブ テスト: http://www.sqlfiddle.com/#!2/c0e94/33


上限のない結果は次のとおりです: http://www.sqlfiddle.com/#!2/c0e94/31

SCREENWIDTH SCREENWIDTHCOUNT
1280        3
1920        2
1890        2
1910        1
1366        1
1024        1
800         1
于 2012-05-01T01:51:08.237 に答える
0

はい、どこにでもあるcaseステートメントで:私はMySQLを持っていませんが、これ、またはこのようなものは機能するはずです...

A. Inner Selectは、画面幅の結果セットと、その画面幅を持つ個別のユーザーの数を生成します...(これにより、各画面幅はユーザーごとに1回だけ効果的にカウントされます)。結果セットは、5人以上のユーザーが使用する画面幅のみに制限されます。

B.次に、外部クエリが完全なテーブルをその結果セットに結合し、式をグループ化して、各画面幅を使用しているユーザーの数を表す「Cnt」を合計します。

   Select case When Z.Cnt < 5 Then screnwidth, else 0 end
       Sum(Z.Cnt) screenwidthcount, 
   From screenwidth A
      Left Join (Select screenwidth, Count(Distinct User_ID) Cnt
                 From screenwidth
                 Group By screenwidth
                 Having count(*) > 4) Z
        On Z.screeenwidth = A.screeenwidth         
   Group By case When Z.Cnt < 5 Then screnwidth, else 0 end

C.MySqlにSQLServers関数のような関数がある場合はStr()、それを使用して大文字と小文字の式を文字列に変換し、その後に0を挿入して、「その他」を使用できます。

   Select case When Z.Cnt < 5 Then Str(screnwidth, 6,0) else 'other' end
       Sum(Z.Cnt) screenwidthcount, 
   From screenwidth A
      Left Join (Select screenwidth, Count(Distinct User_ID) Cnt
                 From screenwidth
                 Group By screenwidth
                 Having count(*) > 4) Z
        On Z.screeenwidth = A.screeenwidth         
   Group By case When Z.Cnt < 5 Then Str(screnwidth, 6,0) else 'other'  end  
于 2012-04-29T15:44:54.330 に答える