У меня есть запрос MySQL, который отлично работает, когда выполняется непосредственно в моей локальной базе данных MySQL, но показывает другой результат при выполнении через PHP.
SELECT a.id, a.title, a.public, a.sysstamp, a.password, t.thumbURL, t.count
FROM 0_lychee_albums AS a
LEFT JOIN (SELECT id, album, thumbURL,
@num := IF(@group = album, @num + 1, 0) AS count,
@group := album AS dummy
from 0_lychee_photos
WHERE album != 0
ORDER BY album, star DESC) AS t ON a.id = t.album
WHERE count <= 2 OR count IS NULL;
или как однострочник:
SELECT a.id, a.title, a.public, a.sysstamp, a.password, t.thumbURL, t.count FROM 0_lychee_albums AS a LEFT JOIN (SELECT id, album, thumbURL, @num := IF(@group = album, @num + 1, 0) AS count, @group := album AS dummy FROM 0_lychee_photos WHERE album != 0 ORDER BY album, star DESC) AS t ON a.id = t.album WHERE count <= 2 OR count IS NULL;
Результат:
| id | title | public | sysstamp | password | thumbURL | count |
| 71 | [Import] 01 | 0 | 1415091268 | NULL | cad008943372d984a9b74378874128f8.jpeg | 0 |
| 72 | [Import] 9n401238 | 0 | 1415091268 | NULL | 7b832b56f182ad3403521589e2815f67.jpeg | 0 |
| 72 | [Import] 9n401238 | 0 | 1415091268 | NULL | f058f379ce519f1d8a2ff8c0f5003631.jpeg | 1 |
| 72 | [Import] 9n401238 | 0 | 1415091268 | NULL | a4d59377bed059e3f60cccf01a69c299.jpeg | 2 |
| 73 | Untitled | 0 | 1415114200 | NULL | NULL | NULL |
Результат PHP:
| id | title | public | sysstamp | password | thumbURL | count |
| 71 | [Import] 01 | 0 | 1415091268 | NULL | cad008943372d984a9b74378874128f8.jpeg | 0 |
| 72 | [Import] 9n401238 | 0 | 1415091268 | NULL | 7b832b56f182ad3403521589e2815f67.jpeg | 0 |
| 72 | [Import] 9n401238 | 0 | 1415091268 | NULL | f058f379ce519f1d8a2ff8c0f5003631.jpeg | 0 |
| 72 | [Import] 9n401238 | 0 | 1415091268 | NULL | a4d59377bed059e3f60cccf01a69c299.jpeg | 0 |
| 72 | [Import] 9n401238 | 0 | 1415092318 | NULL | 7b832b56f182ad3403521589e2815f67.jpeg | 0 |
| 72 | [Import] 9n401238 | 0 | 1415092369 | NULL | cad008943372d984a9b74378874128f8.jpeg | 0 |
| 72 | [Import] 9n401238 | 0 | 1415092369 | NULL | 84030a64a1f546e223e6a46cbf12910f.jpeg | 0 |
| 73 | Untitled | 0 | 1415114200 | NULL | NULL | NULL |
а) count
не увеличивается, как должно
б) из-за а) он показывает больше строк, чем нужно (должно быть ограничено 3 на идентификатор)
Я проверял это несколько раз, оба запроса абсолютно одинаковы. Там нет пользовательского ввода или какой-либо разницы в PHP.
Я уже проверил похожие вопросы, но ни один из них не помог. Следующие запросы показывают одинаковый результат на MySQL и PHP:
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';
Кто-нибудь знает о проблеме, объясняющей эту разницу?
Изменить с дополнительной информацией:
$database = new mysqli($host, $user, $password, $database);
$query = "SELECT a.id, a.title, a.public, a.sysstamp, a.password, t.thumbURL, t.count FROM 0_lychee_albums AS a LEFT JOIN (SELECT id, album, thumbURL, @num := IF(@group = album, @num + 1, 0) AS count, @group := album AS dummy FROM 0_lychee_photos WHERE album != 0 ORDER BY album, star DESC) AS t ON a.id = t.album WHERE count <= 2 OR count IS NULL";
$albums = $database->query($query);
while ($album = $albums->fetch_assoc()) { print_r($album); }
Я также попытался сделать это с и без следующего перед выполнением запроса:
$database->set_charset('utf8');
$database->query('SET NAMES utf8;');
Ага. Порядок оценки выражений в select
пункт не гарантируется. Таким образом, назначения переменных могут происходить в разных порядках, в зависимости от того, как вызывается запрос.
Вы можете исправить это, поместив все переменные в одно выражение. Попробуйте использовать этот подзапрос для t
:
(SELECT id, album, thumbURL,
(@num := IF(@group = album, @num + 1,
if(@group := album, 0, 0)
)
) as count
FROM 0_lychee_photos CROSS JOIN
(SELECT @num := 0, @group := NULL) vars
WHERE album <> 0
ORDER BY album, star DESC
) t
Конкретное объяснение в документация является:
Как правило, кроме инструкций SET, вы никогда не должны
присвоить значение пользовательской переменной и прочитать значение в том же самом
заявление. Например, чтобы увеличить переменную, это нормально:SET @a = @a + 1;
Для других утверждений, таких как SELECT, вы можете получить результаты, которые вы
ожидать, но это не гарантировано. В следующем заявлении вы
Можно подумать, что MySQL сначала оценит @a, а затем сделает
Назначение второе:SELECT @a, @a:=@a+1, ...;
Тем не менее, порядок оценки для выражений с участием пользователя
переменные не определены.
Простой способ решить эту проблему — установить переменные mysql в вашем PHP-документе. Как это:
$ var = mysql_query («SET @nun: = 0;»);