MySQL select with MIN() does not select all rows












2















Background: I'm a hobby programmer, trying to create a personal leaderboard for a racing game. This is done with a Raspberry Pi running a MariaDB. Leaderboard is scraped from another site and stored in the db. Then my personal laptimes are received with UDP from the game, and stored in the same MariaDB on the Pi. The results are shown on a php page. User can select different car and track combo on the php page. I want to display every players best (lowest) laptime for the chosen car-track combo. (Player names are offical gamertags, where no duplicates are allowed. They are all unique.)



With a SELECT statement like this, I get 84 rows, but I get all my own laptimes, and I only want to show my best laptime for that car-track combo.



$sqlstring1="SELECT * FROM laptimes WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC";


I tried to use a SELECT like this, but then I only get 54 rows? I only have two laptimes recorded, so a bunch of laptimes from other people are not shown.



$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";


I've tried different SELECTS too, with LEFT JOIN for example.
The $trackselect and $carselect are values from dropdowns on php page, They seem to be working in both cases. $choice value is from two different buttons on php page. Button 1 sets $choice ="". Button 2 sets $choice = " AND player LIKE 'Maskmagog' ". This is used to show only my laptimes. It seems to be working.



Question: Why are some rows not selected in the 2nd SELECT?



Here are the top 5 output for the first SELECT:



1.  sel                 Ginetta G40 Junior  00:56.017   
2. {DFRUK}michaeldimel Ginetta G40 Junior 00:56.149
3. Yorkshire Farmer Ginetta G40 Junior 00:56.709
4. piquet Ginetta G40 Junior 00:56.756
5. Oomph Ginetta G40 Junior 00:56.981


and the 2nd SELECT:



1.  Yorkshire Farmer    Ginetta G40 Junior  00:56.709   
2. saya777 Ginetta G40 Junior 00:57.002
3. Lamb4chop™ Ginetta G40 Junior 00:57.067
4. Jonge Ginetta G40 Junior 00:57.250
5. NsGTR35 Ginetta G40 Junior 00:57.296


As you can see, only "Yorkshire Farmer" survives and is shown in both selects, and I don't understand why.



Here is the full php page, on Pastebin: https://pastebin.com/ALTzfm2S



EDIT: Thanks to comments below, I finally understand why the 2nd SELECT doesn't work. It first selects the players lowest laptime, regardless of track/car. Then it applies the WHERE, and the players who have their lowest laptimes set in other cars/tracks are of course removed from the result. D'oh! :)



EDIT 2: Well it seems I can't mark more than one answer. Both solutions seems to work, many thanks to all involved! I can't tell if one answer is better/more useful/more correct.










share|improve this question

























  • Have you dumped $sqlstring1 to verify it is as you espect? I recommend using prepared statements and avoid embedded parameters into the string, use ? and pass parameters, this will take care of all the escaping for you.

    – SPlatten
    Nov 26 '18 at 9:44






  • 1





    It seems to me you just need the inner query with the conditions of the outer query. And you should definitely use a prepared statement.

    – jeroen
    Nov 26 '18 at 10:01











  • Thank you, I'll change it to ? and pass parameters. I have echoed $sqlstring1 and it looks ok to my untrained eyes at least. I did have some trouble with the escaping, and echoing it helped me fix that. If the 2nd SELECT looks ok, then it probably is an issue with the WHERE statements? Although all entries are identical, regarding $trackselect and $carselect afaik. Some of the players are featured several times in the db (different cars-tracks), some only once. I can't see a pattern regarding those not selected vs those selected in both SELECTs.

    – Martin
    Nov 26 '18 at 10:07











  • @jeroen Thanks, I'll change to prepared statement. But for now, not sure I understand, Do you mean like this: SELECT player, MIN(laptime), WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC;

    – Martin
    Nov 26 '18 at 10:12






  • 1





    @jeroen cheers, thanks! I can't actually test it right now since I'm at work and the Pi is at home, not reachable from the outside. But I'll test it as soon as I get home!

    – Martin
    Nov 26 '18 at 10:23
















