Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.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_Group By_Sql Order By - Fatal编程技术网

MySQL排序依据在分组依据之前

MySQL排序依据在分组依据之前,mysql,group-by,sql-order-by,Mysql,Group By,Sql Order By,这里有很多类似的问题,但我认为没有人能充分回答这个问题 我将继续从当前最流行的,并使用他们的例子,如果这是好的 本例中的任务是获取数据库中每个作者的最新文章 示例查询产生不可用的结果,因为它并不总是返回的最新帖子 SELECT wp_posts.* FROM wp_posts WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post' GROUP BY wp_posts.post_author

这里有很多类似的问题,但我认为没有人能充分回答这个问题

我将继续从当前最流行的,并使用他们的例子,如果这是好的

本例中的任务是获取数据库中每个作者的最新文章

示例查询产生不可用的结果,因为它并不总是返回的最新帖子

SELECT wp_posts.* FROM wp_posts
    WHERE wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
    GROUP BY wp_posts.post_author           
    ORDER BY wp_posts.post_date DESC
目前公认的答案是

SELECT
    wp_posts.*
FROM wp_posts
WHERE
    wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author
HAVING wp_posts.post_date = MAX(wp_posts.post_date) <- ONLY THE LAST POST FOR EACH AUTHOR
ORDER BY wp_posts.post_date DESC
我的问题很简单: 在分组之前,是否仍然可以不借助子查询对行进行排序?


编辑:这个问题是另一个问题的延续,我的具体情况略有不同。您可以(也应该)假设还有一个wp_posts.id,它是该特定帖子的唯一标识符。

首先,不要在select中使用*,会影响它们的性能并妨碍使用group by和order by。 请尝试以下查询:

SELECT wp_posts.post_author, wp_posts.post_date as pdate FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author           
ORDER BY pdate DESC

如果不按ORDER BY指定表,而只指定别名,则它们将对select的结果进行排序。

否。在分组之前对记录进行排序是没有意义的,因为分组将改变结果集。子查询方式是首选方式。如果速度太慢,您必须更改表设计,例如,将每个作者最后一篇文章的id存储在一个单独的表中,或者引入一个布尔列,指示每个作者的最后一篇文章。

在子查询中使用
ORDER by
不是解决此问题的最佳方法

按作者获取
max(post\u-date)
的最佳解决方案是使用子查询返回max-date,然后在
post\u-author
和max-date上将其连接到表中

解决办法应该是:

SELECT p1.* 
FROM wp_posts p1
INNER JOIN
(
    SELECT max(post_date) MaxPostDate, post_author
    FROM wp_posts
    WHERE post_status='publish'
       AND post_type='post'
    GROUP BY post_author
) p2
  ON p1.post_author = p2.post_author
  AND p1.post_date = p2.MaxPostDate
WHERE p1.post_status='publish'
  AND p1.post_type='post'
order by p1.post_date desc
如果您有以下示例数据:

CREATE TABLE wp_posts
    (`id` int, `title` varchar(6), `post_date` datetime, `post_author` varchar(3))
;

INSERT INTO wp_posts
    (`id`, `title`, `post_date`, `post_author`)
VALUES
    (1, 'Title1', '2013-01-01 00:00:00', 'Jim'),
    (2, 'Title2', '2013-02-01 00:00:00', 'Jim')
;
子查询将返回以下内容的最长日期和作者:

MaxPostDate | Author
2/1/2013    | Jim
然后,由于您要将其连接回表中,因此在这两个值上,您将返回该帖子的完整详细信息

展开我关于使用子查询准确返回此数据的评论

MySQL不会强制您按
列表中包含的每一列对
进行分组。因此,如果您仅按一列进行分组,但总共返回10列,则不能保证属于返回的
post_作者的其他列值。如果列不在
groupby
MySQL中,则选择应返回的值

SELECT wp_posts.* FROM wp_posts
    WHERE wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
    GROUP BY wp_posts.post_author           
    ORDER BY wp_posts.post_date DESC
将子查询与聚合函数一起使用将确保每次返回正确的作者和帖子


顺便说一句,MySQL允许您在子查询中使用
ORDER BY
,并允许您将
GROUP BY
应用于
SELECT
列表中的并非每一列,但在包括SQL Server在内的其他数据库中不允许此行为。

尝试此操作只需从每位作者那里获取最新发布日期的列表。就这样

SELECT wp_posts.* FROM wp_posts WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post' AND wp_posts.post_date IN(SELECT MAX(wp_posts.post_date) FROM wp_posts GROUP BY wp_posts.post_author) 

您的解决方案使用了一个允许按某些字段分组的子句(在本例中,只需
post\u author
):

并选择非聚集列:

SELECT wp_posts.*
未在group by子句中列出的,或未在聚合函数中使用的(最小值、最大值、计数等)

正确使用GROUP BY子句的扩展名

当非聚合列的所有值对于每一行都相等时,这非常有用

