简体   繁体   English

MySQL:联接两个表并根据联接表中的两列填充字段

[英]MySQL: Joining two tables and populating fields according to two columns in the joined table

I'm working on existing gallery system for which I want to make a few fields multilingual (title, source, description). 我正在使用现有的画廊系统,因此我想使一些字段使用多语种(标题,来源,说明)。 A distinct table "translations" is used to store these translated texts. 独特的表“翻译”用于存储这些翻译的文本。 The "lang" column of this table stores the language code ("fr", "en", "de"). 该表的“ lang”列存储语言代码(“ fr”,“ en”,“ de”)。 The "file_id" column stores to which file the translation relates. “ file_id”列存储翻译所涉及的文件。

I'm looking for the best way in MySQL to output the record for one file, with all its columns, including all translations as columns "title_fr, title_en, ..., description_de. 我正在寻找MySQL中输出一个文件及其所有列的记录的最佳方法,包括其所有列,包括所有翻译为列“ title_fr,title_en,...,description_de”。

Tables structure: 表结构:

    CREATE TABLE `files` (
      `id` int(10) unsigned NOT NULL auto_increment,
      `src` varchar(128) NOT NULL default '',
      `name` varchar(128) NOT NULL default '',
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

    CREATE TABLE `translations` (
      `id` int(10) unsigned NOT NULL,
      `file_id` int(10) unsigned NOT NULL,
      `lang` char(2) NOT NULL default '',
      `title` varchar(255) NOT NULL default '',
      `source` varchar(32) default '',
      `description` text,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

I tried two ideas, but none worked. 我尝试了两个想法,但没有一个奏效。

1) The first idea was using VIEWs. 1)第一个想法是使用VIEW。 Failed because of missing access rights on the shared hosting: 由于缺少共享主机上的访问权限而失败:

GRANT CREATE VIEW ON *.* TO 'the-user@the-host' IDENTIFIED BY PASSWORD  'here-the-password';

CREATE VIEW French AS
  SELECT f.id, title AS title_fr, source AS source_fr, description AS description_fr
  FROM files AS f LEFT OUTER JOIN translations AS t ON t.file_id = f.id WHERE (f.id=11 AND t.lang='fr');

CREATE VIEW English AS
  SELECT f.id, title AS title_en, source AS source_en, description AS description_en
  FROM files AS f LEFT OUTER JOIN translations AS t ON t.file_id = f.id WHERE (f.id=11 AND t.lang='en');

CREATE VIEW German AS
  SELECT f.id, title AS title_de, source AS source_de, description AS description_de
  FROM files AS f LEFT OUTER JOIN translations AS t ON t.file_id = f.id WHERE (f.id=11 AND t.lang='de');

SELECT * FROM  files AS f
  LEFT OUTER JOIN French ON f.id=French.id
  LEFT OUTER JOIN English ON f.id=English.id
  LEFT OUTER JOIN German ON f.id=German.id
  GROUP BY f.id;

2) The second idea is inspired from the example in this thread using a pivot table. 2) 第二个想法是通过使用数据透视表从该线程中的示例中得到的。 In my case, I cannot use COUNT() and the following SQL query is not valid, but gives the idea. 就我而言,我不能使用COUNT()并且以下SQL查询无效,但给出了这个主意。 Sorry as there is some redundancy. 抱歉,有一些冗余。

SELECT f.*,
  (CASE
    WHEN t.`lang`='fr'
    THEN t.title
    ELSE NULL
   ) AS title_fr,
  (CASE
    WHEN t.`lang`='en'
    THEN t.title
    ELSE NULL
   ) AS title_en,
  (CASE
    WHEN t.`lang`='de'
    THEN t.title
    ELSE NULL
   ) AS title_de,
  (CASE
    WHEN t.`lang`='fr'
    THEN t.source
    ELSE NULL
   ) AS source_fr,
  (CASE
    WHEN t.`lang`='en'
    THEN t.source
    ELSE NULL
   ) AS source_en,
  (CASE
    WHEN t.`lang`='de'
    THEN t.source
    ELSE NULL
   ) AS source_de 
  (CASE
    WHEN t.`lang`='fr'
    THEN t.description
    ELSE NULL
   ) AS description_fr,
  (CASE
    WHEN t.`lang`='en'
    THEN t.description
    ELSE NULL
   ) AS description_en,
  (CASE
    WHEN t.`lang`='de'
    THEN t.description
    ELSE NULL
   ) AS description_de
FROM files AS f WHERE id=11
LEFT OUTER JOIN
translations AS t
ON f.id=t.file_id
GROUP BY id

I also read about CONCAT and CONCAT_WS but they are not what I'm looking for, as I want to make further PHP processing as simple as possible. 我还阅读了有关CONCAT和CONCAT_WS的信息,但它们并不是我想要的,因为我想使进一步的PHP处理尽可能简单。

Although you can't use count , you can use max , so try this query, it should be what you are looking for: 尽管您不能使用count ,但是可以使用max ,所以请尝试以下查询,它应该是您要寻找的内容:

SELECT 
  f.id, f.src, f.name,
  MAX(CASE WHEN t.lang='fr' THEN t.title ELSE NULL END) AS title_fr,
  MAX(CASE WHEN t.lang='en' THEN t.title ELSE NULL END) AS title_en,
  MAX(CASE WHEN t.lang='de' THEN t.title ELSE NULL END) AS title_de,
  MAX(CASE WHEN t.lang='fr' THEN t.source ELSE NULL END) AS source_fr,
  MAX(CASE WHEN t.lang='en' THEN t.source ELSE NULL END) AS source_en,
  MAX(CASE WHEN t.lang='de' THEN t.source ELSE NULL END) AS source_de,
  MAX(CASE WHEN t.lang='fr' THEN t.description ELSE NULL END) AS description_fr,
  MAX(CASE WHEN t.lang='en' THEN t.description ELSE NULL END) AS description_en,
  MAX(CASE WHEN t.lang='de' THEN t.description ELSE NULL END) AS description_de
FROM files AS f 
LEFT OUTER JOIN translations AS t ON f.id=t.file_id
WHERE f.id=11
GROUP BY f.id, f.src, f.name;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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