2















Background: I'm a hobby programmer, trying to create a personal leaderboard for a racing game. This is done with a Raspberry Pi running a MariaDB. Leaderboard is scraped from another site and stored in the db. Then my personal laptimes are received with UDP from the game, and stored in the same MariaDB on the Pi. The results are shown on a php page. User can select different car and track combo on the php page. I want to display every players best (lowest) laptime for the chosen car-track combo. (Player names are offical gamertags, where no duplicates are allowed. They are all unique.)



With a SELECT statement like this, I get 84 rows, but I get all my own laptimes, and I only want to show my best laptime for that car-track combo.



$sqlstring1="SELECT * FROM laptimes WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC";


I tried to use a SELECT like this, but then I only get 54 rows? I only have two laptimes recorded, so a bunch of laptimes from other people are not shown.



$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";


I've tried different SELECTS too, with LEFT JOIN for example.
The $trackselect and $carselect are values from dropdowns on php page, They seem to be working in both cases. $choice value is from two different buttons on php page. Button 1 sets $choice ="". Button 2 sets $choice = " AND player LIKE 'Maskmagog' ". This is used to show only my laptimes. It seems to be working.



Question: Why are some rows not selected in the 2nd SELECT?



Here are the top 5 output for the first SELECT:



1.  sel                 Ginetta G40 Junior  00:56.017   
2. {DFRUK}michaeldimel Ginetta G40 Junior 00:56.149
3. Yorkshire Farmer Ginetta G40 Junior 00:56.709
4. piquet Ginetta G40 Junior 00:56.756
5. Oomph Ginetta G40 Junior 00:56.981


and the 2nd SELECT:



1.  Yorkshire Farmer    Ginetta G40 Junior  00:56.709   
2. saya777 Ginetta G40 Junior 00:57.002
3. Lamb4chop™ Ginetta G40 Junior 00:57.067
4. Jonge Ginetta G40 Junior 00:57.250
5. NsGTR35 Ginetta G40 Junior 00:57.296


As you can see, only "Yorkshire Farmer" survives and is shown in both selects, and I don't understand why.



Here is the full php page, on Pastebin: https://pastebin.com/ALTzfm2S



EDIT: Thanks to comments below, I finally understand why the 2nd SELECT doesn't work. It first selects the players lowest laptime, regardless of track/car. Then it applies the WHERE, and the players who have their lowest laptimes set in other cars/tracks are of course removed from the result. D'oh! :)



EDIT 2: Well it seems I can't mark more than one answer. Both solutions seems to work, many thanks to all involved! I can't tell if one answer is better/more useful/more correct.










share|improve this question

























  • Have you dumped $sqlstring1 to verify it is as you espect? I recommend using prepared statements and avoid embedded parameters into the string, use ? and pass parameters, this will take care of all the escaping for you.

    – SPlatten
    Nov 26 '18 at 9:44






  • 1





    It seems to me you just need the inner query with the conditions of the outer query. And you should definitely use a prepared statement.

    – jeroen
    Nov 26 '18 at 10:01











  • Thank you, I'll change it to ? and pass parameters. I have echoed $sqlstring1 and it looks ok to my untrained eyes at least. I did have some trouble with the escaping, and echoing it helped me fix that. If the 2nd SELECT looks ok, then it probably is an issue with the WHERE statements? Although all entries are identical, regarding $trackselect and $carselect afaik. Some of the players are featured several times in the db (different cars-tracks), some only once. I can't see a pattern regarding those not selected vs those selected in both SELECTs.

    – Martin
    Nov 26 '18 at 10:07











  • @jeroen Thanks, I'll change to prepared statement. But for now, not sure I understand, Do you mean like this: SELECT player, MIN(laptime), WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC;

    – Martin
    Nov 26 '18 at 10:12






  • 1





    @jeroen cheers, thanks! I can't actually test it right now since I'm at work and the Pi is at home, not reachable from the outside. But I'll test it as soon as I get home!

    – Martin
    Nov 26 '18 at 10:23














