我有一张类似于此的表Transactions
:
id Type Field ObjectId NewValue
1 AddLink HasMember 4567 someDomain/someDirectory/1231
2 AddLink HasMember 4567 someDomain/someDirectory/1232
3 AddLink HasMember 4567 someDomain/someDirectory/1233
4 DeleteLink HasMember 4567 someDomain/someDirectory/1231
" NewValue"的数字结尾是我感兴趣的。
详细说明,我需要那些我有记录类型为" AddLink"并且没有更新的类型记录" DeleteLink"存在,即id
= 2或3(因为4删除1)的记录
" ObjectId"以及" NewValue"的数字位;两者都是"票据"的条目ID。表,我需要相关的门票。
我试过这个:
SELECT `Tickets`.* FROM `Transactions` AS `addedLinks`
LEFT JOIN `Tickets` ON RIGHT (`addedLinks`.`NewValue`, 4) = `Tickets`.`id`
WHERE `addedLinks`.`Type` = 'AddLink'
AND `addedLinks`.`Field` = 'Hasmember'
AND `addedLinks`.`ObjectId` = '4567'
AND NOT RIGHT (`addedLinks`.`NewValue`, 4) in (
SELECT `Tickets`.* FROM `Transactions` AS `deletedLinks`
LEFT JOIN `Tickets` ON RIGHT (`deletedLinks`.`NewValue`, 4) = `Tickets`.`id`
WHERE `deletedLinks`.`Type` = 'DeleteLink'
AND `addedLinks`.`id` < `deletedLinks`.`id`
AND `deletedLinks`.`Field` = 'Hasmember'
AND `deletedLinks`.`ObjectId` = '4567' )
这给了我:
SQL Error (1241): Operand should contain 1 column(s)
除非我出错了,否则问题是
RIGHT (`addedLinks`.`NewValue`, 4)
在&#34; AND NOT ... in()&#34;言。
有人能指出我在正确的方向吗?
[编辑] 感谢David K-J,以下作品:
SELECT `Tickets`.* FROM `Transactions` AS `addedLinks`
LEFT JOIN `Tickets` ON RIGHT (`addedLinks`.`NewValue`, 4) = `Tickets`.`id`
WHERE `addedLinks`.`Type` = 'AddLink'
AND `addedLinks`.`Field` = 'Hasmember'
AND `addedLinks`.`ObjectId` = '5376'
AND NOT (RIGHT (`addedLinks`.`NewValue`, 4)) in (
SELECT `id` FROM `Transactions` AS `deletedLinks`
WHERE `deletedLinks`.`Type` = 'DeleteLink'
AND `addedLinks`.`id` < `deletedLinks`.`id`
AND `deletedLinks`.`Field` = 'Hasmember'
AND `deletedLinks`.`ObjectId` = '5376' )
但我不明白为什么?
答案 0 :(得分:1)
这里的问题是您的子选择,因为您使用它来提供IN
子句的值,您的子选择应该只选择id字段,即Transactions.*
- &gt; Transactions.id
所以你最终得到:
...
AND NOT (RIGHT (`addedLinks`.`NewValue`, 4)) IN
SELECT id FROM Transactions AS deletedLinks WHERE
...
原因是IN
需要列表进行比较,因此foo IN ( 1,2,3,4,5 )
。如果您的子查询正在选择多个字段,则结果列表在概念上是一个列表(AoA),例如,[1, 'a'], [2, 'b'], [3, 'c']
,它会向您投诉=)
答案 1 :(得分:0)
啊,这是如此复杂和子查询...让它更简单,会更快
CREATE TEMPORARY TABLE `__del_max`
SELECT `NewValue`, MAX(`id`) as id FROM tickets
WHERE type = 'DeleteLink'
GROUP BY NewValue;
CREATE INDEX _nv ON __del_max(`NewValue`)
SELECT * FROM `tickets`
LEFT OUTER JOIN `__del_max` ON tickets.NewValue = __del_max.NewValue AND __del_max.id > tickets.id
WHERE __del_max.id IS NULL
你可以在单个大型连接中使用它,但在TMP表中使用它是有益的,这样你就可以添加一个索引;)