3

group_concat() と内部結合の制限について話している他のスレッドを詳しく調べましたが、答えが見つからなかったので、先に進んで質問します。

既存のフォト コミュニティ サイトを開発しています。特定の日 (今日) が誕生日のメンバーを取得し、各メンバーの最も評価の高い 5 枚の写真を取得したいと考えています。しかし、「最もお気に入りの」誕生日メンバー (つまり、お気に入りの数が最も多い) 10 人だけが必要です。ここに私が持っているものがあります:

SELECT users.user_id, users.user_name, 
       GROUP_CONCAT(CONVERT(photos.photo_id,char(32)) 
                    ORDER BY photos.average_rate) as photo_ids
FROM users 
INNER JOIN photos ON photos.user_id=users.user_id
WHERE users.day_of_birth = DATE_FORMAT('2012-04-17', '%m-%d') 
  AND users.photo_count>0 
GROUP BY users.user_id
ORDER BY users.favorite_count DESC, users.photo_count DESC LIMIT 0,10

sの量を 5 に制限できないことを除いて、これは私が望むことをphoto_id行います。出力は JSON としてアプリに送信され、一部のメンバーはすでに 20,000 枚以上の写真をアップロードしているため、許容できないほど長くなります。出力文字列。私にとってうまくいくと思われる唯一の「解決策」は、サーバー変数group_concat_max_lenを少なくとも5つのIDを保持する適切なものに設定することですが、これは非常にハックで信頼性がありません. photo_id単一のクエリでユーザーごとに正確に 5 秒を返す方法はありますか? または、PHP でループを実行する必要がありますか?

コンマ区切り値の photo_ids は必ずしも必要ではありません。group_concat() アプローチを完全に捨てて、それがより実現可能であれば内部結合を行うこともできます。しかし、それでも結果を 5 に制限する方法を知りません。

4

2 に答える 2

1

これらの高度なものは、私がMySQLを好きになる理由です:)

SELECT user_id, user_name, 
    GROUP_CONCAT(CONVERT(photo_id, char(32)) ORDER BY photos.average_rate) as photo_ids
FROM (  SELECT user_id, user_name, photo_id, favorite_count, photo_count, 
            (case when @user_id = user_id then @rownum := @rownum + 1 else CONCAT(@rownum := 1, @user_id := user_id) end) AS dummy_val
        FROM (  SELECT users.user_id, users.user_name, users.favorite_count, users.photo_count, photos.photo_id
                FROM users 
                INNER JOIN photos
                ON photos.user_id=users.user_id
                WHERE users.day_of_birth = DATE_FORMAT('2012-04-17', '%m-%d') 
                    AND users.photo_count > 0 
                ORDER BY users.id ASC, photos.average_rate ASC
             ) AS h, 
             (  @rownum := NULL, 
                @user_id := NULL
             ) AS vars
        HAVING rownum <= 5) AS h2
GROUP BY user_id
ORDER BY favorite_count DESC, photo_count DESC LIMIT 0, 10

基本的に、すべての行を取得し、計算された行数が 6 以上の写真をすべて破棄します。

于 2012-04-18T11:35:34.143 に答える
0
SELECT u.user_id
     , u.user_name 
     , GROUP_CONCAT(p.photo_id ORDER BY p.average_rate) AS photo_ids
FROM 
    ( SELECT user_id
           , user_name
           , favorite_count 
           , photo_count
      FROM users
      WHERE day_of_birth = DATE_FORMAT('2012-04-17', '%m-%d') 
        AND photo_count > 0 
      ORDER BY favorite_count DESC
             , photo_count DESC 
      LIMIT 10
    ) AS u
  INNER JOIN
    photos AS p
      ON  p.user_id = u10.user_id
      AND p.average_rate >= 
          ( SELECT pp.average_rate 
            FROM photos AS pp
            WHERE pp.user_id = u10.user_id
            ORDER BY pp.average_rate DESC
            LIMIT 1 OFFSET 4
          ) 
GROUP BY u.user_id
ORDER BY u.favorite_count DESC
       , u.photo_count DESC 
于 2012-04-18T11:16:05.747 に答える