对一张表进行复杂的 SQL 查询

Posted

技术标签:

【中文标题】对一张表进行复杂的 SQL 查询【英文标题】:Complex SQL query to one table 【发布时间】:2015-12-06 11:37:08 【问题描述】:

有一张桌子:

事件 |id |时间戳 --------------------- 事件1|001|21-03-15 事件2|001|22-03-15 事件1|002|23-03-15 事件2|002|24-03-15

显示结果的请求应该是什么:

id |事件1 |事件2 | ---------------------- 001|21-03-15|22-03-15| 002|23-03-15|24-03-15|

认为您首先需要选择独特的id

SELECT id FROM test GROUP BY id;

然后是这样的:

SELECT timestamp
FROM   ... 
WHERE id IN (SELECT id FROM test GROUP BY id) AND event='event1';

事件提前知道('event1', 'event2')。 如果一个 id 下有重复事件,时间戳不同或相同,则在结果中添加列,例如:

id |event1 |event2 |event1 |event2 | -------------------------------------- 001|21-03-15|22-03-15|23-03-15|23-03-15| 002|23-03-15|24-03-15|空|空|

【问题讨论】:

你能期望每个 ID 都只有两个与之关联的事件吗?它们会一直被称为“event1”和“event2”吗? imo,mysql 查询的有用资源:Common MySQL Queries - Extending Chapter 9 of Get it Done with MySQL 5&6。看看pivot tables 1.每个 ID 不仅会关联两个事件,还会有意外的事件计数 2。是的,事件将始终被称为“事件 1”和“事件 2” 【参考方案1】:

您正在寻找一个简单的“枢轴”或“交叉表”技巧:

SELECT id
     , min(CASE event WHEN 'event1' THEN timestamp END) AS event1
     , min(CASE event WHEN 'event2' THEN timestamp END) AS event2
FROM   test
GROUP  BY id
ORDER  BY id;

SQL Fiddle.

【讨论】:

【参考方案2】:

我找到了解决办法,查询是这样的:

SELECT A.id,GROUP_CONCAT(B.timestamp) AS event1, GROUP_CONCAT(C.timestamp) AS event2 FROM (select distinct id from test) A
   LEFT JOIN test B ON B.id=A.id and B.event='event1'
   LEFT JOIN test C ON C.id=A.id and C.event='event2' GROUP BY A.id

【讨论】:

【参考方案3】:

您可以将具有event1 的记录与具有event2 的记录连接起来:

SELECT t1.id as id, t1.timestamp as event1, t2.timestamp as event2 
FROM test t1 LEFT JOIN test t2
    ON t1.id = t2.id AND t1.event = 'event1' and t2.event = 'event2'

查询假定您始终拥有event1,因此使用了 LEFT JOIN。

如果您需要处理只有event2 可用的情况,您可以按照Full Outer Join in MySQL 中的说明模拟FULL OUTER JOIN

【讨论】:

以上是关于对一张表进行复杂的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

动态SQL

MySQL 复杂查询

第五章 复杂查询 5-1 视图

mybatis 详解------动态SQL

使用SQL的更新语句时,一次可以对几个表进行更新?

复杂SQL_01