Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 从从子查询接收的值列表中选择,可能为空_Mysql_Sql_Unique - Fatal编程技术网

Mysql 从从子查询接收的值列表中选择,可能为空

Mysql 从从子查询接收的值列表中选择,可能为空,mysql,sql,unique,Mysql,Sql,Unique,我的查询的简化版本如下所示: SELECT id FROM table WHERE column1 IN ( SELECT column1 FROM table GROUP BY column1 HAVING COUNT(*) > 1 ) 这将选择一个id列表,其中column1具有多个发生值,换句话说,这些值不是唯一的。这与预期的一样,但有一个例外:如果值NULL出现多次(这是可能的),则不会选择任何ID。如果NULL不是唯一的,那么选择列ID的正确方法

我的查询的简化版本如下所示:

SELECT id
FROM table
WHERE column1
IN
(
    SELECT column1
    FROM table
    GROUP BY column1
    HAVING COUNT(*) > 1
)
这将选择一个id列表,其中column1具有多个发生值,换句话说,这些值不是唯一的。这与预期的一样,但有一个例外:如果值NULL出现多次(这是可能的),则不会选择任何ID。如果NULL不是唯一的,那么选择列ID的正确方法是什么?

使用EXISTS而不是in:EXISTS更清楚IMHO,并且在大多数情况下它也更快。在里面需要删除/抑制重复项和空值,因此:对集合进行排序

在这种特殊情况下:聚合子查询只需要找出组计数>1。查询优化人员可能没有意识到这一点,在将它们与1进行比较之前,计算完整行集合的完整组计数

另一种明显的方法是明确检查null,但这需要一个OR子句和一组括号,如:

SELECT tt.id
FROM thetable tt
WHERE EXISTS (
    SELECT * FROM thetable ex
    WHERE (ex.column1 = tt.column1 
          OR (ex.column1 IS NULL AND tt.column1 IS NULL)
          )
    AND ex.id <> tt.id
);

如果两者恰好都为NULL,则应返回true。这就是整个问题的核心所在。我添加了或ISNULLex.column1和ISNULLtt.column1。现在一切似乎都好起来了。啊哈,那样的话,我又回到原来的计划板上了。。。解决方案可能涉及双重否定:INsubselect始终从结果集中删除空值和重复项。不,如果有足够的键/索引,则不会。聚合子查询版本将需要或不需要完全扫描,这取决于月球的阶段如何计算计数*>1。。。在子查询中没有至少检查两行的情况下,COUNT*>1?在这两种情况下,一旦发现结果,子查询就可以快速退出,但计划生成器/优化者必须足够聪明才能识别这种情况。博士后的一个做并执行了一种特殊的亲/反joinI,显然,第三个或。。。这个版本比COALESCEcolumn1,-1版本慢得多。这可能取决于空值的比例,顺便说一句,在column1上添加索引在所有情况下都有帮助。column1上是否有像键column1这样的索引?是否有一些示例数据?
SELECT tt.id
FROM thetable tt
WHERE EXISTS (
    SELECT * FROM thetable ex
    WHERE COALESCE(ex.column1, -1) = COALESCE(tt.column1, -1)
    AND ex.id <> tt.id
);
SELECT tt.id
FROM thetable tt
WHERE EXISTS (
    SELECT * FROM thetable ex
    WHERE (ex.column1 = tt.column1 
          OR (ex.column1 IS NULL AND tt.column1 IS NULL)
          )
    AND ex.id <> tt.id
);