[MySQL]分组排序取前N条记录以及生成自动数字序列,类似groupby后limit_MySQL
同事的业务场景是,按照cid、author分组,再按照id倒叙,取出前2条记录出来。
oracle里面可以通过row_number() OVER (PARTITION BY cid,author ORDER BY id DESC) 表示根据cid,author分组,在分组内部根据id排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的),而mysql数据库就没有这样的统计函数,需要自己写复杂的sql来实现。
1,录入测试数据
USE csdn;
DROP TABLE IF EXISTS test;
CREATE TABLE test (
id INT PRIMARY KEY,
cid INT,
author VARCHAR(30)
) ENGINE=INNODB;
INSERT INTO test VALUES
(1,1,\'test1\'),
(2,1,\'test1\'),
(3,1,\'test2\'),
(4,1,\'test2\'),
(5,1,\'test2\'),
(6,1,\'test3\'),
(7,1,\'test3\'),
(8,1,\'test3\'),
(9,1,\'test3\'),
(10,2,\'test11\'),
(11,2,\'test11\'),
(12,2,\'test22\'),
(13,2,\'test22\'),
(14,2,\'test22\'),
(15,2,\'test33\'),
(16,2,\'test33\'),
(17,2,\'test33\'),
(18,2,\'test33\');
INSERT INTO test VALUES (200,200,\'200test_nagios\');
2,原始的效率比较低下的子查询实现方式
SELECT * FROM test a
WHERE
N>(
SELECT COUNT(*)
FROM test b
WHERE a.cid=b.cid AND a.`author`=b.`author` AND a.id
只要将N换成你要的数字比如2,就表示查询出每个分组的前2条记录,如下所示:
mysql> SELECT * FROM test a
-> WHERE
-> 2>(
-> SELECT COUNT(*)
-> FROM test b
-> WHERE a.cid=b.cid AND a.`author`=b.`author` AND a.id
+-----+------+----------------+
| id | cid | author |
+-----+------+----------------+
| 2 | 1 | test1 |
| 1 | 1 | test1 |
| 5 | 1 | test2 |
| 4 | 1 | test2 |
| 9 | 1 | test3 |
| 8 | 1 | test3 |
| 11 | 2 | test11 |
| 10 | 2 | test11 |
| 14 | 2 | test22 |
| 13 | 2 | test22 |
| 18 | 2 | test33 |
| 17 | 2 | test33 |
| 200 | 200 | 200test_nagios |
+-----+------+----------------+
13 ROWS IN SET (0.00 sec)
mysql>
3,使用动态sql来实现
先构造序列号码,引入一个@row来做rownumber
SET @row=0;SET @mid='';SELECT cid, author, @row:=@row+1 rownum FROM test ORDER BY cid, author LIMIT 10;
序列号码已经出来了,再加一个@mid来进行分组,重点在于CASE WHEN @mid = author THEN @row:=@row+1 ELSE @row:=1 END rownum,表示分组的时候会自动从1计数指导这个分组数据遍历结束。
好了,再外面加一层inner JOIN 再对 rownumber 做限制 就可以拿到目标数据了。
SET @row=0;
执行结果如下所示:
mysql> SET @row=0;
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> SET @mid=\'\';
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> SELECT a.*,b.rownum FROM test a
-> INNER JOIN (
-> SELECT cid, author, id, CASE WHEN @mid = author THEN @row:=@row+1 ELSE @row:=1 END rownum, @mid:=author MID
-> FROM test
-> ORDER BY cid,author,id DESC
-> ) b ON b.author=a.author AND b.cid=a.cid AND b.id=a.id WHERE b.rownum +-----+------+----------------+--------+
| id | cid | author | rownum |
+-----+------+----------------+--------+
| 2 | 1 | test1 | 1 |
| 1 | 1 | test1 | 2 |
| 5 | 1 | test2 | 1 |
| 4 | 1 | test2 | 2 |
| 9 | 1 | test3 | 1 |
| 8 | 1 | test3 | 2 |
| 11 | 2 | test11 | 1 |
| 10 | 2 | test11 | 2 |
| 14 | 2 | test22 | 1 |
| 13 | 2 | test22 | 2 |
| 18 | 2 | test33 | 1 |
| 17 | 2 | test33 | 2 |
| 200 | 200 | 200test_nagios | 1 |
+-----+------+----------------+--------+
13 ROWS IN SET (0.01 sec)
mysql>
参考文章地址:
http://blog.csdn.net/mchdba/article/details/22163223

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











スタンバイは、iPhone が充電器に接続され、水平 (または横) 向きになっているときにアクティブになるロック画面モードです。これは 3 つの異なる画面で構成されており、そのうちの 1 つは全画面表示されます。時計のスタイルを変更する方法については、この記事を読んでください。 StandBy の 3 番目の画面には、垂直にスワイプできるさまざまなテーマで時刻と日付が表示されます。一部のテーマでは、温度や次のアラームなどの追加情報も表示されます。時計を押し続けると、デジタル、アナログ、ワールド、ソーラー、フローティングなどのさまざまなテーマを切り替えることができます。 Float はカスタマイズ可能な色の大きなバブル数字で時間を表示します。Solar はさまざまな色の太陽フレアのデザインを備えたより標準的なフォントを持ち、World は世界を強調表示して表示します。

乱数や英数字の文字列を生成する機能は、多くの状況で役立ちます。これを使用して、ゲーム内のさまざまな場所に敵や食べ物をスポーンできます。これを使用して、ユーザーにランダムなパスワードを提案したり、ファイルを保存するためのファイル名を作成したりすることもできます。 PHP でランダムな英数字文字列を生成する方法に関するチュートリアルを書きました。この投稿の冒頭で、真にランダムなイベントはほとんどないと述べましたが、乱数や文字列の生成にも同じことが当てはまります。このチュートリアルでは、JavaScript で擬似ランダムな英数字文字列を生成する方法を説明します。 JavaScript での乱数の生成 まずは乱数を生成してみましょう。最初に思い浮かぶメソッドは Math.random() です。これは浮動小数点を返します。

数値を出力として表現することは、どの言語でプログラムを作成する場合でも興味深い、重要な作業です。整数型 (short、long、または Medium 型のデータ) の場合、出力として数値を表すのは簡単です。浮動小数点数 (float または double 型) の場合、特定の小数点以下の桁数に四捨五入する必要がある場合があります。たとえば、52.24568 を小数点以下 3 桁で表現したい場合は、前処理が必要です。この記事では、浮動小数点数を四捨五入して特定の小数点以下の桁数に表現するいくつかのテクニックを紹介します。さまざまなアプローチの中でも、C に似たフォーマット文字列を使用すること、precision 引数を使用すること、および数学ライブラリのround() 関数を使用することが重要です。一つずつ見ていきましょう。と

この記事では、2 から 10 までのどの数値でも割り切れない 1 から n (指定された) までの数値を見つける問題について説明します。いくつかの例でこれを理解しましょう - 入力:num=14出力:3説明:Therearethreenumbers,1,11,and13,thatarenotdivisible.Input:num=21Output:5説明:Therearefivenumbers1,11,13,17,and19,thatarenotdivisible. 解決済み シンプルなメソッド if

私たちは皆、2、3、5、7、8 など、数の 2 乗ではない数字を知っています。非正方形の数は N 個あり、すべての数を知ることは不可能です。そこで、この記事では、平方なしまたは非平方数と、C++ で N 番目の非平方数を見つける方法についてすべて説明します。 N 番目の非平方数 数値が整数の 2 乗である場合、その数値は完全平方と呼ばれます。完全平方数の例としては、-1issquareof14issquareof29issquareof316issquareof425issquareof5 などがあります。数値がどの整数の平方でもない場合、その数値は非正方形と呼ばれます。たとえば、最初の 15 個の非平方数は -2、3、5、6 です。

Java の数値 数値クラスは有形のクラスではなく、抽象クラスであることを理解することが重要です。その中には、その機能を定義する一連のラッパー クラスがあります。これらのラッパー クラスには、Integer、Byte、Double、Short、Float、Long が含まれます。これらは前に説明したのと同じ基本的なデータ型ですが、クラスの命名規則に準拠するために大文字の名前を持つ別のクラスとして表されていることに気づくでしょう。コンパイラは、特定の関数またはプログラム スコープの必要に応じて、プリミティブ データ型をオブジェクトに、またはその逆に自動的に変換します。数値クラスは java.lang パッケージの一部です。このプロセスは、オートボックス化およびアンボックス化と呼ばれます。数値クラスとそれに対応するラッパー クラスの抽象的な性質を理解することで、次のことが可能になります。

PHP プログラミング言語では、is_numeric() 関数は非常によく使用される関数で、変数または値が数値かどうかを判断するために使用されます。実際のプログラミングでは、ユーザーが入力した値が数値型であるかどうかを検証する必要がある場合が多く、この場合には is_numeric() 関数を使用して判定することができます。 1. is_numeric() 関数の概要 is_numeric() 関数は、変数または値が数値であるかどうかを検出するために使用される関数です。変数または値が数値の場合は true を返します

たとえば、数値 N が与えられた場合、その数値を最大の素数に分割する必要があるという問題について説明します。N から素数を引いて、素数の差を確認できます。差が素数であれば、N を 2 つの素数の和として表すことができます。しかし、ここで私たちはしなければなりません
