Mysql选择序数

时间:2013-10-24 07:38:45

标签: mysql select ordinal

有一个名为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);

2 个答案:

答案 0 :(得分:1)

使用变量和条件,您可以根据条件重置计数器(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)

答案 1 :(得分:-3)

也许你可以使用聚合函数

SELECT a.LibraryId, a.BookId, a.Price,
      (SELECT COUNT(b.BookId) FROM books b WHERE b.BookId = a.BookId AND b.LibraryId = a.LibraryId) AS Ordinal
FROM a.books