2

まず、これは単純なスタック オーの質問に似ています。MySQL では、テーブル内のレコード インデックスを含む列をどのように生成できますか? 、一般的な増分列がクエリに追加されました。

ただし、この場合、個々のサブグループをインクリメントしようとしています。

たとえば、次の表を考えてみましょう。

name    sub-group   note
john    1           yes
doe     1           no
bill    1           maybe
greg    2           so
dan     2           blue
jim     3           white

次のように、サブグループごとにインクリメントされた追加の列を含むテーブルを出力するクエリは次のとおりです。

name    sub-group   note    increment
john    1           yes     1
doe     1           no      2
bill    1           maybe   3
greg    2           so      1
dan     2           blue    2
jim     3           white   1

これは可能ですか?

4

2 に答える 2

2

ここの最も優れたブログ投稿の助けのおかげで、私はそれを解決しました: http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/

解決策は簡単ではなく、変数と、mysql がクエリ操作をどのように順序付けるかについての高度な知識が必要ですが、かなりパフォーマンスが高いようです。重要な点の 1 つは、変数の割り当てを関数呼び出し内に隠すことができることです。

基本的に、次のクエリは問題を解決します。

SET @num := 0, @type := '';

SELECT name, subgroup, @num AS increment
FROM table_name
WHERE 0 <= GREATEST(
   @num := IF(@type = subgroup, @num + 1, 1),
   LEAST(0, LENGTH(@type := subgroup)))

関数GREATESTLEAST、およびLENGTHは、変数割り当てのコンテナーとして存在します。ご覧のとおり、これらの関数は基本的に、クエリの出力に影響を与えることは何もしていません。

ただし、テーブルに連続していない「サブグループ」値があることもわかりました。例えば:

+------+----------+
| name | subgroup |
+------+----------+
| john | 1        |
| doe  | 1        |
| jim  | 1        |
| greg | 2        |
| boe  | 2        |
| amos | 3        |
| ben  | 1        |
| gary | 2        |
+------+----------+

次のような出力テーブルが得られました。

+------+----------+-----------+
| name | subgroup | increment |
+------+----------+-----------+
| john | 1        |         1 |
| doe  | 1        |         2 |
| jim  | 1        |         3 |
| greg | 2        |         1 |
| boe  | 2        |         2 |
| amos | 3        |         1 |
| ben  | 1        |         1 |
| gary | 2        |         1 |
+------+----------+-----------+

実行順序が原因で、クエリの最後に句を追加してORDER BYも機能しませんでした。また、ORDER BY句内の変数の割り当てを非表示にすることはより近づきましたが、独自の問題があったため、使用した最終的なクエリは次のとおりです。

SET @num := 0, @type := '';

SELECT name, subgroup, @num AS increment
FROM (SELECT * FROM table_name ORDER BY subgroup) AS table_name2
WHERE 0 <= GREATEST(
   @num := IF(@type = subgroup, @num + 1, 1),
   LEAST(0, LENGTH(@type := subgroup)))

次の出力が得られます。

+------+----------+-----------+
| name | subgroup | increment |
+------+----------+-----------+
| john | 1        |         1 |
| doe  | 1        |         2 |
| jim  | 1        |         3 |
| ben  | 1        |         4 |
| greg | 2        |         1 |
| boe  | 2        |         2 |
| gary | 2        |         3 |
| amos | 3        |         1 |
+------+----------+-----------+

わーい!

于 2013-10-02T22:23:48.840 に答える