有一个名为 books 的表,其结构如下:
╔════════════╦═══════════╦════════╗
║ LibraryId ║ BookId ║ Price ║
╠════════════╬═══════════╬════════╣
║ 123 ║ 9001 ║ 10.99 ║
║ 123 ║ 9005 ║ 12.99 ║
║ 123 ║ 9006 ║ 7.99 ║
║ 124 ║ 8012 ║ 6.49 ║
║ 124 ║ 9001 ║ 3.19 ║
║ 124 ║ 9076 ║ 7.39 ║
╚════════════╩═══════════╩════════╝
我如何做一个选择来返回完整的表,但另外还有一个名为 Ordinal 的字段,它“计算”每个图书馆的图书数量。结果应该类似于:
╔════════════╦═══════════╦════════╦════════╗
║ LibraryId ║ BookId ║ Price ║Ordinal ║
╠════════════╬═══════════╬════════╬════════╣
║ 123 ║ 9001 ║ 10.99 ║ 1 ║
║ 123 ║ 9005 ║ 12.99 ║ 2 ║
║ 123 ║ 9006 ║ 7.99 ║ 3 ║
║ 124 ║ 8012 ║ 6.49 ║ 1 ║
║ 124 ║ 9001 ║ 3.19 ║ 2 ║
║ 124 ║ 9076 ║ 7.39 ║ 3 ║
╚════════════╩═══════════╩════════╝════════╝
我试过类似的东西:
SET @var_record = 1;
SELECT *, (@var_record := @var_record + 1) AS Ordinal
FROM books;
但是无论 libraryId 是什么,这都会继续计数。我需要在每次 libraryId 更改时重置序号的东西。我更喜欢单个查询而不是过程。
测试数据sql脚本:
create temporary table books(libraryId int, bookId int, price double(4,2));
insert into books (libraryId, bookId, price) values (123, 9001, 10.99),(123, 9005, 10.99),(123, 9006, 10.99),(124, 8001, 10.99),(124, 9001, 10.99),(124, 9076, 10.99);
最佳答案
使用变量和条件,您可以根据条件(libraryId 已更改)重置计数器。必须按列 libraryId 排序。
SELECT books.*,
if( @libId = libraryId,
@var_record := @var_record + 1,
if(@var_record := 1 and @libId := libraryId, @var_record, @var_record)
) AS Ordinal
FROM books
JOIN (SELECT @var_record := 0, @libId := 0) tmp
ORDER BY libraryId;
第二个 if 语句用于将两个赋值组合在一起并返回@var_record。
if(@var_record := 1 and @libId := libraryId, @var_record, @var_record)
关于Mysql选择序号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19559805/