5

個別のレコードごとに複数の行を選択する必要があります。私はMySQLを使用していますが、SQLServer2008の個別のIDごとに最初のn個のレコードを選択してください。

この場合、21のクエリを実行することで目的を達成できます。1つは一般で、20はサブレコードを取得します。つまり、次のようになります。

SELECT DISTINCT `user_id`
FROM `posts`
WHERE `deleted` = '0'
ORDER BY `user_id` ASC
LIMIT 20

...必要なすべての行を選択してから、

SELECT *
FROM `posts`
WHERE `deleted` = '0'
AND `user_id` = ?
ORDER BY `id` DESC
LIMIT 5

...最初のクエリで選択された各行ごとにループします。

基本的に、私は各ユーザーの5つの投稿を取得する必要があります。これを1つのクエリで実行する必要があります。セットアップはほんの一例です。posts私はこれを作成したので、うまくいけば、必要なものを理解しやすくなります。

私は次のクエリから始めました:

SELECT * 
FROM `posts` 
WHERE `user_id` 
IN (
    SELECT DISTINCT `user_id` 
    FROM `posts` 
    ORDER BY `user_id` DESC 
    LIMIT 4
) 
LIMIT 5

しかし、#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'エラーが発生します。

だから私はここでJOIN提案されているようなアイデアを試しました:

SELECT  posts.id,
        posts.user_id,
        NULL
FROM    (
        SELECT  posts.user_id
        FROM    posts
        WHERE   posts.deleted = 0
        LIMIT 20
        ) q
JOIN    posts
ON      posts.user_id = q.user_id

ここで提案されているように、いくつかのネストされたクエリも試しました:

SELECT *
FROM posts 
WHERE user_id IN (
      SELECT * FROM (
            SELECT user_id 
            FROM posts 
            LIMIT 20
      ) 
      as t);

そして、インターネット上にある他のソリューション。ただし、これらは機能しないか、データベースから最初のN行を選択するだけです(何らかの理由で条件や結合に関係なく)。試してみましたがLEFT JOINRIGHT JOINそれでもINNER JOIN成功しませんでした。

助けてください。

更新テーブルのサイズが約5GBであることを忘れました。

UPDATE サブサブクエリを試しました:

SELECT * 
FROM `posts` 
WHERE
  `user_id` IN ( SELECT `user_id` FROM (
     SELECT DISTINCT `user_id` 
     FROM `posts` 
    ORDER BY `user_id` DESC 
    LIMIT 4 ) limit_users
  ) 
LIMIT 5

上記と同じように、次を返します。

+----+---------+------+
| id | user_id | post |
+----+---------+------+
|  1 |       1 |    a |
+----+---------+------+
|  2 |       1 |    b |
+----+---------+------+
|  3 |       1 |    c |
+----+---------+------+
| .. |      .. |   .. |

LIMITつまり、同じユーザーの5行(アウターが設定されている行)です。奇妙なことに、サブクエリとサブサブクエリを単独で実行すると、次のようになります。

    SELECT `user_id` FROM (
     SELECT DISTINCT `user_id` 
     FROM `posts` 
    ORDER BY `user_id` DESC 
    LIMIT 4 ) limit_users

私は4つの異なる値を取得します:

+---------+
| user_id |
+---------+
|       1 |
+---------+
|       2 |
+---------+
|       3 |
+---------+
|       4 |
+---------+
4

1 に答える 1

1

変数を使用して、順序付きクエリで 2 つの異なるカウントを行う必要があります。1 つは各ユーザーの投稿数、もう 1 つはユーザーです。

SELECT posts_counts.*
FROM (
  SELECT
    posts.*,
    @post_count:=case when @prec_user_id=user_id then @post_count+1 else 1 end as pc,
    case when @prec_user_id<>user_id then @user_count:=@user_count+1 else @user_count end as uc,
    @prec_user_id:=user_id
  FROM
    posts,
    (select @prec_user_id:=0, @user_count:=0, @post_count:=0) counts
  ORDER BY
    posts.user_id ) posts_counts
WHERE pc<5 and uc<4

編集:このクエリを試すことも検討してください:

SELECT * 
FROM `posts` 
WHERE
  `user_id` IN ( SELECT user_id FROM (
     SELECT DISTINCT `user_id` 
     FROM `posts` 
    ORDER BY `user_id` DESC 
    LIMIT 4 ) limit_users
  ) 
LIMIT 5

(これは、選択した各ユーザーからのすべての投稿から5つの投稿を選択するだけなので、まだ必要なものではありませんが、サブサブクエリでLIMITを使用するトリックを使用しています)

EDIT2:次のクエリは、20 人のユーザーごとに 5 つの投稿を制限します。

select posts_limited.*
from (
  select
    posts.*,
    @row:=if(@last_user=posts.user_id, @row+1, 1) as row,
   @last_user:=posts.user_id
  from
    posts inner join
    (select user_id from
      (select distinct user_id
       from posts
       order by user_id desc
       LIMIT 20) limit_users
    ) limit_users
    on posts.user_id = limit_users.user_id,
    (select @last_user:=0, @row:=0) r
  ) posts_limited
  where row<=5
于 2012-12-23T20:48:19.493 に答える