【问题标题】:How to generate sequence number in MySQL view?如何在 MySQL 视图中生成序列号?
【发布时间】:2023-10-10 23:27:01
【问题描述】:

我在 Linux 下使用 MySQL 5.6。

我有一个表格让用户输入一个起始编号和一个终止编号。

然后,有一个视图可以从另一个表中选择一些记录,这些记录的帐号介于 from-number 和 to-number 之间。

最难的问题是,用户希望视图中的每条记录都有一个序列号,从 1 开始。例如,如果视图显示 37 行,则序列号应该从 1、2、3、...直到37岁,没有跳号。视图的排序顺序并不重要。

我知道 MySQL 表中有自增列。但是,就我而言,我必须使用 VIEW,而不是表格。

有人知道怎么做吗?

顺便说一句,我必须使用 VIEW 来执行此操作,而不是 SELECT 语句。用户不知道如何输入 SELECT 语句,但他们知道如何点击视图查看视图。

【问题讨论】:

  • 该序列将用于什么?您不能将其用于任何查询,那么它的意义何在?
  • ROW_NUMBER() in MySQL的可能重复
  • @Mjh 有无数种方法可以在查询中使用序列或 ROW_NUMBER,这就是为什么大多数数据库已经有了排名功能
  • @PanagiotisKanavos 生成这样的序列,不引用视图中任何表的任何主键是绝对没用的。我知道你认为你是对的,但有一种简单的方法可以验证我所说的 - 使用它。尤其是在稍大的桌子上。我已经知道结果,但请随意自娱自乐。此外,不是相关 RDBMS 的标签。
  • @Mjh 我知道,我一直使用序列和行号,这就是为什么我说它非常有用。无论是对结果进行排名、分页还是跨表序列和 ROW_NUMBER 生成唯一 ID 都非常有用。无论如何,it's possible but slow even in views

标签: mysql


【解决方案1】:

顺便说一句,我必须使用 VIEW 来执行此操作,而不是 SELECT 语句。用户确实 不知道如何输入 SELECT 语句,但他们知道如何单击 view 查看视图。

从技术上讲,您想要这样的东西来模拟排名或行号..

CREATE VIEW table_view 
AS
 SELECT
  *
  , (@row_number := @row_number + 1) AS row_number 
 FROM 
  table
 # Because a SQL table is a unsorted set off data ORDER BY is needed to get stabile ordered results.
 ORDER BY
  table.column ASC 
CROSS JOIN (SELECT @row_number := 0) AS init_user_var  

您不能使用此 SQL 代码,如果您尝试使用用户变量创建视图,则会收到以下错误。

Error Code: 1351
View's SELECT contains a variable or parameter

下面的 SQL 代码还可以生成 row_number。 这假设您有一个使用 AUTO_INCREMENT 生成的 id 列。 但是子查询是一个相关的子查询,这使得在较大的表上执行非常慢,因为需要对每条记录执行计数。

CREATE VIEW table_view
AS
 SELECT 
  *
  , (SELECT COUNT(*) + 1 FROM table inner WHERE inner.id < outer.id) AS row_number
 FROM 
   table outer

仅限 MySQL 8.0+。

MySQL 支持窗口函数,因此不需要 MySQL 的用户变量来模拟排名或行号。

CREATE VIEW table_view 
AS
 SELECT
  *
 # Because a SQL table is a unsorted set off data ORDER BY is needed to get stabile ordered results.
  , (ROW_NUMBER() OVER (ORDER BY table.column ASC)) AS row_number
 FROM 
  table

【讨论】:

  • 另一种可能是第二个答案here。左连接技巧可以返回 X 个 ID 及其排名,然后这些 ID 可用于加载整行。对 ID 可能进行索引意味着速度不会很差。值得进行基准测试
  • 谢谢雷蒙德。我使用第二个答案来实现视图。只需对您的 SQL 进行一个小修复。这是我的 SQL: create view [table]_row_number as select (select count() + 1 from [table] t where t.id from [table ] x
【解决方案2】:

你可以看看this question 和我在这里报告的答案:

MySQL 中没有排名功能。你能得到的最接近的是 使用变量:

SELECT t.*, 
       @rownum := @rownum + 1 AS rank
  FROM YOUR_TABLE t, 
       (SELECT @rownum := 0) r

通过这种方式,您可以在结果中添加行计数器。

【讨论】:

  • 在这种情况下,您应该将问题标记为重复
  • 但是,在我看来,MySQL 5.6 无法使用子查询创建视图。让我下周一试试
  • @AlvinSIU 还有其他技术如shown hereSELECT t.id, (SELECT COUNT(*) FROM TABLE WHERE id &lt; t.id) +1 AS NUM from t.
  • @kiks73 不需要删除答案,但是标记是一个好习惯。