MySQL 为每个组创建带有序列号的视图

MySQL Create View with Sequence Numbers for Each Group

我在这个网站上看到了类似的解决方案,但由于变量使用限制,它在视图中不可用:

Generating Sequence for Each Group in MySQL

A table 说了 1000 个单词,所以这里是:

我在 table 上有这个:

Doc No  Rev
DOC-001 A01
DOC-001 A02
DOC-002 A01
DOC-002 B01
DOC-002 B02
DOC-003 Z01

我想要这个在视图中:

Doc No  Rev Seq
DOC-001 A01 1
DOC-001 A02 2
DOC-002 A01 1
DOC-002 B01 2
DOC-002 B02 3
DOC-003 Z01 1

请帮忙!

如果相关:我在 Windows 10.

上使用 MySQL Workbench

如果你是运行 MySQL 8.0,就用row_number():

select t.*, row_number() over(partition by doc_no order by rev) seq
from mytable t

如果你是运行早期版本并且你不能使用变量,那么一个选项是相关子查询(尽管这比window 函数或变量):

select
    t.*,
    (select count(*) + 1 from mytable t1 where t1.doc_no = t.doc_no and t1.rev < t.rev) seq
from mytable t

请注意,使用此技术,领带会得到相同的 seq - 所以这实际上表现得像 window 函数 rank() 而不是 row_number()

如果您使用的是旧版本的 MySQL,那么您可以使用相关子查询来生成序列:

CREATE VIEW yourView AS
SELECT
    DocNo,
    Rev,
    (SELECT COUNT(*) FROM yourTable t2 WHERE t2.DocNo = t1.DocNo AND t2.Rev <= t1.Rev) AS Seq
FROM yourTable t1
ORDER BY
    DocNo,
    Rev;

如果您使用MySQL 8+,那么使用ROW_NUMBER:

CREATE VIEW yourView AS
SELECT DocNo, Rev, ROW_NUMBER() OVER (PARTITION BY DocNo ORDER BY Rev) Seq
FROM yourTable
ORDER BY
    DocNo,
    Rev;

两个答案都有效,但是

CREATE VIEW yourView AS
SELECT DocNo, Rev, ROW_NUMBER() OVER (PARTITION BY DocNo ORDER BY Rev) Seq
FROM yourTable
ORDER BY
    DocNo,
    Rev;

更准确。这表明正是问题中提出的问题。旧式查询执行相同的工作,但如果将多个 WHERE 子句放入查询中,则结果与要求的或我们期望的相同。

我已经使用这个复杂的长查询测试了这个逻辑:

SELECT
    ROW_NUMBER() OVER (PARTITION BY Test_Centre ORDER BY Appliction_ID) Sr,
    Appliction_ID,
    Name_of_Applicant,
    Domicile, Gender,
    CONCAT(LEFT(CNIC, 5),'-',SUBSTRING(CNIC, 6, 7),'-',RIGHT(CNIC, 1)) AS CNIC,
    DATE_FORMAT(Date_of_Birth, "%d-%b-%Y") AS Data_of_Birth,
    DATE_FORMAT(FROM_DAYS(DATEDIFF('2020-08-11', Date_of_Birth)),'%Y') +0 AS Age,
    CONCAT(LEFT(Mobile_Number, 4),'-',SUBSTRING(Mobile_Number, 5, 7)) AS Mobile_Number,
    Test_Centre
FROM mt_applications
WHERE
    DATE_FORMAT(FROM_DAYS(DATEDIFF('2020-08-11', Date_of_Birth)),'%Y') >= 18 AND 
    DATE_FORMAT(FROM_DAYS(DATEDIFF('2020-08-11', Date_of_Birth)),'%Y') <= 27 AND 
    Name_of_Post = 'ASSISTANT (BPS-15)'
ORDER BY
    Test_Centre ASC,
    Appliction_ID ASC;

按预期正常工作 100:)