1

当我在子查询中使用没有 LIMIT 的以下查询时

SELECT   `c`.*, 
         GROUP_CONCAT(g.photo SEPARATOR "|") AS `photos_list` 
  FROM   `contests` AS `c` 
              LEFT JOIN 
                  (
                      SELECT   `gallery`.`contest_id`, 
                               `gallery`.`photo` 
                        FROM   `gallery`
                   ) AS `g` ON c.id = g.contest_id 
GROUP BY `c`.`id`

一切正常

id   title    photos_list 

1    title1   50026c35632eb.jpg
2    title2   50026ac53567f.jpg|50026ac5ec82e.jpg|500e71557270f....

当我添加 LIMIT 时,我只在一行中得到“photos_list”。以下查询

SELECT   `c`.*, 
         GROUP_CONCAT(g.photo SEPARATOR "|") AS `photos_list` 
  FROM   `contests` AS `c` 
              LEFT JOIN 
                  (
                      SELECT   `gallery`.`contest_id`, 
                               `gallery`.`photo` 
                        FROM   `gallery`
                       LIMIT    0, 2
                   ) AS `g` ON c.id = g.contest_id 
GROUP BY `c`.`id`

将返回

id  title   photos_list 

1   title1  NULL
2   title2  50026ac46ea05.jpg|50026ac53567f.jpg

id = 1的项目必须包含photos_list,但事实并非如此。值得注意的是LIMIT确实适用于id = 2的项目。

我应该怎么做才能得到正确的结果?

4

5 回答 5

2
SELECT   `c`.*, 
     GROUP_CONCAT(g.photo SEPARATOR "|") AS `photos_list` 
FROM   `contests` AS `c` 
          LEFT JOIN 
              (
                  SELECT   `gallery`.`contest_id`, 
                           `gallery`.`photo` 
                    FROM   `gallery`
               ) AS `g` ON c.id = g.contest_id 
GROUP BY `c`.`id`

将 GROUP_CONCAT 更改为:

SUBSTRING_INDEX(GROUP_CONCAT(g.photo SEPARATOR "|"),'|',2) AS `photos_list` 
于 2012-07-24T13:33:25.970 回答
2

photo_date > gsub.photo_date您可以使用时间戳(例如 AND )或更复杂的标准来做类似的事情。唯一需要注意的是,如果有几行都符合条件(例如,几张照片具有相同的时间戳),则它们都将被包括在内。这就是我选择 的原因photo_id,这可能是独一无二的。

将其插入到您的原始查询中,如下所示:

SELECT c.id, c.title,
       GROUP_CONCAT(g.photo SEPARATOR "|") AS photos_list
FROM   contests AS c
  LEFT JOIN (
    //put query from above here
  ) AS g 
ON c.id = g.contest_id  GROUP BY c.id
于 2012-12-10T16:03:04.930 回答
1

这也有效。但是,如果没有围绕它包装另一个 SELECT 子句,如果没有比赛的照片,比赛将不会出现。

SELECT c.*, GROUP_CONCAT(g.photo SEPARATOR "|") AS photo_list
FROM 
  contests c 
LEFT JOIN
  (SELECT *, @num:= if(@contest = contest_id, @num + 1,1) as row_num,
             @contest := contest_id as c_id
   FROM gallery
   ORDER BY contest_id) AS g
ON c.id = g.contest_id
WHERE g.row_num <= 2
GROUP BY c.id, c.title
于 2012-07-24T13:04:28.220 回答
1

SELECT c.*, ((
  SELECT GROUP_CONCAT(temp.photo SEPARATOR "|")
  FROM (SELECT photo FROM gallery g WHERE c.id = g.contest_id LIMIT 2) temp
)) AS photo_list
FROM contests c

抱歉回答不正确。我并不是说以下解决方案是最佳解决方案,但至少它有效。顺便说一句,在这个新解决方案中,我假设您gallery的表有一个名为id.

SELECT c.*, GROUP_CONCAT(g.photo SEPARATOR "|") AS photos_list
FROM contests AS c
LEFT JOIN (
    SELECT
        g_0.*
    FROM (
        SELECT
            g_1.*
            , ((SELECT COUNT(*) FROM gallery g_2 WHERE g_2.contest_id = g_1.contest_id AND g_2.id <= g_1.id)) AS i
        FROM gallery g_1
    ) g_0
    WHERE
        g_0.i <= 2
) g ON (c.id = g.contest_id)
GROUP BY c.id
于 2012-07-24T13:59:56.257 回答
1

您如何决定应返回特定比赛的可能照片集中的哪 2 张?它是一个随机的东西吗?还是最近的 2 张照片,或 2 张评分最高的照片,或其他一些标准?一旦您可以设置选择照片的条件,剩下的就很简单了。此查询将为您提供每个竞赛 ID 具有最高 photo_id 的 2 张照片:

     SELECT contest_id, photo, photo_id
       FROM gallery gsub
       WHERE (
         SELECT COUNT(*) FROM gallery 
           WHERE contest_id=gsub.contest_id //for each category
           AND photo_id > gsub.photo_id 
       ) < 2 //if number of photo_ids > than this photo_id < 2, keep this photo
       ORDER BY contest_id

AND photo_date > gsub.photo_date您可以使用时间戳(例如)或更复杂的标准来做类似的事情。唯一需要注意的是,如果有几行都符合条件(例如,几张照片具有相同的时间戳),则它们都将被包括在内。这就是我选择 photo_id 的原因,它可能是独一无二的。

将其插入到您的原始查询中,如下所示:

SELECT c.id, c.title,
           GROUP_CONCAT(g.photo SEPARATOR "|") AS photos_list
    FROM   contests AS c
      LEFT JOIN (
        //put query from above here
      ) AS g 
    ON c.id = g.contest_id  GROUP BY c.id 
于 2012-07-25T12:02:46.590 回答