【问题标题】:Generate serial number in mysql query在mysql查询中生成序列号
【发布时间】:2012-06-21 02:36:24
【问题描述】:

我有一张桌子:student_marks

marks
-----
  44
  55
  64
  98
  76

预期输出:

serial_number|marks
--------------------
  1          | 44
  2          | 55
  3          | 64
  4          | 98
  5          | 76

使用mysql用户定义变量,可以使用查询来完成:

 set  @a:=0;select @a:=@a+1 serial_number, marks from student_marks;

有什么方法可以在不使用用户定义变量的情况下在 msyql 中实现这一点?

【问题讨论】:

  • 为什么不想使用用户定义的变量?
  • 我必须使用两个查询,一个用于将 mysql 变量初始化为 0,另一个用于实际查询。我试图在这里避免两个查询。

标签: mysql sql


【解决方案1】:

@a:=@a+1 序列号,

交叉连接(选择 @a:= 0)作为 a

SELECT @a:=@a+1 serial_no, sc.id, sc.name, sc.address, c.country,s.state 
FROM oc_table1 sc CROSS JOIN (SELECT @a:= 0) AS a LEFT JOIN oc_table2 .......

【讨论】:

    【解决方案2】:

    您可以使用此查询添加serial number:

    set @counter=0;
    SELECT  @counter:=@counter+1 as serial_number from <table_name>
    

    输出:

       |...............................|
       | serial_number  |   first_name |
       |...............................|
       |      1         |    mojtaba   |
       |      2         |    athena    |
       |      3         |     azin     |
       |      4         |     ava      |
       |      5         |    arash     |
       |...............................|
    

    另外如果你想在where中使用

    set @counter=0;
    select serial_number from (SELECT  @counter:=@counter+1 as serial_number 
    from <table_name>) as tbl_counter where serial_number > 3
    

    输出:

       |...............................|
       | serial_number  |   first_name |
       |...............................|
       |      4         |     ava      |
       |      5         |    arash     |
       |...............................|
    

    【讨论】:

      【解决方案3】:

      在 mysql 5.6 中测试:

      SELECT
          @a:=@a+1 as serial_number,
          student.* 
      FROM
          student
      join (SELECT @a:= 0) a
      

      【讨论】:

        【解决方案4】:

        上述答案似乎都不令人满意,因为您需要在单独的查询中将变量初始化为 null。

        所以发布以下全方位解决方案:

        SELECT ROUND(@a:=@a+1,0) sr_num, t.* from (select @a:=0) initvars, your_table t;
        

        【讨论】:

          【解决方案5】:

          这个问题的最佳答案应该是以下,最佳实践

          SET @count:=0;
          SELECT  (@count:=@count+1) AS serial_number, 
                  marks 
          FROM    student_marks
          

          【讨论】:

          • 为什么你从 2012 年开始复制与 the accepted one 相同的答案?
          • 这不是同一个答案,而且它比@GarethD 的解决方案更快退出
          • 只是措辞不好:他应该建议将其作为替代方案,或者引用他的“最佳实践”证据。没有理由生气或兴奋。
          • 这不是问题的最佳答案,因为 OP 特别想要一个使用一个语句而不是两个语句的解决方案。此外,OP 已经将此解决方案作为问题的一部分发布。因此,如果您可以使用多个语句,这可能是一种更好的方法,但它不是 this 问题的最佳答案。
          【解决方案6】:

          我有一个列 (c5) 包含数字 x 的表,我需要一个重复同一行 x 次的 sql 表达式:

          我的表 A 包含:

          c1  c2  c3  c4  c5
          16  1   2   16  3
          16  1   2   17  2 
          16  1   2   18  1
          

          我需要:

          c1  c2  c3  c4  c5  n
          16  1   2   16  3   1
          16  1   2   16  3   2
          16  1   2   16  3   3
          16  1   2   17  2   1
          16  1   2   17  2   2
          16  1   2   18  1   1
          

          我用以下表达式解决了这个问题:

          SELECT
              c1, c2, c3, c4, c5, row_number AS n
          FROM
              (
                  SELECT
                      @curRow := @curRow + 1 AS row_number
                  FROM
                      tablea
                  JOIN (SELECT @curRow := 0) r
                  WHERE
                      @curRow < (
                          SELECT
                              max(field1)
                          FROM
                              tablea
                      )
              ) AS vwtable2
          LEFT JOIN tablea d ON vwtable2.row_number <= tablea.field1;
          

          【讨论】:

            【解决方案7】:

            虽然答案很晚,但在没有两个查询、不使用连接和不使用子查询的情况下生成顺序 ID。

            SELECT *, (@cnt := if(@cnt IS NULL, 0,  @cnt) + 1) AS id FROM table_name;
            

            干杯

            【讨论】:

            • 多次执行时,cnt不会重置为0
            【解决方案8】:

            根据您不想使用用户定义变量的原因,因为希望避免进行 2 个查询,一个用于初始化,一个用于使用它,您可以使用以下内容:

            SELECT  @a:=@a+1 serial_number, 
                    marks 
            FROM    student_marks,
                    (SELECT @a:= 0) AS a;
            

            【讨论】:

            • 我想知道,如果没有 SELECT 语句中的 AS 关键字,它是如何工作的?
            • @diEcho MySQL Docs 状态 当使用标识符为 select_expr 起别名时,AS 关键字是可选的。 请参阅此working example without AS on SQL Fiddle
            • 如果我不仅要遍历数字,还要遍历所有大写和小写字母(即创建一个以 62 为基数的数字序列),并将其全部用 0 填充怎么办? :D
            • 我建议使用显式的交叉连接。即FROM student_marks CROSS JOIN (SELECT @a:= 0) AS a;,所以意图很明确。
            • @NullPointer 你也可以INNER JOIN 到初始化变量的查询,例如SELECT @a:=@a+1 AS serial_number FROM T1 INNER JOIN T2 ON T2.ID = T1.ID INNER JOIN (SELECT @a:= 0) AS a; - sqlfiddle.com/#!9/f155b4/1
            【解决方案9】:

            不,除非您有一列包含这些数字。

            【讨论】:

              【解决方案10】:

              你为什么不把它变成一个自动增量字段?

              http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html

              【讨论】:

              • 为了简单起见,我创建了这个表。实际上,我必须在结果中添加一个序列号,这将通过连接两个表来获得。
              【解决方案11】:

              不,没有。但是您可以在程序端生成序列号,而不是在数据库端。

              【讨论】:

              • 是的,可以做到。我也已经使用 mysql 用户定义的变量生成了序列号。我想知道mysql中是否有一些替代方法可以实现这一点。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-11-21
              • 2013-02-13
              • 1970-01-01
              • 2017-02-02
              相关资源
              最近更新 更多