Dev*_*vin 47 mysql join group-by max
好的,这是我的查询:
SELECT
  video_category,
  video_url,
  video_date,
  video_title,
  short_description,
  MAX(video_id) 
FROM
  videos
GROUP BY
  video_category
当它拉取数据时,我得到video_id的正确行,但它为其他类别拉出第一行.因此,当我获得类别1的video_id的最大结果时,我得到最大ID,但是表格中的第一行是url,date,title和description.
如何让它拉出与最大ID结果相对应的其他列?
编辑:已修复.
SELECT
    *
FROM
    videos
WHERE
    video_id IN
    (
        SELECT
            DISTINCT
            MAX(video_id)
        FROM
            videos
        GROUP BY
            video_category
    ) 
ORDER BY
    video_category ASC
Dal*_*len 39
我会尝试这样的事情:
SELECT
   s.video_id
   ,s.video_category
   ,s.video_url
   ,s.video_date
   ,s.video_title
   ,short_description
FROM videos s
   JOIN (SELECT MAX(video_id) AS id FROM videos GROUP BY video_category) max
      ON s.video_id = max.id
这比你自己的解决方案快得多
Ste*_*ley 30
我最近发布了一种新技术来处理 MySQL 中的此类问题。
标量减少
Scalar-Aggregate Reduction 是迄今为止实现这一目标的最高性能方法和最简单的方法(用数据库引擎术语),因为它不需要连接、子查询和 CTE。
对于您的查询,它看起来像这样:
SELECT
  video_category,
  MAX(video_id) AS video_id,
  SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), video_url)), 12) AS video_url,
  SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), video_date)), 12) AS video_date,
  SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), video_title)), 12) AS video_title,
  SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), short_description)), 12) AS short_description
FROM
  videos
GROUP BY
  video_category
标量函数和聚合函数的组合执行以下操作:
如果要检索 CHAR 以外类型的值,则可能需要对输出执行额外的 CAST,例如,如果您想video_date成为 DATETIME:
CAST(SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), video_date)), 12) AS DATETIME)
与自联接方法相比,此方法的另一个好处是您可以组合其他聚合数据(不仅仅是最新值),甚至可以组合同一查询中的第一个和最后一个项目,例如
SELECT
    -- Overall totals
    video_category,
    COUNT(1) AS videos_in_category,
    DATEDIFF(MAX(video_date), MIN(video_date)) AS timespan,
    
    -- Last video details
    MAX(video_id) AS last_video_id,
    SUBSTRING(MAX(CONCAT(LPAD(video_id, 11, '0'), video_url)), 12) AS last_video_url,
    ...
    
    -- First video details
    MIN(video_id) AS first_video_id,
    SUBSTRING(MIN(CONCAT(LPAD(video_id, 11, '0'), video_url)), 12) AS first_video_url,
    ...
    
    -- And so on
有关解释此方法与其他旧方法的优点的更多详细信息,我的完整博客文章在这里:https : //www.stevenmoseley.com/blog/tech/high-performance-sql-correlated-scalar-aggregate-reduction-queries
一个稍微“质朴”的解决方案,但应该完成相同的工作:
SELECT
  video_category,
  video_url,
  video_date,
  video_title,
  short_description,
  video_id
FROM
  videos
ORDER BY video_id DESC
LIMIT 1;
换句话说,只需生成一个包含所需所有列的表,对其进行排序,使最大值位于顶部,然后将其删除,以便只返回一行。
这是一个更通用的解决方案(处理重复项)
CREATE TABLE test(
  i INTEGER,
  c INTEGER,
  v INTEGER
);
insert into test(i, c, v)
values
(3, 1, 1),
(3, 2, 2),
(3, 3, 3),
(4, 2, 4),
(4, 3, 5),
(4, 4, 6),
(5, 3, 7),
(5, 4, 8),
(5, 5, 9),
(6, 4, 10),
(6, 5, 11),
(6, 6, 12);
SELECT t.c, t.v
FROM test t
JOIN (SELECT test.c, max(i) as mi FROM test GROUP BY c) j ON
  t.i = j.mi AND
  t.c  = j.c
ORDER BY c;
| 归档时间: | 
 | 
| 查看次数: | 58188 次 | 
| 最近记录: |