2












2








2








Background: I'm a hobby programmer, trying to create a personal leaderboard for a racing game. This is done with a Raspberry Pi running a MariaDB. Leaderboard is scraped from another site and stored in the db. Then my personal laptimes are received with UDP from the game, and stored in the same MariaDB on the Pi. The results are shown on a php page. User can select different car and track combo on the php page. I want to display every players best (lowest) laptime for the chosen car-track combo. (Player names are offical gamertags, where no duplicates are allowed. They are all unique.)



With a SELECT statement like this, I get 84 rows, but I get all my own laptimes, and I only want to show my best laptime for that car-track combo.



$sqlstring1="SELECT * FROM laptimes WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC";


I tried to use a SELECT like this, but then I only get 54 rows? I only have two laptimes recorded, so a bunch of laptimes from other people are not shown.



$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";


I've tried different SELECTS too, with LEFT JOIN for example.
The $trackselect and $carselect are values from dropdowns on php page, They seem to be working in both cases. $choice value is from two different buttons on php page. Button 1 sets $choice ="". Button 2 sets $choice = " AND player LIKE 'Maskmagog' ". This is used to show only my laptimes. It seems to be working.



Question: Why are some rows not selected in the 2nd SELECT?



Here are the top 5 output for the first SELECT:



1.  sel                 Ginetta G40 Junior  00:56.017   
2. {DFRUK}michaeldimel Ginetta G40 Junior 00:56.149
3. Yorkshire Farmer Ginetta G40 Junior 00:56.709
4. piquet Ginetta G40 Junior 00:56.756
5. Oomph Ginetta G40 Junior 00:56.981


and the 2nd SELECT:



1.  Yorkshire Farmer    Ginetta G40 Junior  00:56.709   
2. saya777 Ginetta G40 Junior 00:57.002
3. Lamb4chop™ Ginetta G40 Junior 00:57.067
4. Jonge Ginetta G40 Junior 00:57.250
5. NsGTR35 Ginetta G40 Junior 00:57.296


As you can see, only "Yorkshire Farmer" survives and is shown in both selects, and I don't understand why.



Here is the full php page, on Pastebin: https://pastebin.com/ALTzfm2S



EDIT: Thanks to comments below, I finally understand why the 2nd SELECT doesn't work. It first selects the players lowest laptime, regardless of track/car. Then it applies the WHERE, and the players who have their lowest laptimes set in other cars/tracks are of course removed from the result. D'oh! :)



EDIT 2: Well it seems I can't mark more than one answer. Both solutions seems to work, many thanks to all involved! I can't tell if one answer is better/more useful/more correct.










share|improve this question
















Background: I'm a hobby programmer, trying to create a personal leaderboard for a racing game. This is done with a Raspberry Pi running a MariaDB. Leaderboard is scraped from another site and stored in the db. Then my personal laptimes are received with UDP from the game, and stored in the same MariaDB on the Pi. The results are shown on a php page. User can select different car and track combo on the php page. I want to display every players best (lowest) laptime for the chosen car-track combo. (Player names are offical gamertags, where no duplicates are allowed. They are all unique.)



With a SELECT statement like this, I get 84 rows, but I get all my own laptimes, and I only want to show my best laptime for that car-track combo.



$sqlstring1="SELECT * FROM laptimes WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC";


I tried to use a SELECT like this, but then I only get 54 rows? I only have two laptimes recorded, so a bunch of laptimes from other people are not shown.



$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";


I've tried different SELECTS too, with LEFT JOIN for example.
The $trackselect and $carselect are values from dropdowns on php page, They seem to be working in both cases. $choice value is from two different buttons on php page. Button 1 sets $choice ="". Button 2 sets $choice = " AND player LIKE 'Maskmagog' ". This is used to show only my laptimes. It seems to be working.



