0

我的情况如下:

我有一张articles包含这些详细信息的表格:

    article | image1 | image2 | image3 
    ---------------------------------    
      1     | im-x
      2     | im-y
      3     | im-z 

和其他带有此数据的 article_images 表:

    article | image    
    ---------------    
        1   | im-a
        1   | im-b
        2   | im-c
        2   | im-d
        3   | im-e 

我需要像这样更新表格文章:

    article | image1 | image2 | image3    
    ---------------------------------    
       1    | im-x   | im-a   | im-b
       2    | im-y   | im-c   | im-d    
       3    | im-z   | im-e   | 

我知道这似乎不是很困难,但不可能在谷歌上找到一个例子。任何人都可以帮助我吗?

4

3 回答 3

1

如果您可以向 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

那么这应该工作:

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
于 2012-05-18T13:35:18.247 回答
1

您当前使用单独的“article_images”表的方法是最好的方法。这种表是关系数据库的基础!如果您的文章必须在同一行中包含前 3 张图像,那么我建议您创建一个视图,并保留您当前的表结构。视图可以定义为:

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

SQL Fiddle 现场测试

于 2012-05-18T14:10:46.110 回答
1

此查询将生成所需的 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);

有点复杂,但是这个子查询可以在 MySQL + PostgreSQL 中工作。

要更新使用(这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;

如果您的数据库支持窗口函数 + 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;

现在,每篇文章都有一个较短的行,您可以使用此子查询进行更新:

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;

UPDATE查询将在 PostgreSQL 中工作,但在 ORACLE / SQL Server 上可能不会。

您可以使用MySQLPostgreSQL变体。

于 2012-05-18T14:16:10.430 回答