I'm trying to create a temp table or view that I can use for charting league members changing handicaps over the season. This requires creating a pivot table.
Even before that, however, I need to create an ordinal column to represent the nth match the person played that season. I can't use date_played since players can play on all different dates, and I'd like each player's 2nd match to line up vertically, and their third to do so as well, etc.
I used code from the answer to this question which seemed like it should work. Here's a copy of the relevant section:
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
Normally there would be two records in PLAYERS for each MATCH record, but I didn't add them here. The fact that the id and match_id are the same in every record of PLAYERS is artificial because this isn't real data.
Before I used this snippet, my code looked like this:
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
and generated data that looks like this:
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
At any time during the season there will be different numbers of matches played by each of the players, but by the end of the season, they will have all played the same number of matches.
I tried to incorporate Alin Stoian's code into mine like so, changing a variable name and field names as I thought appropriate.
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
I was hoping for a new column with the ordinals, but the new column is all zeros. Before I move on to trying the pivot table, I have to get these ordinals, so I hope someone here can show me my mistake.
OK, it turns out that I wasn't getting all 1s in my Ordinal column after all, just in the 1st 25 records. Since it was obviously wrong I didn't look further.
The sample data I provided is in physical order as well as logical order, but MY ACTUAL data is not. That was the only difference I could think of, so I investigated further and found that in the 1st 1,000 records of output I got 7 records with 2 as the ordinal, not coincidentally where the m.ids were consecutive.
I created a view to put the data in order like in the sample and the JOINed that to the rest of the tables but still got bad data for the Ordinal.
When I swapped out the view for a temporary table it worked. It turns out that an ORDER BY in a view will be ignored if there's an ORDER by joining to it.
Bill Karwin pointed this out to me in a different question (46892912).