mysql - 联接并统计多个表

标签 mysql sql count sum self-join

我试图写一个复杂的字符串(至少,就我的知识水平而言),但我有一个地狱般的时间。
这就是问题所在。我有两张桌子,一张叫t1,一张叫c1。
表格定义如下:

table T1:

e_id, char(8),  
e_date, datetime,  
e_status, varchar(2)

table C1:

e_id, char(8),  
e_date, datetime,  
e_status, varchar(2)

每个表都包含一个标识符列表,这些标识符可能在两个表中都找到,也可能不在两个表中都找到(它们在每个表中可能是唯一的),以及相关的状态(在T1表中可以是“OK”或“R”,在C1表中可以是“OK”或“C”),以及一个日期时间,即e_date,与e_id的每次出现相关
我正在尝试编写一个查询,它将:
检索T1表中过去24小时内e_date的所有e_id值。
检索T1中过去30天内(e_date>now-30天)过去24小时内(e_date大于当前时间-24小时)发生的e_id的所有事件,仍在表T1内(例如:如果在T1中发现e_id的AAAAAAAA和bbbbbb,且e_date在过去24小时内,检索同一表中e_id的AAAAAAAA和BBBBBBBB的所有事件,但其e_日期在过去30天内)
将在整个e_status = 'OK'中找到的每个特定e_idT1 table计数附加到行结果中
将在整个e_Status = 'OK'中找到的每个特定e_idC1 table计数附加到行结果中
我会尽力在这里写一些样本数据/结果。为了清楚起见,我将忽略表数据类型。假设当前日期和时间为2012年11月8日19:00:00
T1号:
e嫒id:'A',e嫒日期:2012-11-08 10:00:00,e嫒状态:'OK'
eêid:'A',eê日期:2012-11-08 10:00:00,eê状态:'R'
e嫒id:'A',e嫒日期:2012-10-15 10:00:00,e嫒状态:'R'
e嫒id:'B',e嫒日期:2012-10-15 10:00:00,e嫒状态:'OK'
e嫒id:'A',e嫒日期:2012-10-15 10:00:00,e嫒状态:'OK'
e嫒id:'A',e嫒日期:2012-10-15 10:00:00,e嫒状态:'R'
e嫒id:'A',e嫒日期:2012-10-15 10:00:00,e嫒状态:'R'
e嫒id:'A',e嫒日期:2010-01-01 10:00:00,e嫒状态:'R'
e嫒id:'A',e嫒日期:2010-01-01 10:00:00,e嫒状态:'R'
C1类:
eêid:'A',eê日期:2012-10-01 10:00:00,eê状态:'C
e嫒id:'B',e嫒日期:2012-10-01 10:00:00,e嫒状态:'OK'
eêid:'A',eê日期:2012-10-01 10:00:00,eê状态:'C
e嫒id:'B',e嫒日期:2012-10-01 10:00:00,e嫒状态:'OK'
e嫒id:'A',e嫒日期:2012-10-01 10:00:00,e嫒状态:'OK'
运行查询将产生:
eúU id、eúU日期、e戋U状态、r戋U计数、c戋U计数
一。e U id:'A',e U日期:2012-11-08 10:00:00,e U状态:'OK',r U计数:6,c U计数:2
2。e_id:'A',e_日期:2012-11-08 10:00:00,e_状态:'R',R_计数:6,c_计数:2
三。e U id:'A',e U日期:2012-10-15 10:00:00,e U状态:'R',R U计数:6,c U计数:2
四。eêid:'A',eêu日期:2012-10-15 10:00:00,eêu状态:'OK',rêu计数:6,cêu计数:2
5个。e U id:'A',e U日期:2012-10-15 10:00:00,e U状态:'R',R U计数:6,c U计数:2
6。e U id:'A',e U日期:2012-10-15 10:00:00,e U状态:'R',R U计数:6,c U计数:2
很抱歉,我不得不将T1第3行的日期更改为第7行(结果的第3、4、5、6行),因为这些值是错误的。
未返回T1的第4行,因为在过去24小时内未发现e_id: B
T1行8和9未返回,因为它们在过去30天之外

