繁体   English   中英

MYSQL - 从不同的行中获取值并将它们返回到同一行

[英]MYSQL - Grab value from different row and return them on the same row

我正在使用Laravel 4开发一个多语言网站,我正在使用一个名为waavi翻译的翻译包,简而言之就是将laravel的语言文本文件保存到数据库中。

我有一个问题是以连贯的方式检索数据以使用数据表显示它们以创建语言翻译界面。

表结构如下:

语言表:

id | locale | name
---------------------
1  | en     | english
2  | fr     | french

等等...

Language_entries表:

id  | language_id | namespace | group       | item         | text
--------------------------------------------------------------------
.....
9   | 1           | *         | permissions | save.success | :name has successfully been saved.
....
102 | 2           | *         | permissions | save.success | :name a bien été sauvegardé.
.....

我正在寻找的查询结果是:

group       | item         | en                                 | fr 
----------------------------------------------------------------------------------------------
permissions | save.success | :name has successfully been saved. | :name a bien été sauvegardé.

任何帮助,将不胜感激!

如果您有超过2个区域设置,则可以使用动态版本作为原始问题。

SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(CASE WHEN locale= ''',
      locale,
      ''' THEN text END) AS ',
      locale
    )
   )INTO @sql
FROM language_entries t
JOIN languages l
ON t.language_id=l.id
GROUP BY `group`,item;



SET @sql=CONCAT('SELECT `group`,item,',@sql,' FROM
language_entries t
JOIN languages l
ON t.language_id=l.id
GROUP BY `group`,item');


PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

或者只是非动态版本

SELECT `group`,
item,
MAX(CASE WHEN locale= 'en' THEN text END) AS en
,MAX(CASE WHEN locale= 'et' THEN text END) AS et
FROM language_entries t 
JOIN languages l 
ON t.language_id=l.id 
GROUP BY `group`,item

小提琴

以用户的@Notulysses回答。 您可以在Laravel中使用SQL查询(在4.0上测试),如下所示:

DB::table(DB::raw('language_entries t2'))
  ->select(
    't2.group',
    't2.item',
    DB::raw('GROUP_CONCAT(IF(t1.locale = "en", t2.`text`, NULL)) AS en'),
    DB::raw('GROUP_CONCAT(IF(t1.locale = "fr", t2.`text`, NULL)) AS fr')
  )
  ->leftJoin(DB::raw('languages t1'), function($join)
  {
    $join->on('t1.id', '=', 't2.language_id');
  })
  ->groupBy('t2.group', 't2.item')
  ->get();

我在DB::table()使用DB::raw('')原因是因为Laravel会将language_entries t2变为'language_entries t2' ,这将破坏查询。 选择和左连接的原因相同。

如果您想使用变量而不是手动添加区域设置,请确保使用

DB::connection()->getPdo()->quote("Safe")

保持查询安全。

如上所述,这个问题被称为pivot,我可以建议您使用多个IF条件(与第一个表中唯一的locale条目数一样多)的以下解决方案:

SELECT t2.`group`
     , t2.`item`
     , GROUP_CONCAT(IF(t1.locale = 'en', t2.`text`, NULL)) AS en
     ...
     , GROUP_CONCAT(IF(t1.locale = 'fr', t2.`text`, NULL)) AS fr
FROM `language_entries` t2 
LEFT JOIN `languages` t1 ON t1.`id` = t2.`language_id`
GROUP BY t2.`group`,
         t2.`item`

SQLFiddle

暂无
暂无

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

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