Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.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_Aggregate Functions - Fatal编程技术网

MySQL查询-使用聚合和分组方式生成单独的结果

MySQL查询-使用聚合和分组方式生成单独的结果,mysql,group-by,aggregate-functions,Mysql,Group By,Aggregate Functions,我有一个表,其中一个或多个具有相同“id”值的条目可以插入我们的日志/事实表(包含超过1亿条记录) 以设定的频率,将一条新记录插入该表,并为“已创建”列和“查看百分比”(已观看视频的百分比)列插入一个新值。 对于两个不同的查询,我想返回: 期望结果1: 使用此查询,我无法在执行聚合函数时筛选出必要的记录。。。取而代之的是所有行的平均值,结果值为31.307 SELECT archive_asset_id, asset_title, COUNT(DISTINCT id * 1000000 + a

我有一个表,其中一个或多个具有相同“id”值的条目可以插入我们的日志/事实表(包含超过1亿条记录)
以设定的频率,将一条新记录插入该表,并为“已创建”列和“查看百分比”(已观看视频的百分比)列插入一个新值。
对于两个不同的查询,我想返回:

期望结果1:

使用此查询,我无法在执行聚合函数时筛选出必要的记录。。。取而代之的是所有行的平均值,结果值为31.307

SELECT archive_asset_id, asset_title, COUNT(DISTINCT id * 1000000 + archive_asset_id) AS count_asset, AVG(view_percent) AS avg_view, FROM_UNIXTIME(created, '%Y-%m-%d') AS time_day
FROM log_embed_video 
WHERE archive_asset_id = 83386 
AND created >= 1281312000
AND created < 1281484800
GROUP BY time_day
ORDER BY time_day;
这是我用于结果2的查询,但不是我想要的。。。group by log_embed_video.id生成4个结果。。。这是给定查询的预期结果,但不是所需的输出

SELECT id, FROM_UNIXTIME(created, '%Y-%m-%d') AS time_day, archive_asset_id, asset_title, COUNT(DISTINCT id * 1000000 + archive_asset_id) AS 'count_asset', MAX(view_percent) as 'max_view_percent'
FROM log_embed_video 
WHERE archive_asset_id = 83386 
AND created >= 1281312000
AND created < 1281484800
GROUP BY time_day, id


表格和原始数据:

CREATE TABLE `log_embed_video` (
  `id` int(11) NOT NULL,
  `archive_asset_id` int(11) NOT NULL,
  `asset_title` varchar(255) NOT NULL,
    `view_percent` float NOT NULL,
  `created` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO `log_embed_video` VALUES 
(43326898, 83386, 'Oliver James', 0, 1281327306),
(43326898, 83386, 'Oliver James', 13, 1281327327),
(43432090, 83386, 'Oliver James', 0, 1281371423),
(43432090, 83386, 'Oliver James', 17, 1281371445),
(43432092, 83386, 'Oliver James', 0, 1281371424),
(43432092, 83386, 'Oliver James', 17, 1281371446),
(43470093, 83386, 'Oliver James', 0, 1281380789),
(43470093, 83386, 'Oliver James', 17, 1281380810),
(43470093, 83386, 'Oliver James', 35, 1281380830),
(43470093, 83386, 'Oliver James', 52, 1281380850),
(43470093, 83386, 'Oliver James', 69, 1281380871),
(43470093, 83386, 'Oliver James', 87, 1281380891),
(43470093, 83386, 'Oliver James', 100, 1281380906);

检查这是否会让您更清楚

SELECT archive_asset_id, AVG(actual_percent) 
FROM (SELECT id, archive_asset_id, asset_title, 
             MAX(view_percent) as actual_percent 
      FROM log_embed_video GROUP by id) T 
GROUP BY archive_asset_id;
它返回:

+------------------+---------------------+
| archive_asset_id | AVG(actual_percent) |
+------------------+---------------------+
|            83386 |               36.75 | 
+------------------+---------------------+
一些注释

  • 这在100米记录上表现不佳
  • 另外,您可能希望规范化数据以提高性能(在本例中就是这样;基本上,将实际的最终行移动到它们自己的表中对我来说更有意义)
  • 这个表达式
    COUNT(DISTINCT id*1000000+archive\u asset\u id)
    吸引了我的眼球,因为它有些奇怪;你确定你的意思不是简单的
    COUNT(*)
    COUNT(id)
编辑:

第二个

SELECT archive_asset_id, actual_percent, count(*) 
FROM (SELECT id, archive_asset_id, asset_title,               
             MAX(view_percent) as actual_percent        
      FROM log_embed_video GROUP by id) T  
GROUP BY archive_asset_id, actual_percent;

+------------------+----------------+----------+
| archive_asset_id | actual_percent | count(*) |
+------------------+----------------+----------+
|            83386 |             13 |        1 | 
|            83386 |             17 |        2 | 
|            83386 |            100 |        1 | 
+------------------+----------------+----------+

唯一id的每个id行的所有最大百分比:

SELECT a.* 
FROM log_embed_video a 
LEFT JOIN log_embed_video b
ON b.id = a.id
AND b.view_percent > a.view_percent
WHERE b.id IS NULL
-- possibly limit on date for  more performance.
就性能而言,这更好:

SELECT * FROM (
    SELECT id, archive_asset_id, asset_title, view_percent, created,
        @rn := IF(id != @old_id,1,@rn + 1) as rownumber,
        @old_id := id 
    FROM log_embed_video 
    JOIN (SELECT @rn:=0,@old_id:=0) void
    ORDER BY id, view_percent DESC
) a WHERE rownumber=1;

我在这里找不到问题-我真的不知道你在问什么。+1用于示例数据并创建表。。。但是(对我来说)你想要实现什么还不是很清楚(试着用语言解释“期望的结果”;仅仅盯着数据并不能帮助我理解你想要实现什么),代码应该如何处理到第二天(即:23:59=>50%/00:01=>55%)?我不确定是否要过滤掉重复的数据。参考条件数据。。我想保留4行,过滤掉所有其他行,然后能够使用聚合函数并对过滤后的数据分组。@Wrikken-我需要过滤掉重复的行。。。例如,有2条记录的id为43326898。包含该id的行和具有最大值/最高值的view_percent列是我要过滤的
计数(不同id*1000000+存档\u资产\u id)
我假设要获得
计数(不同id,存档\u资产\u id)是一个难题
我们正在使用Infobright Brighthouse数据库,该数据库专门用于查询大型数据集。目前,该数据库不支持COUNT(DISTINCT col1,col2),因此他们推荐使用@Unreason,这两种修改后的查询都可以很好地工作。当按日期范围和单个资产id向下筛选数据时,结果将在不到200毫秒的时间内返回,该表中有超过1亿条记录。感谢您抽出时间回答我的问题@苏格兰人;啊,我明白了不同的逻辑。。那现在也没必要了。。(请参见faq重新投票)+1,因为它是有效的:)我确实想知道Scott会发现哪个解决方案更容易理解……如果他不熟悉左连接技巧,可读性就会受到影响。在性能方面,它也会受到一些影响。我可能会输入一个更难理解的答案,这个答案会快得多…现在,所有的可读性都被排除在外,以利于性能:P@Wrikken-感谢您提交这个查询,但这并没有产生预期的结果。Unreason提交的两个修改后的查询都符合我的目标。谢谢你@Scott:这些是通用的“我想要一个集合的最小/最大值的行,以及来自同一行的相关数据”。实际上,这并不是您想要的完整查询,但这两种查询都会产生您提到的适当的“条件数据”,并且在Anyone(My)SQL的工具集中非常方便,尤其是第二种查询的性能(至少在普通InnoDB/MyISAM表上)。但不用担心,非理性的回答确实有效。
+------------------+---------------------+
| archive_asset_id | AVG(actual_percent) |
+------------------+---------------------+
|            83386 |               36.75 | 
+------------------+---------------------+
SELECT archive_asset_id, actual_percent, count(*) 
FROM (SELECT id, archive_asset_id, asset_title,               
             MAX(view_percent) as actual_percent        
      FROM log_embed_video GROUP by id) T  
GROUP BY archive_asset_id, actual_percent;

+------------------+----------------+----------+
| archive_asset_id | actual_percent | count(*) |
+------------------+----------------+----------+
|            83386 |             13 |        1 | 
|            83386 |             17 |        2 | 
|            83386 |            100 |        1 | 
+------------------+----------------+----------+
SELECT a.* 
FROM log_embed_video a 
LEFT JOIN log_embed_video b
ON b.id = a.id
AND b.view_percent > a.view_percent
WHERE b.id IS NULL
-- possibly limit on date for  more performance.
SELECT * FROM (
    SELECT id, archive_asset_id, asset_title, view_percent, created,
        @rn := IF(id != @old_id,1,@rn + 1) as rownumber,
        @old_id := id 
    FROM log_embed_video 
    JOIN (SELECT @rn:=0,@old_id:=0) void
    ORDER BY id, view_percent DESC
) a WHERE rownumber=1;