mysql使用'不在'没有列值

时间:2016-03-02 15:01:41

标签: mysql

我有一张类似于此的表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' )

但我不明白为什么?

2 个答案:

答案 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表中使用它是有益的,这样你就可以添加一个索引;)