草庐IT

mysql - SQL - 来自 3 个表的结果,聚合函数

coder 2023-10-18 原文

我正在尝试为以下结果创建 SQL 查询:

id, name,   Users in group, Messages in groups, Message type 1 in groups, Message type 2 in groups
1   Group1  4               3                   2                         1
2   Group2  3               2                   1                         1
3   Group1  1               1                   1                         0

我的数据库:

create database user_test;

use user_test;


CREATE TABLE `user` (
  `id`             BIGINT      NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(50) NOT NULL,
  `group_id`       BIGINT      NOT NULL,
  PRIMARY KEY (`id`)
);


CREATE TABLE `user_group` (
  `id`      BIGINT           NOT NULL AUTO_INCREMENT,
  `name`    VARCHAR(100)
            CHARACTER SET utf8
            COLLATE utf8_bin NOT NULL,
  UNIQUE KEY `unique` (`name`) USING BTREE,
  PRIMARY KEY (`id`)
);


CREATE TABLE `message` (
  `id`               BIGINT   NOT NULL AUTO_INCREMENT,
  `user_id`           BIGINT   NOT NULL,
  `type`             INT      NOT NULL,
  `date`             DATETIME NOT NULL,
  UNIQUE KEY `unique` (`user_id`, `type`, `date`) USING BTREE,
  PRIMARY KEY (`id`)
);


ALTER TABLE user
    ADD CONSTRAINT user_group_c_fk FOREIGN KEY (group_id) REFERENCES user_group(id);


ALTER TABLE message
    ADD CONSTRAINT user_a_fk FOREIGN KEY (user_id) REFERENCES user(id);

和初始值:

INSERT INTO `user_group`
VALUES (1, "Group 1"),
       (2, "Group 2"),
       (3, "Group 3");

INSERT INTO `user`
VALUES (1, "User 1", 1),
       (2, "User 2", 1),
       (3, "User 3", 1),
       (4, "User 4", 1),
       (5, "User 5", 2),
       (6, "User 6", 2),
       (7, "User 7", 2),
       (8, "User 8", 3);

INSERT INTO `message`
VALUES (1, 1, 1, "2019-07-25 00:00:00"),
       (2, 1, 2, "2019-07-25 00:00:01"),
       (3, 1, 2, "2019-07-25 00:00:02"),
       (4, 5, 1, "2019-07-25 00:00:03"),
       (5, 6, 2, "2019-07-25 00:00:04"),
       (6, 8, 1, "2019-07-25 00:00:05");

我想知道是否有可能的结果。我正在尝试这样的事情:

use user_test;

select user_group.id, 
       user_group.name,
       count(user.id) As "Users in group",
       count(message.id) AS "Messages in groups",
       count(message.type = 1) AS "Message type1 in groups",
       count(message.type = 2) AS "Message type2 in groups"
FROM user_group
LEFT JOIN user ON user.group_id = user_group.id
LEFT JOIN message ON message.user_id = user.id
WHERE user_group.id = message.user_id
GROUP BY user_group.id;

但是,当然,这是完全错误的查询。我认为配置数据库在这种情况下无济于事,但它与整个系统的 split 很小,我无法修改。我想为后端端点创建一个通用查询 - 最好的解决方案是对所有结果进行一次查询。

最佳答案

您可以使用 count(distinct) 快速完成此操作:

SELECT ug.id, ug.name,
       count(distinct u.id) As "Users in group",
       count(distinct m.id) AS "Messages in groups",
       count(distinct case when m.type = 1 then m.id end) AS "Message type1 in groups",
       count(distinct case when m.type = 2 then m.id end) AS "Message type2 in groups"
FROM user_group ug  LEFT JOIN
     user u
     ON u.group_id = ug.id LEFT JOIN
     message m
     ON m.user_id = u.id
WHERE ug.id = m.user_id
GROUP BY ug.id;

您还可以通过在执行联接之前聚合来获得准确的计数。另请注意,我添加了表别名,以便查询更易于编写和阅读。

关于mysql - SQL - 来自 3 个表的结果,聚合函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57197510/

有关mysql - SQL - 来自 3 个表的结果,聚合函数的更多相关文章

  1. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  2. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  3. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  4. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  5. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  6. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  7. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  8. Hive SQL 五大经典面试题 - 2

    目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类

  9. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  10. ruby-on-rails - 将字符串转换为 ruby​​-on-rails 中的函数 - 2

    我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。

随机推荐