从没有子查询的 MySQL 表中获取详细信息
Posted
技术标签:
【中文标题】从没有子查询的 MySQL 表中获取详细信息【英文标题】:Get the details from a MySQL table without sub query 【发布时间】:2017-10-26 12:55:17 【问题描述】:我正在使用mysql
查询从 2 个表中获取数据。在这里,我在 table2 中有一个状态 Transfer Out
。我确实需要获取状态为Transfer Out
的所有详细信息,同时,在Transfer Out
之后添加的Transfer In
状态不应该有任何详细信息。 这样我就不应该在Transfer Out
之后得到Transfer back In
的详细信息。
现在我正在使用subquery
。但是当数据计数变高时,就会导致超时问题。有没有更好的方法来重写查询并获得相同的结果?
我的查询示例是
SELECT sq.etid
FROM (
SELECT og.etid, pt.timestamp
FROM og_membership og
INNER JOIN table1 n ON(n.nid=og.etid)
INNER JOIN table2 pt ON(og.etid=pt.animal_nid)
WHERE og.entity_type='node'
AND pt.partner_gid = :gid
AND pt.shelter_gid = :our_gid
AND pt.type = 'Transfer Out'
AND (
SELECT count(id)
FROM table2
WHERE timestamp > pt.timestamp
AND type = 'Transfer In'
AND partner_gid = :gid
AND shelter_gid = :our_gid
) = 0
) AS sq
【问题讨论】:
这不就是说最后一笔交易在哪里“转出”,或者转出后是否还有转入以外的交易? "来自 2 个表" -- 看起来像 3 个表! 【参考方案1】:例如,您可以通过一个组来执行此操作
select something
from somehwere
group by something having isnull(max(out_date),0) > isnull(max(indate) ,0)
例如
DROP TABLE IF EXISTS LOANS;
CREATE TABLE LOANS (ID INT AUTO_INCREMENT PRIMARY KEY, ISBN INT,DIRECTION VARCHAR(3), DT DATETIME);
INSERT INTO LOANS(ISBN,DIRECTION,DT) VALUES
(1,'OUT','2017-10-01 09:00:00'),
(2,'OUT','2017-10-02 10:00:00'),
(2,'IN', '2017-10-02 10:10:00'),
(3,'REC','2017-10-02 10:00:00'),
(4,'REC','2017-10-02 10:00:00'),
(4,'OUT','2017-10-03 10:00:00'),
(4,'IN', '2017-10-04 10:00:00'),
(4,'OUT','2017-10-05 10:00:00')
;
SELECT ISBN
FROM LOANS
WHERE DIRECTION IN('OUT','IN')
GROUP BY ISBN HAVING
MAX(CASE WHEN DIRECTION = 'OUT' THEN DT ELSE 0 END) >
MAX(CASE WHEN DIRECTION = 'IN' THEN DT ELSE 0 END) ;
结果
+------+
| ISBN |
+------+
| 1 |
| 4 |
+------+
2 rows in set (0.00 sec)
如果 DT 出现平局,您可以替换 id。
【讨论】:
感谢您的努力。但问题是,没有像 out_date 和 indate 这样的字段。两者都有一个时间戳列,如果有摄入/结果,将添加新行 原理不变,请看例子补充回答。【参考方案2】:改变
( SELECT COUNT(id) FROM ... ) = 0
到
EXISTS ( SELECT 1 FROM ... )
去掉最外层的查询和第一个pt.timestamp
。 (或者pt.timestamp
有什么不为人知的原因吗?)
table2
需要INDEX(type, partner_gid, shelter_gid, timestamp)
。 timestamp
必须排在最后,但其他的可以任意排列。
table2
需要INDEX(type, partner_gid, shelter_gid, animal_nid)
;列可以按任何顺序排列。 (这个索引不能和前一个结合。)
og_membership
需要 INDEX(etid, entity_type)
(以任意顺序)。
为什么查询中有INNER JOIN table1 n ON(n.nid=og.etid)
? table1
似乎根本没有被使用——除了可能用于验证行的存在。如果可能,请将其删除。
更改后,请提供EXPLAIN SELECT ...
和SHOW CREATE TABLE
用于2(或3??)表。
【讨论】:
以上是关于从没有子查询的 MySQL 表中获取详细信息的主要内容,如果未能解决你的问题,请参考以下文章