JOIN子查询

时间:2017-03-02 15:27:28

标签: mysql sql-update inner-join

我有一个帐户表,其中包含一行role_id。我有另一个名为组织组的表,它保存与组织关联的组,这个组具有ID和名称列。我有一个名为account_group的第三个表,它有两列,一个是account_id,另一个是group_id,用于将两者列在一起。

现在我想检查帐户的组,并根据组的名称,我将更新此帐户的角色ID值。

我设法想到的查询:

    UPDATE account 
SET account.role_id = (CASE WHEN organisation_group.name = "Social Worker" THEN 50
                            WHEN organisation_group.name = "Foster Carer" THEN 26
                       END)
    WHERE organisation_group.name in 
    (SELECT organisation_group.name FROM organisation_group 
INNER JOIN account_group ON organisation_group.id = account_group.group_id 
WHERE organisation_id = 11 GROUP BY organisation_group.name);

这会引发以下错误Unknown column 'organisation_group.name' in 'IN/ALL/ANY subquery'。我不擅长SQL,但我需要这个更新。任何想法如何做这个操作。

50和26是我想要使用的角色ID。

更新1(更清楚的解释)

我有一个包含[[id,username,name,role_id,organisation_id]列的帐户表。

我需要编辑account.role_id列。我需要做的是:

  1. 查看帐户'团队名字。
  2. 这些组位于一个名为organisation_group的表中。该表有三列[id,organisation_id,name]。

    要将帐户映射到一个组,我有一个名为account_group的表,其中有三列[id。 account_id,group_id]。

    2-根据组名,我需要更新account.role_id,以便在(组名=角色名称)时拥有角色ID。

    该角色存储在名为organisation_role的表中,该表包含[id,name,organisation_id]列。

2 个答案:

答案 0 :(得分:1)

首先在你的where条件中你指的是在顶层看不到的table.column WHERE organisation_group.name 你需要account.name 第二,一个建议,你没有聚合函数i子查询,所以如果你需要不同的值sue distinct子句

UPDATE account 
SET account.role_id = (CASE WHEN organisation_group.name = "Social Worker" THEN 50
                            WHEN organisation_group.name = "Foster Carer" THEN 26
                       END)
WHERE account.name in 
    ( SELECT distinct organisation_group.name FROM organisation_group 
      INNER JOIN account_group ON organisation_group.id = account_group.group_id 
      WHERE organisation_id = 11 
     );

但 如果我理解您的加入规则,您应该以这种方式加入

UPDATE account 
INNER JOIN account_group on account_group.account_id = account.id
INNER JOIN organisation_group on organisation_group.id = account_group.group_id 
SET account.role_id = (CASE WHEN organisation_group.name = "Social Worker" THEN 50
                        WHEN organisation_group.name = "Foster Carer" THEN 26
                   END)
WHERE organisation_group.id = 11

答案 1 :(得分:0)

这是我使用的技术。我没有开始尝试编写多表UPDATE语句,而是通过编写SELECT语句来启动该过程。

SELECT语句的目标是返回我想要更新的行(至少是行的主键/唯一键/标识符),以及要更新的列(将要更新的当前值)替换。)除此之外,我还返回了我想要分配列的新值。

我可以调整并使用该SELECT语句来使其准确返回我想要的行。我可以验证将要分配的新值。我可以完成所有这些工作而不会破坏数据库,并更新错误的行。

一旦我验证了SELECT语句,通常可以直接将其转换为UPDATE语句。 (在某些情况下,我将不得不接受SELECT语句并将其包装在parens中并将其用作内联视图。)

我们可以从我们想要更新的表开始。

SELECT a.id
     , a.group_name
     , a.role_id
  FROM account a
 ORDER BY a.id

account_group

添加联接
SELECT a.id
     , a.group_name
     , a.role_id
     , g.group_id
  FROM account a
  JOIN account_group g
    ON g.account_id = a.id
 ORDER BY a.id

(是否仍然返回我们想要返回的所有行?或更多行?如果我们得到多行匹配,那么我们实际想要匹配的哪一行......基数是对的吗?)< / p>

然后将联接添加到organisation_group

SELECT a.id
     , a.group_name
     , a.role_id
     , g.group_id
     , o.name
  FROM account a
  JOIN account_group g
    ON g.account_id = a.id
  JOIN organisation_group o
    ON o.id = g.group_id
 ORDER BY a.id

是否返回了正确的行?然后我们可以添加表达式以将role_id派生到SELECT列表。

SELECT a.id
     , a.group_name
     , a.role_id
     , g.group_id
     , o.name

     , CASE o.name 
       WHEN 'Social Worker' THEN 50
       WHEN 'Foster Care'   THEN 26
       ELSE NULL
       END AS new_role_id

  FROM account a
  JOIN account_group g
    ON g.account_id = a.id
  JOIN organisation_group o
    ON o.id = g.group_id
 ORDER BY a.id

group_name中是否有任何NULL值,或group_name的值不匹配? new_role_id列是否包含我们要分配的值,是否每行都正确?是否有任何行返回我们不想更新?我们是否希望将role_id设置为NULL,而不是&#39;社会工作者&#39;和&#39;寄养&#39; ,或者我们想要保留原样吗? (通过用a.role_id替换NULL)?

一旦我们有SELECT语句工作,将其转换为UPDATE。

我们只需将SELECT ... FROM替换为UPDATE关键字,并在SET子句之前添加WHERE子句(或者在此情况下,在ORDER BY子句之前。)

在此示例中,我们可以将new_role_id表达式分配给role_id列。

UPDATE account a
  JOIN account_group g
    ON g.account_id = a.id
  JOIN organisation_group o
    ON o.id = g.group_id
   SET a.role_id
     = CASE o.name 
       WHEN 'Social Worker' THEN 50
       WHEN 'Foster Care'   THEN 26
       ELSE NULL
       END
 ORDER BY a.id

这是我用来构建多表更新语句的方法。我不够聪明,不能开始编写UPDATE语句。我使用逐步细化来构建SELECT语句,因为我想确定我知道该语句将要做什么。通过检查SELECT返回的结果,我可以进行验证。在我用UPDATE打造一张桌子之前。