最佳答案

是时候做一些TDQD测试驱动的查询设计了。
过去24小时T1行

SELECT DISTINCT e_id
  FROM T1
 WHERE e_date >= DATE_SUB(NOW(), INTERVAL 24 HOUR)

这将是查询其他部分中常见的子查询。
过去30天的T1行。。。
……在过去24小时内T1有记录。
SELECT a.e_id
  FROM t1 AS a
  JOIN (SELECT DISTINCT e_id
          FROM T1
         WHERE e_date >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
       ) AS b ON b.e_id = a.e_id
 WHERE a.e_date >= DATE_SUB(NOW(), INTERVAL 30 DAY)

我们可以根据需要添加其他列。
T1中状态为“R”的行数。。。
…在过去24小时内T1有记录
SELECT a.e_id, COUNT(*) AS r_count  -- Per question; why not t_count?
  FROM t1 AS a
  JOIN (SELECT DISTINCT e_id
          FROM T1
         WHERE e_date >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
       ) AS b ON b.e_id = a.e_id
 WHERE a.e_status = 'R'
 GROUP BY a.e_id

C1中状态为“C”的行数。。。
…在过去24小时内T1有记录
SELECT a.e_id, COUNT(*) AS c_count
  FROM c1 AS a
  JOIN (SELECT DISTINCT e_id
          FROM T1
         WHERE e_date >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
       ) AS b ON b.e_id = a.e_id
 WHERE a.e_status = 'C'
 GROUP BY a.e_id

组合查询集以生成结果
SELECT a.e_id, a.e_date, a.e_status, c.r_count, d.c_count
  FROM t1 AS a
  JOIN (SELECT DISTINCT e_id
          FROM T1
         WHERE e_date >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
       ) AS b ON b.e_id = a.e_id
  LEFT JOIN -- Because there might be no OK rows in T1
       (SELECT a.e_id, COUNT(*) AS r_count
          FROM t1 AS a
          JOIN (SELECT DISTINCT e_id
                  FROM T1
                 WHERE e_date >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
               ) AS b ON b.e_id = a.e_id
         WHERE a.e_status = 'OK'
         GROUP BY a.e_id
       ) AS c ON c.e_id = a.e_id
  LEFT JOIN -- Because there might be no OK rows in C1
       (SELECT a.e_id, COUNT(*) AS c_count
          FROM c1 AS a
          JOIN (SELECT DISTINCT e_id
                  FROM T1
                 WHERE e_date >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
               ) AS b ON b.e_id = a.e_id
         WHERE a.e_status = 'OK'
         GROUP BY a.e_id
       ) AS d ON d.e_id = a.e_id
 WHERE a.e_date >= DATE_SUB(NOW(), INTERVAL 30 DAY)

您可能可以在不使用24小时子查询的情况下编写子查询,但尽快消除尽可能多的行可能是有效的。
TDQD背后概念的一个优点是,您可以检查中期结果。有一些基本上微不足道的语法问题(部分原因是MySQL不是我的主要DBMS),但是在组装查询时,您很容易发现两个COUNT子查询从JOIN到LEFT JOIN的变化。如果不是徒劳无功的话,第一次就把事情做好是很困难的。但是一步一步的积累可以让你对自己所做的事情充满信心。如果不测试组件子查询,我永远不会从头开始构建像这样复杂的查询。
感谢(小)更新,FatalMojo

关于mysql - 联接并统计多个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13299262/

相关文章:

mysql - WikkaWiki 1.3.3 版本中,为什么安装脚本无法创建数据库表?

mysql - AWS : how to host ASP. NET MVC + MySQL

php - MySQL:后续出现的次数

SQL COUNT 条记录在表 2 JOINS 掉

sql - 如何将两个 postgres 列合并为单个值(json 对象)

sql-server - 计算表中出现的次数

mysql - 如何在mysql中分别选择每一行的最长字段

mysql - 如何从本地主机将 SQL 数据库导入 R?

c# - 检查 javascript 函数中的 c# 函数是否为 true

sql - POSTGRES - 如何创建连接两个数据库的选择查询?