MySQL 创建序数

MySQL Create Ordinal

我正在尝试创建一个临时 table 或视图,我可以使用它来绘制联盟成员在整个赛季中改变的差点。这需要创建一个枢轴 table.

然而,即使在那之前,我也需要创建一个序数列来表示该人在那个赛季参加的第 n 场比赛。我不能使用 date_played,因为玩家可以在所有不同的日期玩,我希望每个玩家的第二场比赛垂直排列,第三场比赛也垂直排列,等等。

我使用了 this question 的答案中的代码,它看起来应该可以工作。这是相关部分的副本:

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;

`lwljhb_lwl_matches`        # One record for each match played
id
date_played
other fields about the match

id    date_played
1     2017-08-23
2     2017-08-29
3     2017-09-26
4     2017-08-24
5     2017-09-02
6     2017-09-21
7     2017-08-24
8     2017-08-31
9     2017-09-05
10    2017-09-15
11    2017-09-17
`lwljhb_users`
id
display_name

id    display_name
1     Alan
2     Bill
3     Dave


`lwljhb_lwl_players`  # One record per player per match
id
match_id              # Foreign key to matches.id
player_id             # Foreign key to users.id
end_hcp
other fields about the player's performance in the linked match

id   match_id  player_id  end_hcp
1    1         1          720
2    2         1          692
3    3         1          694
4    4         2          865
5    5         2          868
6    6         2          842
7    7         3          363
8    8         3          339
9    9         3          332
10   10        3          348
11   11        3          374

通常每条MATCH记录在PLAYERS中会有两条记录,但我没有在这里添加。 PLAYERS 的每条记录中的 id 和 match_id 都相同的事实是人为的,因为这不是真实数据。

在我使用此代码段之前,我的代码如下所示:

SELECT u.display_name,
   m.date_played,
   p.end_hcp 
FROM `lwljhb_lwl_matches` AS m
INNER JOIN `lwljhb_lwl_players` AS p
INNER JOIN `lwljhb_users` AS u
ON    m.id = p.match_id AND
      p.player_id = u.id
WHERE league_seasons_id = 12 AND
      playoff_round = 0
ORDER BY u.display_name, m.date_played

生成的数据如下所示:

display_name  date_played  end_hcp
Alan          2017-08-23   720
Alan          2017-08-29   692
Alan          2017-09-26   694
Bill          2017-08-24   865
Bill          2017-09-02   868
Bill          2017-09-21   842 
Dave          2017-08-24   363
Dave          2017-08-31   339
Dave          2017-09-05   332
Dave          2017-09-15   348
Dave          2017-09-17   374 

在赛季中的任何时候,每位球员的比赛次数都会有所不同,但到赛季结束时,他们的比赛次数都会相同。

我试过像这样将 Alin Stoian 的代码合并到我的代码中,更改我认为合适的变量名和字段名。

SET @var_record = 1;
SELECT u.display_name,
   m.date_played,
   p.end_hcp, 
    if( @player = u.display_name, 
    @var_record := @var_record + 1, 
        if(@var_record := 1 and @player := u.display_name, @var_record, @var_record)
) AS Ordinal 
FROM `lwljhb_lwl_matches` AS m
INNER JOIN `lwljhb_lwl_players` AS p
INNER JOIN `lwljhb_users` AS u
JOIN (SELECT @var_record := 0, @player := 0) tmp
ON    m.id = p.match_id AND
      p.player_id = u.id
WHERE league_seasons_id = 12 AND
      playoff_round = 0
ORDER BY u.display_name, m.date_played

我希望有一个带有序数的新列,但新列全为零。在我继续尝试枢轴 table 之前,我必须得到这些序数,所以我希望这里有人能告诉我我的错误。

试试这个:

SELECT u.display_name,
    m.date_played,
    p.end_hcp, 
    @var_record := if ( @player = u.display_name, 
                        @var_record + 1,
                        if(@player := u.display_name, 1, 1)
                    ) AS Ordinal 
FROM `lwljhb_lwl_matches` AS m
INNER JOIN `lwljhb_lwl_players` AS p
INNER JOIN `lwljhb_users` AS u
JOIN (SELECT @var_record := 0, @player := 0) tmp
ON    m.id = p.match_id AND
      p.player_id = u.id
WHERE league_seasons_id = 12 AND
      playoff_round = 0
ORDER BY u.display_name, m.date_played

Demo

好吧,事实证明我并没有在我的序数列中得到所有的 1,只是在第 1 个 25 条记录中。因为这显然是错误的,所以我没有进一步看。

我提供的示例数据是按物理顺序和逻辑顺序排列的,但我的实际数据不是。这是我能想到的唯一区别,所以我进一步调查,发现在输出的第 1,000 条记录中,我得到了 7 条记录,其中 2 作为序号,而不是巧合 m.ids 是连续的。

我创建了一个视图来像示例中那样按顺序排列数据,并将其连接到 table 的其余部分,但对于 Ordinal 仍然有错误的数据。

当我将视图换成临时 table 时,它起作用了。事实证明,如果存在通过加入的 ORDER BY,视图中的 ORDER BY 将被忽略。

Bill Karwin 在另一个问题 (46892912) 中向我指出了这一点。