Question: Why are some rows not selected in the 2nd SELECT?



Here are the top 5 output for the first SELECT:



1.  sel                 Ginetta G40 Junior  00:56.017   
2. {DFRUK}michaeldimel Ginetta G40 Junior 00:56.149
3. Yorkshire Farmer Ginetta G40 Junior 00:56.709
4. piquet Ginetta G40 Junior 00:56.756
5. Oomph Ginetta G40 Junior 00:56.981


and the 2nd SELECT:



1.  Yorkshire Farmer    Ginetta G40 Junior  00:56.709   
2. saya777 Ginetta G40 Junior 00:57.002
3. Lamb4chop™ Ginetta G40 Junior 00:57.067
4. Jonge Ginetta G40 Junior 00:57.250
5. NsGTR35 Ginetta G40 Junior 00:57.296


As you can see, only "Yorkshire Farmer" survives and is shown in both selects, and I don't understand why.



Here is the full php page, on Pastebin: https://pastebin.com/ALTzfm2S



EDIT: Thanks to comments below, I finally understand why the 2nd SELECT doesn't work. It first selects the players lowest laptime, regardless of track/car. Then it applies the WHERE, and the players who have their lowest laptimes set in other cars/tracks are of course removed from the result. D'oh! :)



EDIT 2: Well it seems I can't mark more than one answer. Both solutions seems to work, many thanks to all involved! I can't tell if one answer is better/more useful/more correct.







php mysql select min






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 26 '18 at 16:23







Martin

















asked Nov 26 '18 at 9:39









MartinMartin

155




155













  • Have you dumped $sqlstring1 to verify it is as you espect? I recommend using prepared statements and avoid embedded parameters into the string, use ? and pass parameters, this will take care of all the escaping for you.

    – SPlatten
    Nov 26 '18 at 9:44






  • 1





    It seems to me you just need the inner query with the conditions of the outer query. And you should definitely use a prepared statement.

    – jeroen
    Nov 26 '18 at 10:01











  • Thank you, I'll change it to ? and pass parameters. I have echoed $sqlstring1 and it looks ok to my untrained eyes at least. I did have some trouble with the escaping, and echoing it helped me fix that. If the 2nd SELECT looks ok, then it probably is an issue with the WHERE statements? Although all entries are identical, regarding $trackselect and $carselect afaik. Some of the players are featured several times in the db (different cars-tracks), some only once. I can't see a pattern regarding those not selected vs those selected in both SELECTs.

    – Martin
    Nov 26 '18 at 10:07











  • @jeroen Thanks, I'll change to prepared statement. But for now, not sure I understand, Do you mean like this: SELECT player, MIN(laptime), WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC;

    – Martin
    Nov 26 '18 at 10:12






  • 1





    @jeroen cheers, thanks! I can't actually test it right now since I'm at work and the Pi is at home, not reachable from the outside. But I'll test it as soon as I get home!

    – Martin
    Nov 26 '18 at 10:23



















  • Have you dumped $sqlstring1 to verify it is as you espect? I recommend using prepared statements and avoid embedded parameters into the string, use ? and pass parameters, this will take care of all the escaping for you.

    – SPlatten
    Nov 26 '18 at 9:44






  • 1





    It seems to me you just need the inner query with the conditions of the outer query. And you should definitely use a prepared statement.

    – jeroen
    Nov 26 '18 at 10:01











  • Thank you, I'll change it to ? and pass parameters. I have echoed $sqlstring1 and it looks ok to my untrained eyes at least. I did have some trouble with the escaping, and echoing it helped me fix that. If the 2nd SELECT looks ok, then it probably is an issue with the WHERE statements? Although all entries are identical, regarding $trackselect and $carselect afaik. Some of the players are featured several times in the db (different cars-tracks), some only once. I can't see a pattern regarding those not selected vs those selected in both SELECTs.

    – Martin
    Nov 26 '18 at 10:07











  • @jeroen Thanks, I'll change to prepared statement. But for now, not sure I understand, Do you mean like this: SELECT player, MIN(laptime), WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC;

    – Martin
    Nov 26 '18 at 10:12






  • 1





    @jeroen cheers, thanks! I can't actually test it right now since I'm at work and the Pi is at home, not reachable from the outside. But I'll test it as soon as I get home!

    – Martin
    Nov 26 '18 at 10:23

















