[英]Update columns in one table from rows of another table
My case is as follow: 我的情况如下:
I have a table articles
with these details: 我有一个表格articles
,其中包含以下详细信息:
article | image1 | image2 | image3
---------------------------------
1 | im-x
2 | im-y
3 | im-z
and other article_images table with this data: 以及其他具有此数据的article_images表:
article | image
---------------
1 | im-a
1 | im-b
2 | im-c
2 | im-d
3 | im-e
I need to update the table articles like this: 我需要像这样更新表文章:
article | image1 | image2 | image3
---------------------------------
1 | im-x | im-a | im-b
2 | im-y | im-c | im-d
3 | im-z | im-e |
I know it seems not very difficult, but impossible to find an example on google. 我知道这似乎不是很困难,但不可能在Google上找到示例。 Can anyone help me, please? 有人可以帮我吗?
If you can add an additional colum to the article_images table and identify which colum the image needs to go in: 如果您可以在article_images表中添加一个额外的列,并确定图像需要进入哪个列:
article | image | col
------------------------
1 | im-a | image2
1 | im-b | image3
2 | im-c | image3
2 | im-d | image2
3 | im-e | image3
Then this should work: 然后这应该工作:
update articles
set image1 = CASE WHEN col = 'image1' THEN image else image1 END,
image2 = CASE WHEN col = 'image2' THEN image else image2 END,
image3 = CASE WHEN col = 'image3' THEN image else image3 END
from articles inner join article_images
on articles.article = article_images.article
Your current approach with a separate "article_images" table is the best approach. 当前的方法是使用单独的“ article_images”表,这是最好的方法。 This kind of table is the bread and butter of a relational database! 这种表是关系数据库的基础! If it is essential that you have an article with the first 3 images in the same row then I would suggest creating a view, and keeping your current table structure. 如果必须在同一行中包含前三幅图像,那么我建议您创建一个视图并保留当前的表格结构。 The view could be defined as: 该视图可以定义为:
SELECT ar.Article,
MIN(img1.Image) AS Image1,
MIN(img2.Image) AS Image2,
MIN(img3.Image) AS Image3
FROM Articles ar
LEFT JOIN Article_images img1
ON img1.Article = ar.Article
LEFT JOIN Article_images img2
ON img2.Article = ar.Article
AND img2.Image > img1.Image
LEFT JOIN Article_images img3
ON img3.Article = ar.Article
AND img3.Image > img2.Image
GROUP BY ar.Article
This query will produce the desired Pivot: 此查询将产生所需的数据透视:
SELECT a.article, coalesce(i1.image,'') AS img1, coalesce(i2.image, '') AS img2
FROM (SELECT article FROM article_images GROUP BY article) a
LEFT JOIN article_images i1 ON a.article = i1.article AND i1.image =
(SELECT image FROM article_images WHERE article = a.article
ORDER BY image LIMIT 1)
LEFT JOIN article_images i2 ON a.article = i2.article AND i2.image =
(SELECT image FROM article_images WHERE article = a.article
ORDER BY image LIMIT 1 OFFSET 1);
A bit complicated, but this subquery will work in MySQL + PostgreSQL. 有点复杂,但是此子查询将在MySQL + PostgreSQL中运行。
To update use (this UPDATE
is MySQL specific): 要更新使用(此UPDATE
是MySQL特定的):
UPDATE articles a, (SELECT a.article, coalesce(i1.image, '') AS img1,
coalesce(i2.image, '') AS img2
FROM (SELECT article FROM article_images GROUP BY article) a
LEFT JOIN article_images i1 ON a.article = i1.article AND i1.image =
(SELECT image FROM article_images WHERE article = a.article
ORDER BY image LIMIT 1)
LEFT JOIN article_images i2 ON a.article = i2.article AND i2.image =
(SELECT image FROM article_images WHERE article = a.article
ORDER BY image LIMIT 1 OFFSET 1)) AS s
SET a.image2 = s.img1, a.image3 = s.img2
WHERE a.article = s.article;
If your database support window functions + CTE, like SQL Server, PostgreSQL or ORACLE, the following query can be used instead to generate Pivot: 如果您的数据库支持窗口功能+ CTE(例如SQL Server,PostgreSQL或ORACLE),则可以使用以下查询来生成Pivot:
WITH rowed AS (
SELECT article, image,
row_number() OVER (PARTITION BY article ORDER BY image) AS row
FROM article_images)
SELECT a.article, coalesce(i1.image, '') AS img1, coalesce(i2.image, '') AS img2
FROM (SELECT article FROM article_images GROUP BY article) AS a
LEFT JOIN rowed i1 ON i1.article = a.article AND i1.row = 1
LEFT JOIN rowed i2 ON i2.article = a.article AND i2.row = 2;
Now you have a single row per article in a shorter way and you can use this subquery to update: 现在,您可以以较短的方式在每篇文章中拥有一行,并且可以使用此子查询来更新:
UPDATE articles a
SET image2 = s.img1,
image3 = s.img2
FROM (WITH rowed AS (
SELECT article, image,
row_number() OVER (PARTITION BY article ORDER BY image) AS row
FROM article_images)
SELECT a.article, coalesce(i1.image, '') AS img1, coalesce(i2.image, '') AS img2
FROM (SELECT article FROM article_images GROUP BY article) AS a
LEFT JOIN rowed i1 ON i1.article = a.article AND i1.ROW = 1
LEFT JOIN rowed i2 ON i2.article = a.article AND i2.ROW = 2) AS s
WHERE a.article = s.article;
This UPDATE
query will work in PostgreSQL, but likely it wont on ORACLE / SQL Server. 此UPDATE
查询可在PostgreSQL中使用,但可能不会在ORACLE / SQL Server上使用。
You can play around with MySQL and PostgreSQL variants. 您可以使用MySQL和PostgreSQL变体。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.