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

时间:2015-08-26 18:33:38

标签: mysql join merge field

我正在研究现有的图库系统,我想用多语言制作一些字段(标题,来源,描述)。不同的表“翻译”用于存储这些翻译的文本。该表的“lang”列存储语言代码(“fr”,“en”,“de”)。 “file_id”列存储与翻译相关的文件。

我正在寻找MySQL中输出一个文件记录的最佳方法,包括所有列,包括所有翻译为“title_fr,title_en,...,description_de。

表格结构:

    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 ;

我尝试了两个想法,但都没有效果。

1)第一个想法正在使用VIEW。由于缺少共享主机的访问权限而失败:

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)第二个想法的灵感来自this thread中使用数据透视表的示例。在我的情况下,我不能使用COUNT()并且以下SQL查询无效,但给出了这个想法。抱歉,因为有一些冗余。

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

我还读到了关于CONCAT和CONCAT_WS的内容,但它们并不是我想要的,因为我希望尽可能简单地进行PHP处理。

1 个答案:

答案 0 :(得分:0)

虽然您无法使用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;