Have you dumped $sqlstring1 to verify it is as you espect? I recommend using prepared statements and avoid embedded parameters into the string, use ? and pass parameters, this will take care of all the escaping for you.

– SPlatten
Nov 26 '18 at 9:44





Have you dumped $sqlstring1 to verify it is as you espect? I recommend using prepared statements and avoid embedded parameters into the string, use ? and pass parameters, this will take care of all the escaping for you.

– SPlatten
Nov 26 '18 at 9:44




1




1





It seems to me you just need the inner query with the conditions of the outer query. And you should definitely use a prepared statement.

– jeroen
Nov 26 '18 at 10:01





It seems to me you just need the inner query with the conditions of the outer query. And you should definitely use a prepared statement.

– jeroen
Nov 26 '18 at 10:01













Thank you, I'll change it to ? and pass parameters. I have echoed $sqlstring1 and it looks ok to my untrained eyes at least. I did have some trouble with the escaping, and echoing it helped me fix that. If the 2nd SELECT looks ok, then it probably is an issue with the WHERE statements? Although all entries are identical, regarding $trackselect and $carselect afaik. Some of the players are featured several times in the db (different cars-tracks), some only once. I can't see a pattern regarding those not selected vs those selected in both SELECTs.

– Martin
Nov 26 '18 at 10:07





Thank you, I'll change it to ? and pass parameters. I have echoed $sqlstring1 and it looks ok to my untrained eyes at least. I did have some trouble with the escaping, and echoing it helped me fix that. If the 2nd SELECT looks ok, then it probably is an issue with the WHERE statements? Although all entries are identical, regarding $trackselect and $carselect afaik. Some of the players are featured several times in the db (different cars-tracks), some only once. I can't see a pattern regarding those not selected vs those selected in both SELECTs.

– Martin
Nov 26 '18 at 10:07













@jeroen Thanks, I'll change to prepared statement. But for now, not sure I understand, Do you mean like this: SELECT player, MIN(laptime), WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC;

– Martin
Nov 26 '18 at 10:12





@jeroen Thanks, I'll change to prepared statement. But for now, not sure I understand, Do you mean like this: SELECT player, MIN(laptime), WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC;

– Martin
Nov 26 '18 at 10:12




1




1





@jeroen cheers, thanks! I can't actually test it right now since I'm at work and the Pi is at home, not reachable from the outside. But I'll test it as soon as I get home!

– Martin
Nov 26 '18 at 10:23





@jeroen cheers, thanks! I can't actually test it right now since I'm at work and the Pi is at home, not reachable from the outside. But I'll test it as soon as I get home!

– Martin
Nov 26 '18 at 10:23












2 Answers
2






active

oldest

votes


















0














Based on your requirements, you don't need nested SELECT's. You can add the conditions to your inner query and use that:



SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
WHERE track = ?
AND carname LIKE ?
AND player LIKE ?
GROUP BY player
ORDER BY laptime ASC


If you don't need all conditions, you can build the sql statement string dynamically, adding only the ones you need. Afterwards you bind the required number of variables and execute the statement.






share|improve this answer
























  • Thanks, I'll try as soon as I can. Also thank you for showing how to pass parameters with ? (I'm a rookie).

    – Martin
    Nov 26 '18 at 10:30






  • 1





    Thank you, this works fine!

    – Martin
    Nov 26 '18 at 16:13



















1














