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   | 

それほど難しくないように思えますが、Googleで例を見つけることは不可能です。誰でも私を助けてもらえますか?

4

3 に答える 3

1

このクエリは、目的のピボットを生成します。

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;

データベースがSQLServer、PostgreSQL、ORACLEなどのウィンドウ関数+ CTEをサポートしている場合は、代わりに次のクエリを使用してピボットを生成できます。

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;

これで、記事ごとに短い方法で1つの行ができ、このサブクエリを使用して以下を更新できます。

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 /SQLServerでは機能しない可能性があります。

MySQLPostgreSQLの亜種をいじることができます。

于 2012-05-18T14:16:10.430 に答える
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

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 に答える