2

私はMySQLを学び始めたばかりで、解決策または単にロジックが必要なこの問題に遭遇しました。

たとえば、次のテーブルがあります。

id         a 
--        --
 1         1
 2         2
 3         3
 4         5
 5         6
 6         7
 7         9
 8        10
 9        11
10        12

今、私が望むのは、aシリーズごとにグループ化する必要がある列にすべてのデータを表示することです。この場合、結果は次のようになります。

series_start|series_end|count
------------+----------+-----
           1          3     3
           5          7     3
           9         12     4

これには、多くのサブクエリと結合が必要です。私は今ではそれを理解することはできません。

4

2 に答える 2

2

これは問題であり、変数を使用して解決する別の方法を次に示します。

SELECT
  MIN(a) AS series_start,
  MAX(a) AS series_end,
  MAX(a) - MIN(a) + 1 AS series_count
FROM (
  SELECT
    a,
    @r := @r + 1 AS r
  FROM
    yourtable,
    (SELECT @r := 0) AS x
  ORDER BY
    a
) s
GROUP BY
  a - r
ORDER BY
  a - r
;

これがその仕組みです。

サブクエリは、テーブルの行に行番号を割り当て、次の行セットを返します。

 a   r
--  --
 1   1
 2   2
 3   3
 5   4
 6   5
 7   6
 9   7
10   8
11   9
12  10

この場合、r行番号を格納する列はたまたまidデータ サンプルの列と一致しますが、一般に列にギャップがある可能性があると想定してidいるため、ここでは使用できません。

rメインクエリは、との差によって結果をグループ化しますa: 連続する値の場合、常に同じになります:

 a   r  a - r
--  --  -----
 1   1      0
 2   2      0
 3   3      0
 5   4      1
 6   5      1
 7   6      1
 9   7      2
10   8      2
11   9      2
12  10      2

これにより、そのような行をグループ化できます。この時点で残っているのは、最小値、最大値、およびカウントを取得することだけです。これにより、次の出力が得られます。

series_start  series_end  series_count
------------  ----------  ------------
           1           3             3
           5           7             3
           9          12             4

@sgeddes のスキーマを借用した、このクエリの SQL Fiddle デモンストレーションは、こちらにあります


アップデート

数値変数は使用できないため (コメントによると)、三角形の自己結合を使用して行番号を割り当てることができますが、変数を使用するよりも効率が大幅に低下します。とにかく、これが変更されたバージョンです。太字で強調表示されている以前のクエリへの変更です。

選択する
  MIN(a) AS series_start、
  MAX(a) AS series_end,
  MAX(a) - MIN(a) + 1 AS series_count
から (
  選択する
    data.a、
    COUNT(*) AS r
  から
    あなたのテーブルASデータ
  内部結合
    yourtable AS タリー
  オン
    data.id >= 集計.id
  グループ化
    data.a
) 秒
グループ化
  a - r
オーダーバイ
  a - r
;

アプローチ自体は変更されていません。サブクエリはランク付けされた行セットを返し、それが以前と同じように処理されます。

変更されたクエリの SQL Fiddle デモは、こちらから入手できます。

于 2013-10-11T13:32:48.217 に答える
0

を使用した1つのソリューションを次に示しuser defined variablesます。

select min(series_start) series_start, 
  max(series_end) series_end,
  1 + max(series_end) - min(series_start) count
from (
  select t1.a series_start, 
    t2.a series_end,
    @val:=IF(@prev=t2.a-1,@val,@val+1) val,
    @prev:=t2.a
  from yourtable t1
    join yourtable t2 on t1.a = t2.a-1
    join (select @val:= 0, @prev:= 0) t
  order by t2.a
  ) t
group by val
于 2013-10-10T01:37:28.287 に答える