MySQL中的问题更新,其中所选行的计数为1

时间:2017-08-24 20:00:23

标签: mysql sql sql-update

我在使用简单的更新语句更新表时遇到问题。

数据看起来像这样

+----------------------------------------------------------------------+
|    id   |    contractor_id    |    domain    |    primary_domain     |
_______________________________________________________________________|
|    1    |         50          |    foo.com   |           1           |
|----------------------------------------------------------------------|
|    2    |         50          |    foo.net   |           0           |
|----------------------------------------------------------------------|
|    3    |         100         |  widget.com  |           0           |
+----------------------------------------------------------------------+

我要做的是update只有 1 域的承包商将该域设置为 0 。 ..因此,在这种情况下,它会忽略承包商 50 并将承包商 100 primary_domain设置为 1

这就是我想出来的,但它失败了,我不知道为什么 - 有人可以解释我的昙花一现吗?我如何达到预期的效果?

UPDATE domains_test SET primary_domain = '1'
WHERE(
SELECT primary_domain 
FROM domains_test 
WHERE primary_domain = 0 
HAVING domain = 1);

修改 我甚至试过HAVING count(domain) = 1);

响应总是

You can't specify target table 'domains_test' for update in FROM clause

3 个答案:

答案 0 :(得分:2)

要正确获取与只有一个 contractor_id相关的domain值,您可以使用以下查询:

SELECT contractor_id
FROM domains_test
GROUP BY contractor_id
HAVING COUNT(DISTINCT domain) = 1;

<强>输出:

contractor_id
--------------
100

因此,UPDATE可以写成:

UPDATE domains_test
SET primary_domain = 1
WHERE primary_domain = 0 AND 
      contractor_id IN (SELECT contractor_id
                        FROM (
                            SELECT contractor_id
                            FROM domains_test
                            GROUP BY contractor_id
                            HAVING COUNT(DISTINCT domain) = 1) AS t);

由于错误,子查询中的嵌套是必要的:

  

您无法指定目标表&#39; domains_test&#39;用于FROM子句中的更新

如果直接从子查询中的contractor_id获取domains_test,则会出现此错误。

Demo here

答案 1 :(得分:0)

您的逻辑是不正常的:您希望更新子查询的COUNT为特定值的域;在这种情况下,只有1个域和该域的contractors计数值为0

您目前没有计算 SQL中的任何内容。而是使用它:

UPDATE domains_test SET primary_domain = 1
WHERE (
      SELECT COUNT(*) FROM domains_test
      GROUP BY (contractor_id) 
      ) = 1
AND primary_domain = 0

这样做:首先它搜索承包商组,其中contractor_id只在计数中出现一次,然后对于每个承包商,它检查primary_domain的值,当两个条件都为真时适当更新。

答案 2 :(得分:0)

<强> SQL DEMO

UPDATE domains_test AS d
LEFT JOIN 
     (SELECT contractor_id 
      FROM domains_test
      GROUP BY  contractor_id
      HAVING COUNT(*) = 1) as f
   ON d.contractor_id = f.contractor_id
SET d.primary_domain = 1

WHERE  d.primary_domain = 0
  AND  f.contractor_id IS NOT NULL;