Your problem is that your subquery is returning the minimum lap time for a player regardless of track or car. You need it to return the minimum lap time for the player for each car on each track they have raced on, so you need to change the GROUP BY to



GROUP BY player, track, carname


and then you also need to add track and carname to the subquery SELECT and to the JOIN. So your query should look like:



$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, track, carname, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player, track, carname
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime AND t1.track = t2.track AND t1.carname = t2.carname
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";





share|improve this answer


























  • Thanks, this sounds very interesting. I'll try as soon as I get home.

    – Martin
    Nov 26 '18 at 10:28











  • Perhaps even car name should be included in the group by / joining condition if a player can race with multiple cars on the same track. Regardless of this, I think this answer is on the right track :)

    – Shadow
    Nov 26 '18 at 10:49













  • @Shadow yes on closer reading I think you're right. I'll update the answer.

    – Nick
    Nov 26 '18 at 11:25











  • @Martin I've updated my answer based on Shadow's comment which I think is correct; I don't think I had completely understood the question.

    – Nick
    Nov 26 '18 at 11:27











  • Or you could add the same filter criteria to the subquery and then you do not need group by on car and track, only on user. Or just use the subquery without the outer query with filters and add the filter values as static fields to the select list and group by on the players only.

    – Shadow
    Nov 26 '18 at 12:55












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53478272%2fmysql-select-with-min-does-not-select-all-rows%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














Based on your requirements, you don't need nested SELECT's. You can add the conditions to your inner query and use that:



SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
WHERE track = ?
AND carname LIKE ?
AND player LIKE ?
GROUP BY player
ORDER BY laptime ASC


If you don't need all conditions, you can build the sql statement string dynamically, adding only the ones you need. Afterwards you bind the required number of variables and execute the statement.






share|improve this answer
























  • Thanks, I'll try as soon as I can. Also thank you for showing how to pass parameters with ? (I'm a rookie).

    – Martin
    Nov 26 '18 at 10:30






  • 1





    Thank you, this works fine!

    – Martin
    Nov 26 '18 at 16:13
















0














Based on your requirements, you don't need nested SELECT's. You can add the conditions to your inner query and use that:



SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
WHERE track = ?
AND carname LIKE ?
AND player LIKE ?
GROUP BY player
ORDER BY laptime ASC


If you don't need all conditions, you can build the sql statement string dynamically, adding only the ones you need. Afterwards you bind the required number of variables and execute the statement.






share|improve this answer
























  • Thanks, I'll try as soon as I can. Also thank you for showing how to pass parameters with ? (I'm a rookie).

    – Martin
    Nov 26 '18 at 10:30






  • 1





    Thank you, this works fine!

    – Martin
    Nov 26 '18 at 16:13














0












0








0







Based on your requirements, you don't need nested SELECT's. You can add the conditions to your inner query and use that:



SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
WHERE track = ?
AND carname LIKE ?
AND player LIKE ?
GROUP BY player
ORDER BY laptime ASC


If you don't need all conditions, you can build the sql statement string dynamically, adding only the ones you need. Afterwards you bind the required number of variables and execute the statement.






share|improve this answer













Based on your requirements, you don't need nested SELECT's. You can add the conditions to your inner query and use that:



SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
WHERE track = ?
AND carname LIKE ?
AND player LIKE ?
GROUP BY player
ORDER BY laptime ASC


If you don't need all conditions, you can build the sql statement string dynamically, adding only the ones you need. Afterwards you bind the required number of variables and execute the statement.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 26 '18 at 10:20









jeroenjeroen

82.8k18100124




82.8k18100124













  • Thanks, I'll try as soon as I can. Also thank you for showing how to pass parameters with ? (I'm a rookie).

    – Martin
    Nov 26 '18 at 10:30






  • 1





    Thank you, this works fine!

    – Martin
    Nov 26 '18 at 16:13



















  • Thanks, I'll try as soon as I can. Also thank you for showing how to pass parameters with ? (I'm a rookie).

    – Martin
    Nov 26 '18 at 10:30






  • 1





    Thank you, this works fine!

    – Martin
    Nov 26 '18 at 16:13

















Thanks, I'll try as soon as I can. Also thank you for showing how to pass parameters with ? (I'm a rookie).

– Martin
Nov 26 '18 at 10:30





Thanks, I'll try as soon as I can. Also thank you for showing how to pass parameters with ? (I'm a rookie).

– Martin
Nov 26 '18 at 10:30




1




1





Thank you, this works fine!

– Martin
Nov 26 '18 at 16:13





Thank you, this works fine!

– Martin
Nov 26 '18 at 16:13













1














Your problem is that your subquery is returning the minimum lap time for a player regardless of track or car. You need it to return the minimum lap time for the player for each car on each track they have raced on, so you need to change the GROUP BY to



GROUP BY player, track, carname


and then you also need to add track and carname to the subquery SELECT and to the JOIN. So your query should look like:



$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, track, carname, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player, track, carname
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime AND t1.track = t2.track AND t1.carname = t2.carname
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";





share|improve this answer


























  • Thanks, this sounds very interesting. I'll try as soon as I get home.

    – Martin
    Nov 26 '18 at 10:28











  • Perhaps even car name should be included in the group by / joining condition if a player can race with multiple cars on the same track. Regardless of this, I think this answer is on the right track :)

    – Shadow
    Nov 26 '18 at 10:49













  • @Shadow yes on closer reading I think you're right. I'll update the answer.

    – Nick
    Nov 26 '18 at 11:25











  • @Martin I've updated my answer based on Shadow's comment which I think is correct; I don't think I had completely understood the question.

    – Nick
    Nov 26 '18 at 11:27











  • Or you could add the same filter criteria to the subquery and then you do not need group by on car and track, only on user. Or just use the subquery without the outer query with filters and add the filter values as static fields to the select list and group by on the players only.

    – Shadow
    Nov 26 '18 at 12:55
















1














Your problem is that your subquery is returning the minimum lap time for a player regardless of track or car. You need it to return the minimum lap time for the player for each car on each track they have raced on, so you need to change the GROUP BY to



GROUP BY player, track, carname


and then you also need to add track and carname to the subquery SELECT and to the JOIN. So your query should look like:



$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, track, carname, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player, track, carname
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime AND t1.track = t2.track AND t1.carname = t2.carname
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";





share|improve this answer


























  • Thanks, this sounds very interesting. I'll try as soon as I get home.

    – Martin
    Nov 26 '18 at 10:28











  • Perhaps even car name should be included in the group by / joining condition if a player can race with multiple cars on the same track. Regardless of this, I think this answer is on the right track :)

    – Shadow
    Nov 26 '18 at 10:49













  • @Shadow yes on closer reading I think you're right. I'll update the answer.

    – Nick
    Nov 26 '18 at 11:25











  • @Martin I've updated my answer based on Shadow's comment which I think is correct; I don't think I had completely understood the question.

    – Nick
    Nov 26 '18 at 11:27











  • Or you could add the same filter criteria to the subquery and then you do not need group by on car and track, only on user. Or just use the subquery without the outer query with filters and add the filter values as static fields to the select list and group by on the players only.

    – Shadow
    Nov 26 '18 at 12:55














1












1








1







Your problem is that your subquery is returning the minimum lap time for a player regardless of track or car. You need it to return the minimum lap time for the player for each car on each track they have raced on, so you need to change the GROUP BY to



GROUP BY player, track, carname


and then you also need to add track and carname to the subquery SELECT and to the JOIN. So your query should look like:



$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, track, carname, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player, track, carname
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime AND t1.track = t2.track AND t1.carname = t2.carname
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";





share|improve this answer















Your problem is that your subquery is returning the minimum lap time for a player regardless of track or car. You need it to return the minimum lap time for the player for each car on each track they have raced on, so you need to change the GROUP BY to



GROUP BY player, track, carname


and then you also need to add track and carname to the subquery SELECT and to the JOIN. So your query should look like:



$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, track, carname, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player, track, carname
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime AND t1.track = t2.track AND t1.carname = t2.carname
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 26 '18 at 11:26

























answered Nov 26 '18 at 10:11









NickNick

37.9k132443




37.9k132443













  • Thanks, this sounds very interesting. I'll try as soon as I get home.

    – Martin
    Nov 26 '18 at 10:28











  • Perhaps even car name should be included in the group by / joining condition if a player can race with multiple cars on the same track. Regardless of this, I think this answer is on the right track :)

    – Shadow
    Nov 26 '18 at 10:49













  • @Shadow yes on closer reading I think you're right. I'll update the answer.

    – Nick
    Nov 26 '18 at 11:25











  • @Martin I've updated my answer based on Shadow's comment which I think is correct; I don't think I had completely understood the question.

    – Nick
    Nov 26 '18 at 11:27











  • Or you could add the same filter criteria to the subquery and then you do not need group by on car and track, only on user. Or just use the subquery without the outer query with filters and add the filter values as static fields to the select list and group by on the players only.

    – Shadow
    Nov 26 '18 at 12:55



















  • Thanks, this sounds very interesting. I'll try as soon as I get home.

    – Martin
    Nov 26 '18 at 10:28











  • Perhaps even car name should be included in the group by / joining condition if a player can race with multiple cars on the same track. Regardless of this, I think this answer is on the right track :)

    – Shadow
    Nov 26 '18 at 10:49













  • @Shadow yes on closer reading I think you're right. I'll update the answer.

    – Nick
    Nov 26 '18 at 11:25











  • @Martin I've updated my answer based on Shadow's comment which I think is correct; I don't think I had completely understood the question.

    – Nick
    Nov 26 '18 at 11:27











  • Or you could add the same filter criteria to the subquery and then you do not need group by on car and track, only on user. Or just use the subquery without the outer query with filters and add the filter values as static fields to the select list and group by on the players only.

    – Shadow
    Nov 26 '18 at 12:55

















Thanks, this sounds very interesting. I'll try as soon as I get home.

– Martin
Nov 26 '18 at 10:28





Thanks, this sounds very interesting. I'll try as soon as I get home.

– Martin
Nov 26 '18 at 10:28













Perhaps even car name should be included in the group by / joining condition if a player can race with multiple cars on the same track. Regardless of this, I think this answer is on the right track :)

– Shadow
Nov 26 '18 at 10:49







Perhaps even car name should be included in the group by / joining condition if a player can race with multiple cars on the same track. Regardless of this, I think this answer is on the right track :)

– Shadow
Nov 26 '18 at 10:49















@Shadow yes on closer reading I think you're right. I'll update the answer.

– Nick
Nov 26 '18 at 11:25





@Shadow yes on closer reading I think you're right. I'll update the answer.

– Nick
Nov 26 '18 at 11:25













@Martin I've updated my answer based on Shadow's comment which I think is correct; I don't think I had completely understood the question.

– Nick
Nov 26 '18 at 11:27





@Martin I've updated my answer based on Shadow's comment which I think is correct; I don't think I had completely understood the question.

– Nick
Nov 26 '18 at 11:27













Or you could add the same filter criteria to the subquery and then you do not need group by on car and track, only on user. Or just use the subquery without the outer query with filters and add the filter values as static fields to the select list and group by on the players only.

– Shadow
Nov 26 '18 at 12:55





Or you could add the same filter criteria to the subquery and then you do not need group by on car and track, only on user. Or just use the subquery without the outer query with filters and add the filter values as static fields to the select list and group by on the players only.

– Shadow
Nov 26 '18 at 12:55


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53478272%2fmysql-select-with-min-does-not-select-all-rows%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Wiesbaden

Marschland

Dieringhausen