39

我想根据这种情况生成查询结果,可以根据 cramp_id 和类型创建行号。

id   crew_id   amount    type
 1      4       1000      AUB
 2      4       1500      AUB
 3      5       8000      CA
 4      4       1000      CA
 5      5       1000      AUB
 6      6       3000      AUB
 7      4       2000      CA
 8      6       3500      AUB
 9      4       5000      AUB
 10     5       9000      CA
 11     5       1000      CA

输出必须是 ff:

id    crew_id   amount   type    row_number
 1      4       1000      AUB        1    
 2      4       1500      AUB        2 
 9      4       5000      AUB        3
 4      4       1000      CA         1
 7      4       2000      CA         2
 5      5       1000      AUB        1
 3      5       8000      CA         1
 10     5       9000      CA         2
 11     5       1000      CA         3
 6      6       3000      AUB        1
 6      6       3000      AUB        2

我只想在此输出中使用单个 select 语句

4

7 回答 7

47

请通过我的小提琴

这是最后一次尝试

    SELECT    id,
              crew_id,
              amount,
              type,
             ( 
                CASE type 
                WHEN @curType 
                THEN @curRow := @curRow + 1 
                ELSE @curRow := 1 AND @curType := type END
              ) + 1 AS rank
    FROM      Table1 p,
              (SELECT @curRow := 0, @curType := '') r
   ORDER BY  crew_id,type asc;
于 2013-07-30T06:23:45.880 回答
24

这个问题很老了。但我想发布它以防有人遇到同样的问题。

首先,描述的答案不正确。例如,对于

id   crew_id   amount    type
1      4       1000      AUB
2      4       1500      AUB
5      5       1000      AUB
6      6       3000      AUB
8      6       3500      AUB
9      4       5000      AUB

(我刚刚删除了“CA”类型的行)结果表将是

id   crew_id   amount    rank   type
1      4       1000      1      AUB
2      4       1500      2      AUB
9      4       5000      3      AUB
5      5       1000      4      AUB
6      6       3000      5      AUB
8      6       3500      6      AUB

所以实际上它并没有同时使用crew_id 和type,它只是使用了type。

这是我解决这个问题的方法(可能有比使用两个嵌套的“CASE”更优雅的方法,但你明白了):

SELECT id,
    amount,
    CASE crew_id 
        WHEN @curCrewId THEN
            CASE type 
                WHEN @curType THEN @curRow := @curRow + 1 
                ELSE @curRow := 1
            END
        ELSE @curRow :=1
    END AS rank,
    @curCrewId := crew_id AS crew_id,
    @curType := type AS type
FROM Table1 p
JOIN (SELECT @curRow := 0, @curCrewId := 0, @curType := '') r
ORDER BY crew_id, type

主要思想仍然存在。我刚刚添加了一个变量@curCrewId。如果有人需要使用 3 个变量进行分组,那么只需使用 3 个变量和 3 个嵌套的“CASE”。:)

于 2016-06-08T17:41:47.633 回答
4

除了@Janty 的答案之外,如果您想使用行号 UDATE 您的表,这里还有一个解决方案:

UPDATE myTable mt,(SELECT @curRow := 0, @curType := '') r SET type=
    ( 
        CASE type 
            WHEN @curType
        THEN @curRow := @curRow + 1 
        ELSE @curRow := 1 AND @curType := type END
      )
;

由于 janty 太 crampId 不在其中。如其他答案中所述,使用第二个“案例”。

于 2017-04-06T17:02:10.417 回答
4

@Janty 的答案在类型以数字开头时不起作用(排名从 2 开始而不是 1)。

请改用以下内容:

SELECT id,
     crew_id,
     amount,
     CASE type 
         WHEN @curType THEN @curRow := @curRow + 1 
         ELSE @curRow := 1
     END AS rank,
     @curType := type AS type
FROM Table1 p
JOIN (SELECT @curRow := 0, @curType := '') r
ORDER BY crew_id, type
于 2016-05-23T13:27:49.563 回答
3

在 MySQL 8.0 中,您可以使用窗口函数 ROW_NUMBER:

SELECT *, ROW_NUMBER() OVER(PARTITION BY crew_id) AS row_number
FROM MyTable
于 2021-04-06T06:37:25.407 回答
0
SELECT id, crew_id, amount, type,
       ( 
        CASE type 
          WHEN @curType 
          THEN @curRow := @curRow + 1 
          ELSE @curRow := 1 AND @curType := type  END
      ) + 1 AS rank
 FROM      Table1 p,
      (SELECT @curRow := 0, @curType := '') r
   ORDER BY  crew_id, type asc;
于 2013-07-30T07:17:43.237 回答
0

这是我的答案,仅使用一种根据两列创建行号的情况:

SELECT id, crew_id, amount, type,
   (CASE CONCAT(crew_id, type) 
        WHEN @cur_crew_type
        THEN @curRow := @curRow + 1
        ELSE @curRow := 0 END) + 1 AS cnt,
    @cur_crew_type := CONCAT(crew_id, type) AS cur_crew_type
FROM TABLE t,
     (SELECT @curRow := 0, @cur_crew_type := '') counter
      ORDER BY crew_id, type;
于 2016-07-28T18:03:20.510 回答