简体   繁体   中英

How to Join mulitple rows of values into columns in second table, by foreign key in MySQL

I have 2 tables - news and files. The files table has a news_id foreign key. There may be multiple rows of files with the same news_id. Each news_id has up to 3 files, some have none; for example one news article may have 2 images associated with it and another only one etc. I want to select the 'name' from the files table, which matches the news_id and insert the 'name' into the news table - into cols: file_1, file_2, file_3.

files

file_id news_id name cat_id
1 2 im1.jpg 13
2 2 im2.jpg 13
3 3 im4.jpg 13
4 3 im6.jpg 13
5 3 im7.jpg 14

news

news_id file_1 file_2 file_3
1
2
3

The select part of the query retrieves the files I need. I just cant seem to work out the insert as there are different amount of files for each news ID. I have tried this query:

INSERT INTO news(files_1,files_2,files_3)
SELECT t2.name
FROM files t2
left JOIN news t1 ON t2.file_id = t1.news_id
WHERE t2.cat_id LIKE 13

And:

INSERT INTO news(files_1, files_2, files_3)
SELECT COALESCE( t2.name, '')
FROM files t2
LEFT JOIN news t1 ON t2.file_id = t1.news_id
WHERE t2.cat_id LIKE 13

The error I get is: column count doesn't match value count at row 1.

I am trying to achieve something like:

news

news_id file_1 file_2 file_3
1 0 0 0
2 im1.jpg im2.jpg 0
3 im4.jpg im6.jpg 0

This answer: [1]: https://dba.stackexchange.com/questions/128668/insert-data-from-multiple-rows-into-multiple-columns

helped me write the following query, which achieved the desired result:

 SELECT t1.news_id
  , COALESCE(grp.file_1, '') as file_1
  , COALESCE(grp.file_2, '') as file_2
  , COALESCE(grp.file_3, '') as file_3
FROM news t1
INNER JOIN (
   SELECT d.news_id as news_id
   , MAX(CASE WHEN row = 1 THEN d.name END) AS file_1
   , MAX(CASE WHEN row = 2 THEN d.name END) AS file_2
   , MAX(CASE WHEN row = 3 THEN d.name END) AS file_3
    FROM
    (
      SELECT @row := CASE WHEN t2.news_id = @news_id 
          THEN @row + 1 ELSE 1 END as row 
          , @news_id := t2.news_id as news_id
          , t2.name
          FROM (SELECT @row := 0, @news_id := 0) v
        , files as t2 
      ORDER BY t2.news_id
    ) d 
    GROUP BY d.news_id
) grp
    ON grp.news_id = t1.news_id;


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