Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 订单依据和分组依据中的限制_Mysql_Sql_Group By_Limit_Greatest N Per Group - Fatal编程技术网

Mysql 订单依据和分组依据中的限制

Mysql 订单依据和分组依据中的限制,mysql,sql,group-by,limit,greatest-n-per-group,Mysql,Sql,Group By,Limit,Greatest N Per Group,我试图得到一组记录的子集,我已经看到了很多疯狂的解决方案,但是它们看起来太复杂了,有没有更有效的方法呢 SELECT user_id, GROUP_CONCAT(item_id ORDER BY `timestamp`) AS items FROM wb_user_book_current_item GROUP BY user_id 这将返回所有用户的所有当前项目,到目前为止还可以。但我只想要最近的十件。将ORDER BY添加到GROUP_CONCAT会有所帮助,但它仍然无法提供最后十条记录

我试图得到一组记录的子集,我已经看到了很多疯狂的解决方案,但是它们看起来太复杂了,有没有更有效的方法呢

SELECT user_id, GROUP_CONCAT(item_id ORDER BY `timestamp`) AS items 
FROM wb_user_book_current_item GROUP BY user_id
这将返回所有用户的所有当前项目,到目前为止还可以。但我只想要最近的十件。将ORDER BY添加到GROUP_CONCAT会有所帮助,但它仍然无法提供最后十条记录

编辑

如果我这样做并硬编码用户id,那么我就可以得到我想要的一个用户的结果,问题是组合它,这样我就不需要硬编码用户id,例如,可以只得到所有用户的最后十项

SELECT GROUP_CONCAT(cp2.item_id) AS items 
FROM (SELECT cp.user_id, cp.item_id 
      FROM wb_user_book_current_item cp 
      WHERE cp.user_id=1 ORDER BY cp.`timestamp` 
      LIMIT 10) AS cp2 
GROUP BY cp2.user_id

更新:我没有注意到组_CONCAT,因此您将不得不在confunction with LIMIT中使用子查询

使用限制

SELECT column_name(s)
FROM table_name
LIMIT number

这是一个困难的问题,但如何处理这个问题:

SELECT user_id, GROUP_CONCAT(item_id ORDER BY `timestamp`) AS items
FROM wb_user_book_current_item T
WHERE NOT EXISTS
(
    SELECT 1
    FROM wb_user_book_current_item T2
    WHERE T2.user_id = T.user_id
    ORDER BY T2.`timestamp` DESC
    LIMIT 10,1
) 
OR T.`timestamp` > (
    SELECT T2.`timestamp`
    FROM wb_user_book_current_item T2
    WHERE T2.user_id = T.user_id
    ORDER BY T2.`timestamp` DESC
    LIMIT 10,1
)
GROUP BY user_id
当然,这假设同一用户不会有两行具有相同的时间戳

如果时间戳字段始终为正整数,则还可以替换NOT EXISTS…或使用合并:

原始答案,但显然MySQL不理解如何正确执行,并抱怨subselect返回多行。当然,我们需要多行;这是一个集体聚会。Grr

不幸的是,我认为没有真正的方法来使用子查询:

SELECT T.user_id, 
    GROUP_CONCAT((SELECT T2.item_id 
                  FROM wb_user_book_current_item T2 
                  WHERE T2.user_id = T.user_id 
                  ORDER BY T2.`timestamp` 
                  LIMIT 10)) AS items 
FROM wb_user_book_current_item T
GROUP BY user_id
否则,在其他任何地方添加限制将限制组的数量,或限制表上的总记录集,而不是组-这两者都不是您试图实现的目标。

尝试以下方法:

SELECT 
  user_id, 
  GROUP_CONCAT(item_id ORDER BY `timestamp`) AS items 
FROM wb_user_book_current_item 
GROUP BY user_id
LIMIT 0, 10

所以我在这里找到了一个很好的解决方案,效果很好

它是这样的,把所有这些放在一起:

SET @num := 0, @user_id := '';

SELECT cp2.user_id, CONCAT(cp2.item_id) AS items
FROM (
   SELECT cp.user_id, cp.item_id,
   @num := IF(@user_id = cp.user_id, @num + 1, 1) AS row_number,
   @user_id := cp.user_id AS dummy
   FROM wb_user_curent_item AS cp
   ORDER BY cp.user_id ASC, cp.`timestamp` DESC
) AS cp2 WHERE cp2.row_number <= 10
GROUP BY cp2.user_id
所以基本上它只是使用num增量来限制记录,而不是使用limit


关于用户id、时间戳、项目id的索引将有助于提高效率。

也许您必须在末尾设置限制0,10?同意,我没有看到组concat-op必须与限制一起使用子查询,因此SELECT会返回多行,但是CONCAT发生在这之后,所以我得到了一个多行错误,因为它试图将所有内容都放在一个记录中。仍在努力以其他方式将其浓缩,但似乎还没有找到方法。这将限制最终结果的数量,而不是每个用户的项目结果。
SET @num := 0, @user_id := '';

SELECT cp2.user_id, CONCAT(cp2.item_id) AS items
FROM (
   SELECT cp.user_id, cp.item_id,
   @num := IF(@user_id = cp.user_id, @num + 1, 1) AS row_number,
   @user_id := cp.user_id AS dummy
   FROM wb_user_curent_item AS cp
   ORDER BY cp.user_id ASC, cp.`timestamp` DESC
) AS cp2 WHERE cp2.row_number <= 10
GROUP BY cp2.user_id
SELECT 
    i.user_id,
    GROUP_CONCAT(i.item_id ORDER BY i.timestamp) AS items 
FROM 
    ( SELECT DISTINCT user_id
      FROM wb_user_book_current_item 
    ) AS du
  JOIN
    wb_user_book_current_item AS i
      ON  i.user_id = du.user_id
      AND i.timestamp <= COALESCE(
          ( SELECT i2.item_id 
            FROM wb_user_book_current_item AS i2
            WHERE i2.user_id = du.user_id
            ORDER BY i2.timestamp ASC 
              LIMIT 1 OFFSET 9
          )
          , '2038-01-19 03:14:07')
GROUP BY
    i.user_id ;