简体   繁体   English

WHERE中的SQL子查询返回有限的结果集,但仍与所有结果匹配

[英]SQL subquery in WHERE returning limited result set but still matching all

I need help with SQL query: 我需要有关SQL查询的帮助:

UPDATE content_type_blog b
LEFT JOIN node n
ON n.nid = b.nid
SET b.field_is_latest_value = 1
WHERE n.nid IN (
  (
    SELECT nid
    FROM node
    GROUP BY uid
    ORDER BY created DESC
  )
);

The select in WHERE clause returns 4012 results but when the whole query is run it updates 124k results instead limiting it to those 4012 matched in subquery. WHERE子句中的select返回4012个结果,但是在运行整个查询时,它将更新124k个结果,而不是将其限制为子查询中匹配的4012个结果。

This query intends to update content_type_blog - table columns by nid where created is highest (latest) in node-table. 该查询旨在通过nid更新content_type_blog表列,其中创建的节点表最高(最新)。

Your subquery filters out duplicate nid values, but it still returns all of them. 您的子查询会过滤掉重复的nid值,但仍会返回所有值。 So it's not a filter at all. 因此,它根本不是过滤器。

In other databases, what you ask is typically done with a window function like row_number() . 在其他数据库中,通常使用诸如row_number()类的窗口函数来完成您所要求的操作。 But MySQL doesn't support that. 但是MySQL不支持。 Instead, you could use a filtering join. 相反,您可以使用过滤联接。

Here's an example. 这是一个例子。 SQL Fiddle seems down, so I can't test it, but I hope it will point you in the right direction. SQL Fiddle看起来很糟糕,因此我无法对其进行测试,但我希望它会为您指明正确的方向。

create table table1 (col1 int, col2 bit, created datetime)
insert table1 values
    (1, 0, '2013-01-01'),
    (1, 0, '2013-01-02'),
    (1, 0, '2013-01-03'),
    (2, 0, '2013-01-01');

update  table1
join    (
        select  col1
        ,       max(created) as max_created
        from    table1
        group by
                col1
        ) filter
on      filter.col1 = table1.col1
        and filter.max_created = table1.creatd
set     col2 = 1

select  *
from    table1

Maybe the problem would be that you are using content_type_blog b LEFT JOIN , so doing it you are including all rows of content_typ_blog on the result query. 可能的问题是您正在使用content_type_blog b LEFT JOIN ,因此您将在结果查询中包括content_typ_blog所有行。 Try using INNER JOIN to update only the rows of your subquery: 尝试使用INNER JOIN仅更新子查询的行:

UPDATE content_type_blog b
INNER JOIN node n
ON n.nid = b.nid
SET b.field_is_latest_value = 1
WHERE n.nid IN (
  (
    SELECT nid
    FROM node
    GROUP BY uid
    ORDER BY created DESC
    LIMIT 1
  )
);

This seems to do the trick: 这似乎可以解决问题:

UPDATE content_type_blog b
LEFT OUTER JOIN node n
ON n.nid = b.nid
JOIN    (
        SELECT DISTINCT nid,
        MAX(created) AS max_created
        FROM    node
        GROUP BY uid
        ) filter
ON      filter.nid = b.nid
SET b.field_is_latest_value = 1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM