[英]MYSQL - Grab value from different row and return them on the same row
I am working on an multi-language website with Laravel 4 and I am using a translation package called waavi translation, in short grabs the language text files of laravel and saves them to the db. 我正在使用Laravel 4开发一个多语言网站,我正在使用一个名为waavi翻译的翻译包,简而言之就是将laravel的语言文本文件保存到数据库中。
I am having an issue retrieving the data in a coherent manner to display them with datatables to create a language translation interface. 我有一个问题是以连贯的方式检索数据以使用数据表显示它们以创建语言翻译界面。
The table structures is as follow: 表结构如下:
Languages Table: 语言表:
id | locale | name
---------------------
1 | en | english
2 | fr | french
etc... 等等...
Language_entries Table: 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é.
.....
The query result I am looking for is: 我正在寻找的查询结果是:
group | item | en | fr
----------------------------------------------------------------------------------------------
permissions | save.success | :name has successfully been saved. | :name a bien été sauvegardé.
Any help would be appreciated! 任何帮助,将不胜感激!
If you have more than 2 locale you can use a dynamic version,for your original question. 如果您有超过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;
Or just the non dynamic version 或者只是非动态版本
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
Taking user's @Notulysses answer. 以用户的@Notulysses回答。 You can use the SQL query in Laravel (tested on 4.0) like so: 您可以在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();
The reason why I'm using DB::raw('')
inside DB::table()
is because Laravel would turn language_entries t2
to 'language_entries t2'
which would break the query. 我在DB::table()
使用DB::raw('')
原因是因为Laravel会将language_entries t2
变为'language_entries t2'
,这将破坏查询。 Same reason in select and left join. 选择和左连接的原因相同。
If you would want to use a variable instead of manually adding locales then make sure you use 如果您想使用变量而不是手动添加区域设置,请确保使用
DB::connection()->getPdo()->quote("Safe")
To keep the query safe. 保持查询安全。
As it is said above this problem is called pivot and I can suggest you the following solution, using multiple IF
conditions (as much as the number of unique locale
entries in the first table ) : 如上所述,这个问题被称为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`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.