我有一个旧的数据库,来自一个被遗弃的" Joomgalaxy" Joomla插件。
有三个表格joomgalaxy_entries
,joomgalaxy_fields
和joomgalaxy_entries_data
id
表中的entries
与entry_id
表中的entries_data
匹配,但实际字段名称保存在另一个表fields
< / p>
有人可以帮助我使用正确的SQL语句来获取结果,就像您在终极目标中看到的那样?我的MySQL知识非常基础,从我的搜索中听起来我需要使用LEFT JOIN,但我不知道如何使用field_name
中的值作为返回值的列名
谢谢!!
joomgalaxy_entries
---------------------------------------
| id | title | longitude | latitude |
---------------------------------------
| 50 | John | -79.333333 | 43.669999 |
| 51 | Bob | -79.333333 | 43.669999 |
---------------------------------------
joomgalaxy_fields
这只是下面两个例子,为了简单起见,不仅仅是这两个,所以它必须能够使用field_name
作为列名动态处理。
--------------------------------
| id | field_type | field_name |
--------------------------------
| 1 | textbox | websiteurl |
| 2 | dropdown | occupation |
--------------------------------
joomgalaxy_entries_data
&#34;技术上&#34;不应该有任何重复的条目(fieldid
和entry_id
),所以根据我的理解,不应该影响使用上面的field_name
作为列名,但是如果最终成为一个怎么办?
-------------------------------------
| fieldid | field_value | entry_id |
-------------------------------------
| 1 | google.com | 50 |
| 2 | unemployed | 50 |
| 1 | doctor.com | 51 |
| 2 | doctor | 51 |
-------------------------------------
终极目标
最终尝试获得这种类型的结果,然后我可以在MySQL Workbench中使用该语句来导出如下所示的数据:
------------------------------------------------------------------
| id | title | longitude | latitude | websiteurl | occupation |
------------------------------------------------------------------
| 50 | John | -79.333333 | 43.669999 | google.com | unemployed |
| 51 | Bob | -79.333333 | 43.669999 | doctor.com | doctor |
------------------------------------------------------------------
修改
不仅仅是两个字段websiteurl
和occupation
,我只是将这两个字段用作示例,有许多字段都是不同的,因此理论上从field_name
中提取值将用于列名称
答案 0 :(得分:1)
您可以使用某些条件逻辑(如CASE
语句)以及max()
或min()
等聚合函数将这些值作为列返回:
SELECT je.id,
je.title,
je.longitude,
je.latitude,
max(case when jf.fieldid = 1 then jed.field_value end) as WebsiteUrl,
max(case when jf.fieldid = 2 then jed.field_value end) as Occupation
FROM joomgalaxy_entries je
INNER JOIN joomgalaxy_entries_data jed
on je.id = jed.entry_id
GROUP BY je.id,
je.title,
je.longitude,
je.latitude
如果要返回所有joomgalaxy_entries
,即使在其他表中没有要连接的匹配行,使用INNER JOIN也只会返回每个表中包含值的joomgalaxy_entries
行,然后将INNER JOIN更改为LEFT JOIN。
答案 1 :(得分:1)
您可以编写一个简单的SELECT
查询,如下所示:
SELECT je.id, je.title, je.longitude, je.latitude,
(SELECT field_value FROM joomgalaxy_entries_data WHERE fieldid = 1 AND entry_id = je.id) AS websiteurl,
(SELECT field_value FROM joomgalaxy_entries_data WHERE fieldid = 2 AND entry_id = je.id) AS occupation
FROM joomgalaxy_entries je;
答案 2 :(得分:0)
第一步很简单:
SELECT JE.id, JE.title, JE.longitude, JE.latitude
FROM joomgalaxy_entries JE
现在你需要加入:
SELECT JE.id, JE.title, JE.longitude, JE.latitude,
JD.*
FROM joomgalaxy_entries JE
JOIN joomgalaxy_entries_data JD
ON JE.id = JD.entry_id
现在您需要将行转换为列
SELECT JE.id, JE.title, JE.longitude, JE.latitude,
MIN(CASE WHEN fieldid = 1 THEN JD.field_value END) as WebsiteUrl,
MIN(CASE WHEN fieldid = 2 THEN JD.field_value END) as Occupation
FROM joomgalaxy_entries JE
JOIN joomgalaxy_entries_data JD
ON JE.id = JD.entry_id
GROUP BY JE.id, JE.title, JE.longitude, JE.latitude
这取决于你每个条目只有两个字段,如果字段数是动态的,你需要一个不同的方法。
答案 3 :(得分:0)
这应该有效:
select id, title, longitude, latitude,
(select field_value from joomgalaxy_entries_data jed
where fieldid = (select id from joomgalaxy_fields
where field_name = 'websiteurl')
and jed.entry_id = je.id
) as websiteurl,
(select field_value from joomgalaxy_entries_data jed
where fieldid = (select id from joomlgalaxy_fields
where field_name = 'occupation')
and jed.entry_id = je.id) as occupation
from joomgalaxy_entries je;
请注意,左边连接的原因是,如果siteurl或者占用为null,则无论如何,此解决方案应该适用于该情况。
答案 4 :(得分:0)
嗯,这肯定会让它变得更难...... :)老实说,我不确定你用静态SQL查询可以提出什么问题。但是,如果我错了,我相信有人会说出来。
那就是说,我可以尝试一些选项:
选项1 - 动态生成SQL
假设这是mysql,如果执行以下SQL,它将动态生成子查询:
select concat('(select field_value from joomgalaxy_entries_data jed ',
'where fieldid = (select id from joomgalaxy_fields ',
'where field_name = ''', field_name, ''') ',
'and jed.entry_id = je.id) as ', field_name, ',')
from joomgalaxy_fields;
获取该命令的结果,将其复制粘贴到文本编辑器中,并在开头添加以下内容:
select id, title, longitude, latitude,
最后的其余部分:
from joomgalaxy_entries je;
然后运行新的超级查询,根据数据库中的数据量,获取一份副本,午餐或晚安睡眠。
或者,您可以将所有这些添加到存储过程中,这样您就不必手动编辑SQL。另请注意,我的语法适用于MySQL。其他数据库具有不同的连接运算符,因此您可能必须解决此问题(如果适用)。此外,有50多个子查询,这个超级查询很可能会很慢,可能太慢,无法使这个选项可行。
选项2 - 按照您想要的方式创建一个表格并填充它
希望这是不言自明的,但只需创建一个包含joomgalaxy_fields表中所有必需列的新表。然后用一长串应该是非常简单的sql命令分别填充每一列。当然,如果数据库不再使用,我相信你指出这个选项是可行的。从那里结果就是:
select * from my_new_table;