簡體   English   中英

使用 MySQL,如何生成包含表中記錄索引的列?

[英]With MySQL, how can I generate a column containing the record index in a table?

有什么辦法可以從查詢中獲取實際的行號?

我希望能夠通過名為 score 的字段訂購名為 League_girl 的表; 並返回用戶名和該用戶名的實際行位置。

我想對用戶進行排名,以便我可以知道特定用戶在哪里,即。 Joe 在 200 中的位置是 100,即

User Score Row
Joe  100    1
Bob  50     2
Bill 10     3

我在這里看到了一些解決方案,但我已經嘗試了其中的大部分,但實際上沒有一個返回行號。

我試過這個:

SELECT position, username, score
FROM (SELECT @row := @row + 1 AS position, username, score 
       FROM league_girl GROUP BY username ORDER BY score DESC) 

作為派生

...但它似乎沒有返回行位置。

有任何想法嗎?

您可能想嘗試以下操作:

SELECT  l.position, 
        l.username, 
        l.score,
        @curRow := @curRow + 1 AS row_number
FROM    league_girl l
JOIN    (SELECT @curRow := 0) r;

JOIN (SELECT @curRow := 0)部分允許變量初始化而無需單獨的SET命令。

測試用例:

CREATE TABLE league_girl (position int, username varchar(10), score int);
INSERT INTO league_girl VALUES (1, 'a', 10);
INSERT INTO league_girl VALUES (2, 'b', 25);
INSERT INTO league_girl VALUES (3, 'c', 75);
INSERT INTO league_girl VALUES (4, 'd', 25);
INSERT INTO league_girl VALUES (5, 'e', 55);
INSERT INTO league_girl VALUES (6, 'f', 80);
INSERT INTO league_girl VALUES (7, 'g', 15);

測試查詢:

SELECT  l.position, 
        l.username, 
        l.score,
        @curRow := @curRow + 1 AS row_number
FROM    league_girl l
JOIN    (SELECT @curRow := 0) r
WHERE   l.score > 50;

結果:

+----------+----------+-------+------------+
| position | username | score | row_number |
+----------+----------+-------+------------+
|        3 | c        |    75 |          1 |
|        5 | e        |    55 |          2 |
|        6 | f        |    80 |          3 |
+----------+----------+-------+------------+
3 rows in set (0.00 sec)
SELECT @i:=@i+1 AS iterator, t.*
FROM tablename t,(SELECT @i:=0) foo

這是我使用的模板結構:

  select
          /*this is a row number counter*/
          ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) 
          as rownumber,
          d3.*
  from 
  ( select d1.* from table_name d1 ) d3

這是我的工作代碼:

select     
           ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) 
           as rownumber,
           d3.*
from
(   select     year( d1.date ), month( d1.date ), count( d1.id )
    from       maindatabase d1
    where      ( ( d1.date >= '2013-01-01' ) and ( d1.date <= '2014-12-31' ) )
    group by   YEAR( d1.date ), MONTH( d1.date ) ) d3

你也可以使用

SELECT @curRow := ifnull(@curRow,0) + 1 Row, ...

初始化計數器變量。

如果您只想在按字段分數排序后了解某個特定用戶的位置,您可以簡單地從表中選擇字段分數高於當前用戶分數的所有行。 並使用返回的行號 + 1 來知道當前用戶的位置。

假設你的表是league_girl並且你的主要字段是id ,你可以使用這個:

SELECT count(id) + 1 as rank from league_girl where score > <your_user_score>

假設 MySQL 支持它,您可以使用標准 SQL 子查詢輕松完成此操作:

select 
    (count(*) from league_girl l1 where l2.score > l1.score and l1.id <> l2.id) as position,
    username,
    score
from league_girl l2
order by score;

對於大量顯示的結果,這會有點慢,您需要切換到自聯接。

我知道 OP 要求提供mysql答案,但由於我發現其他答案對我不起作用,

  • 他們中的大多數都因order by失敗
  • 或者它們的效率非常低,並且使您的查詢對於胖表非常緩慢

因此,為了節省像我這樣的其他人的時間,只需在從數據庫中檢索它們后索引該行

PHP 中的示例:

$users = UserRepository::loadAllUsersAndSortByScore();

foreach($users as $index=>&$user){
    $user['rank'] = $index+1;
}

在 PHP 中使用偏移和限制進行分頁的示例:

$limit = 20; //page size
$offset = 3; //page number

$users = UserRepository::loadAllUsersAndSortByScore();

foreach($users as $index=>&$user){
    $user['rank'] = $index+1+($limit*($offset-1));
}

我發現原始答案非常有用,但我也想根據我插入的行號獲取一組特定的行。 因此,我將整個原始答案包裝在一個子查詢中,以便我可以引用我插入的行號。

SELECT * FROM 
( 
    SELECT *, @curRow := @curRow + 1 AS "row_number"
    FROM db.tableName, (SELECT @curRow := 0) r
) as temp
WHERE temp.row_number BETWEEN 1 and 10;

在子查詢中使用子查詢不是很有效,因此值得測試是否通過讓 SQL 服務器處理此查詢獲得更好的結果,或者獲取整個表並讓應用程序/Web 服務器在事后操作行.

就個人而言,我的 SQL 服務器並不太忙,因此最好讓它處理嵌套的子查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM