9

ローカルの 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  |

a)count必要なように増加していない
b) a) 必要以上の行が表示されているため (ID ごとに 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;');
4

2 に答える 2

4

うん。select句内の式の評価順序は保証されません。そのため、変数の割り当ては、クエリの呼び出し方法に応じて、さまざまな順序で発生する可能性があります。

これは、すべての変数の割り当てを 1 つの式に入れることで修正できます。次のサブクエリを使用してみてください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, ...;

ただし、ユーザー変数を含む式の評価順序は定義されていません。

于 2014-11-05T11:39:19.600 に答える
0

これを解決する簡単な方法は、PHP ドキュメントで変数 mysql を設定することです。このように: $var = mysql_query("SET @nun := 0;");

于 2015-12-15T23:21:01.997 に答える