简体   繁体   中英

How do I set the value of a column be a result of a SQL query using one of the columns of the same table

I have two tables

Table 1 : Users

Has columns id , Name , institution

Institution is a sting showing institution name.

Table 2: Institutions.

Has columns id , institution , count

I need the count column to be recording the number of rows in table 1 where institution is same as the institution in each row of Table 2. This should happen for all the rows of Table 2.

Please help me get the right MySQL queries or table relations to achieve this.

Join both the tables on instutions and get the count like below

select i.institution,
X.ins_count
from  Institutions i
left join
(
select institution,
count(*) as ins_count
from Users
group by institution
) X on i.institutions = X.institutions

this question doesn't have a lot of detail but from what I understand you just want to do this.

UPDATE TABLE institutions,
    (SELECT 
        i.id,
        COUNT(u.id) as user_count
    FROM Users u
    JOIN Institutions i on i.institution = u.institution
    GROUP BY i.institution) as temp
SET institutions.count = temp.user_count 
WHERE temp.id = institutions.id;

I'd do something like this:

UPDATE institutions i
  LEFT
  JOIN ( SELECT u.institution
              , COUNT(1) AS user_cnt 
           FROM users u
          GROUP BY u.institution
       ) c
    ON c.institution = i.institution
   SET i.count = IFNULL(c.user_cnt,0)

The inline view (aliased as c) gets a count of users for each "institution". This result is outer joined to institutions. (We reference the result from that inline view query like it was a table; MySQL actually refers to the inline view as a "derived table".

We assign the value derived user_cnt value to the count column, and substituting 0 for NULL (which will happen if there are no users in a given "institution".)

To see this in action BEFORE you run the update, you can run a similar SELECT (remove the SET clause and change the UPDATE keyword to be SELECT <expression_list> FROM , optionally add an ORDER BY clause.

SELECT i.institution
     , i.count               AS old_count
     , IFNULL(c.user_cnt,0)  AS new_count
  FROM institutions i
  LEFT
  JOIN ( SELECT u.institution
              , COUNT(1) AS user_cnt 
           FROM users u
          GROUP BY u.institution
       ) c
    ON c.institution = i.institution
 ORDER BY i.institution

As another possible approach to achieve the same result, but with (likely) less efficiency (if this is actually valid), would be to use a correlated subquery to return the value:

UPDATE institutions i
   SET i.count = ( SELECT COUNT(1) 
                     FROM users u
                    WHERE u.institution = i.institution
                 ) 

I know that approach "works" in a SELECT statement. I expect it to work in an UPDATE statement, but I haven't tested that. Equivalent SELECT would be:

SELECT i.institution
     , i.count AS old_count
     , ( SELECT COUNT(1) 
           FROM users u
          WHERE u.institution = i.institution
        ) AS new_count
  FROM institutions i

Absent any compelling reason to use a correlated subquery, I'd avoid that and go with the JOIN operation instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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