对一张表进行复杂的 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”吗? 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 查询的主要内容,如果未能解决你的问题,请参考以下文章