例如,假设您有一个表
GardensFlowers
name
花园,
flower
生长在花园中):

你想把花园里所有的花都提取出来,在那里有很多花。然后您必须使用子查询,例如,您可以使用:

SELECT GardensFlowers.*
FROM   GardensFlowers
WHERE  name IN (SELECT   name
                FROM     GardensFlowers
                GROUP BY name
                HAVING   COUNT(DISTINCT flower)>1);
SELECT   GardensFlowers.*
FROM     GardensFlowers
GROUP BY name
HAVING   COUNT(DISTINCT flower)=1;
如果您需要提取花园中唯一的花,您可以将HAVING条件更改为HAVING COUNT(DISTINCT flower)=1,但MySql也允许您使用此选项:

SELECT GardensFlowers.*
FROM   GardensFlowers
WHERE  name IN (SELECT   name
                FROM     GardensFlowers
                GROUP BY name
                HAVING   COUNT(DISTINCT flower)>1);
SELECT   GardensFlowers.*
FROM     GardensFlowers
GROUP BY name
HAVING   COUNT(DISTINCT flower)=1;
没有子查询,不是标准SQL,但更简单

对GROUP BY子句的扩展使用不正确

但是,如果选择每行不相等的非聚合列,会发生什么情况?MySql为该列选择的值是什么

看起来MySql总是首先选择它遇到的

为了确保它遇到的第一个值正是您想要的值,您需要将
groupby
应用于有序查询,因此需要使用子查询。否则你做不到

假设MySql总是选择它遇到的第一行,那么您将正确地在GROUP BY之前对行进行排序。但不幸的是,如果您仔细阅读文档,您会发现这个假设是不正确的

当选择不总是相同的非聚合列时,MySql可以自由选择任何值,因此它实际显示的结果值是不确定的

我发现这种获取非聚合列的第一个值的技巧被大量使用,而且通常/几乎总是有效的,有时我也会使用它(风险由我自己承担)。但由于没有记录,你不能依赖这种行为

这个链接(感谢ypercube!)显示了一种情况,同一个查询在MySql和MariaDB之间返回不同的结果,可能是因为不同的优化引擎

所以,如果这个把戏奏效,那只是运气的问题

在我看来,这是个错误:

HAVING wp_posts.post_date = MAX(wp_posts.post_date)
wp\u posts。post\u date
是一个非聚合列,其值将不确定,但可能是遇到的第一个
post\u date
。但由于GROUP BY技巧应用于无序表,因此无法确定遇到的第一个
post_日期

它可能返回的帖子是单个用户的唯一帖子
SELECT wp_posts.*
FROM   wp_posts
WHERE  id IN (
  SELECT max(id)
  FROM wp_posts
  WHERE (post_author, post_date) = (
    SELECT   post_author, max(post_date)
    FROM     wp_posts
    WHERE    wp_posts.post_status='publish'
             AND wp_posts.post_type='post'
    GROUP BY post_author
  ) AND wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
  GROUP BY post_author
)
SELECT x.*
  FROM my_table x
  JOIN (SELECT grouping_criteria,MAX(ranking_criterion) max_n FROM my_table GROUP BY grouping_criteria) y
    ON y.grouping_criteria = x.grouping_criteria
   AND y.max_n = x.ranking_criterion;
SELECT x.*
  FROM my_table x
  LEFT
  JOIN my_table y
    ON y.joining_criteria = x.joining_criteria
   AND y.ranking_criteria < x.ranking_criteria
 WHERE y.some_non_null_column IS NULL;  
...
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC
SELECT wp_posts.*
FROM wp_posts
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC
ORDER BY wp_posts.post_date DESC;
SELECT * 
FROM wp_posts
INNER JOIN
(
  SELECT max(post_date) post_date, post_author
  FROM wp_posts
  WHERE post_status='publish' AND post_type='post'
  GROUP BY post_author
  ORDER BY post_date DESC
  -- LIMIT GOES HERE
) p2 USING (post_author, post_date)
WHERE post_status='publish' AND post_type='post';
SELECT *
FROM (
  SELECT post_id
  FROM wp_posts
  WHERE post_status='publish' AND post_type='post'
  GROUP BY post_author DESC
  ORDER BY post_date DESC
  -- LIMIT GOES HERE
) as ids
JOIN wp_posts USING (post_id);
SELECT wp_posts.*
FROM   wp_posts
WHERE  wp_posts.post_status = 'publish'
       AND wp_posts.post_type = 'post'
GROUP  BY wp_posts.post_author
ORDER  BY wp_posts.post_date DESC; 
SELECT p.post_status,
       p.post_type,
       Max(p.post_date),
       p.post_author
FROM   wp_posts P
WHERE  p.post_status = "publish"
       AND p.post_type = "post"
GROUP  BY p.post_author
ORDER  BY p.post_date; 
    select max(taskhistory.id) as id from taskhistory
            group by taskhistory.taskid
            order by taskhistory.datum desc