Mysql 如何查询没有直接关系的不同表并合并不明确的列 此问题已在原始问题回答者反馈后编辑
我有一个复杂的MySQL问题,需要在不一定有任何连接的不同表之间进行查询我与第三方系统打交道,因此无法对数据库的结构进行任何更改 为了简洁起见,我把这个问题过分简化了,但我能想到的最简单的解释方式是:我需要一份学生及其主要活动的清单。学生被包含在一个表中,但问题是他们所参与的活动是通过其他表引用的,而这些表之间只有粗略的关系。每个建筑都有(2)个自定义字段信息表。“XX_CUSTOMFIELDNAMES”包含自定义字段的名称,“XX_CUSTOMFIELDVALUES”包含相关值。在本例中,自定义字段名为“活动” 表格和样本数据:Mysql 如何查询没有直接关系的不同表并合并不明确的列 此问题已在原始问题回答者反馈后编辑,mysql,sql,Mysql,Sql,我有一个复杂的MySQL问题,需要在不一定有任何连接的不同表之间进行查询我与第三方系统打交道,因此无法对数据库的结构进行任何更改 为了简洁起见,我把这个问题过分简化了,但我能想到的最简单的解释方式是:我需要一份学生及其主要活动的清单。学生被包含在一个表中,但问题是他们所参与的活动是通过其他表引用的,而这些表之间只有粗略的关系。每个建筑都有(2)个自定义字段信息表。“XX_CUSTOMFIELDNAMES”包含自定义字段的名称,“XX_CUSTOMFIELDVALUES”包含相关值。在本例中,自定
======================================
| STUDENTS |
======================================
| studentID | studentName | building |
--------------------------------------
| 101 | Bob | HS |
| 102 | Amy | MS |
| 103 | Jim | ES |
| 104 | Andy | HS |
--------------------------------------
======================= ====================================
| HS_CUSTOMFIELDNAMES | | HS_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 48 | Activity | | 48 | 101 | Football |
| 49 | Health | | 49 | 101 | Asthma |
----------------------- ------------------------------------
======================= ====================================
| MS_CUSTOMFIELDNAMES | | MS_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 44 | Activity | | 44 | 102 | Track |
----------------------- ------------------------------------
======================= ====================================
| ES_CUSTOMFIELDNAMES | | ES_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 43 | Activity | | 43 | 103 | Band |
| 42 | Teacher | | 42 | 103 | Mr. Smith |
----------------------- ------------------------------------
==================================================
| studentID | studentName | building | Activity |
--------------------------------------------------
| 101 | Bob | HS | Asthma |
| 101 | Bob | HS | Football |
| 102 | Amy | MS | Track |
| 103 | Jim | ES | Band |
| 103 | Jim | ES | Mr. Smith |
| 104 | Andy | HS | |
--------------------------------------------------
=================================================
| studentID | studentName | building | activity |
-------------------------------------------------
| 101 | Bob | HS | Football |
| 102 | Amy | MS | Track |
| 103 | Jim | ES | Band |
| 104 | Andy | HS | |
-------------------------------------------------
一个例子:
======================================
| STUDENTS |
======================================
| studentID | studentName | building |
--------------------------------------
| 101 | Bob | HS |
| 102 | Amy | MS |
| 103 | Jim | ES |
| 104 | Andy | HS |
--------------------------------------
======================= ====================================
| HS_CUSTOMFIELDNAMES | | HS_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 48 | Activity | | 48 | 101 | Football |
| 49 | Health | | 49 | 101 | Asthma |
----------------------- ------------------------------------
======================= ====================================
| MS_CUSTOMFIELDNAMES | | MS_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 44 | Activity | | 44 | 102 | Track |
----------------------- ------------------------------------
======================= ====================================
| ES_CUSTOMFIELDNAMES | | ES_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 43 | Activity | | 43 | 103 | Band |
| 42 | Teacher | | 42 | 103 | Mr. Smith |
----------------------- ------------------------------------
==================================================
| studentID | studentName | building | Activity |
--------------------------------------------------
| 101 | Bob | HS | Asthma |
| 101 | Bob | HS | Football |
| 102 | Amy | MS | Track |
| 103 | Jim | ES | Band |
| 103 | Jim | ES | Mr. Smith |
| 104 | Andy | HS | |
--------------------------------------------------
=================================================
| studentID | studentName | building | activity |
-------------------------------------------------
| 101 | Bob | HS | Football |
| 102 | Amy | MS | Track |
| 103 | Jim | ES | Band |
| 104 | Andy | HS | |
-------------------------------------------------
要确定Bob参加了哪项活动,我们必须查看他的建筑HS
和学生ID101
。由于他的建筑是HS
,我们必须查看HS-CUSTOMFIELDNAMES
表以找到字段名活动
,并获取48
的fieldID
。然后,我们必须查看HS_CUSTOMFIELDVALUES
表,找到48
的fieldID
和Bob的学生ID101
。然后我们可以看到鲍勃在踢足球,他的健康状况值为哮喘。但是,我们只想查询活动
或缺少活动
我有一个查询,它没有得到空的activity值,也没有像您看到的那样合并“activity”字段(因为否则我会得到一个“不明确的列名”错误)。此外,我跳过了“ES”构建,以缩短此处的查询
SELECT
s.studentID, s.studentName, s.building, COALESCE(HS.fieldvalue, MS.fieldvalue, ES.fieldvalue) AS 'Activity'
FROM
students s
LEFT JOIN
HS_CUSTOMFIELDVALUES HS
ON
s.studentID = HS.studentID
LEFT JOIN
HS_CUSTOMFIELDNAMES AS HSF
ON HSF.fieldID = HS.fieldID AND HSF.fieldname = 'Activity'
LEFT JOIN
MS_CUSTOMFIELDVALUES MS
ON
s.studentID = MS.studentID
LEFT JOIN
MS_CUSTOMFIELDNAMES AS MSF
ON MSF.fieldID = MS.fieldID AND MSF.fieldname = 'Activity'
LEFT JOIN
ES_CUSTOMFIELDVALUES ES
ON
s.studentID = ES.studentID
LEFT JOIN
ES_CUSTOMFIELDNAMES AS ESF
ON ESF.fieldID = ES.fieldID AND ESF.fieldname = 'Activity'
实际查询结果:
======================================
| STUDENTS |
======================================
| studentID | studentName | building |
--------------------------------------
| 101 | Bob | HS |
| 102 | Amy | MS |
| 103 | Jim | ES |
| 104 | Andy | HS |
--------------------------------------
======================= ====================================
| HS_CUSTOMFIELDNAMES | | HS_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 48 | Activity | | 48 | 101 | Football |
| 49 | Health | | 49 | 101 | Asthma |
----------------------- ------------------------------------
======================= ====================================
| MS_CUSTOMFIELDNAMES | | MS_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 44 | Activity | | 44 | 102 | Track |
----------------------- ------------------------------------
======================= ====================================
| ES_CUSTOMFIELDNAMES | | ES_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 43 | Activity | | 43 | 103 | Band |
| 42 | Teacher | | 42 | 103 | Mr. Smith |
----------------------- ------------------------------------
==================================================
| studentID | studentName | building | Activity |
--------------------------------------------------
| 101 | Bob | HS | Asthma |
| 101 | Bob | HS | Football |
| 102 | Amy | MS | Track |
| 103 | Jim | ES | Band |
| 103 | Jim | ES | Mr. Smith |
| 104 | Andy | HS | |
--------------------------------------------------
=================================================
| studentID | studentName | building | activity |
-------------------------------------------------
| 101 | Bob | HS | Football |
| 102 | Amy | MS | Track |
| 103 | Jim | ES | Band |
| 104 | Andy | HS | |
-------------------------------------------------
由于第一条和第五条记录都不是活动
,因此我不需要返回这些结果,因此输出如下所示:
所需的查询结果:
======================================
| STUDENTS |
======================================
| studentID | studentName | building |
--------------------------------------
| 101 | Bob | HS |
| 102 | Amy | MS |
| 103 | Jim | ES |
| 104 | Andy | HS |
--------------------------------------
======================= ====================================
| HS_CUSTOMFIELDNAMES | | HS_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 48 | Activity | | 48 | 101 | Football |
| 49 | Health | | 49 | 101 | Asthma |
----------------------- ------------------------------------
======================= ====================================
| MS_CUSTOMFIELDNAMES | | MS_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 44 | Activity | | 44 | 102 | Track |
----------------------- ------------------------------------
======================= ====================================
| ES_CUSTOMFIELDNAMES | | ES_CUSTOMFIELDVALUES |
======================= ====================================
| fieldID | fieldname | | fieldID | studentID | fieldvalue |
----------------------- ------------------------------------
| 43 | Activity | | 43 | 103 | Band |
| 42 | Teacher | | 42 | 103 | Mr. Smith |
----------------------- ------------------------------------
==================================================
| studentID | studentName | building | Activity |
--------------------------------------------------
| 101 | Bob | HS | Asthma |
| 101 | Bob | HS | Football |
| 102 | Amy | MS | Track |
| 103 | Jim | ES | Band |
| 103 | Jim | ES | Mr. Smith |
| 104 | Andy | HS | |
--------------------------------------------------
=================================================
| studentID | studentName | building | activity |
-------------------------------------------------
| 101 | Bob | HS | Football |
| 102 | Amy | MS | Track |
| 103 | Jim | ES | Band |
| 104 | Andy | HS | |
-------------------------------------------------
SQL Fiddle:
提前谢谢 使用子查询仅从每对表中获取活动。然后
LEFT JOIN
将这些查询与students
表进行连接,并使用COALESCE()
指定优先级
SELECT
s.studentID, s.studentName, s.building, COALESCE(HS.fieldvalue, MS.fieldvalue, ES.fieldvalue) AS 'Activity'
FROM
students s
LEFT JOIN
(SELECT HS.studentID, HS.fieldvalue
FROM
HS_CUSTOMFIELDVALUES HS
JOIN
HS_CUSTOMFIELDNAMES AS HSF
ON HSF.fieldID = HS.fieldID
WHERE HSF.fieldname = 'Activity') AS HS
ON S.studentID = HS.studentID
LEFT JOIN
(SELECT MS.studentID, MS.fieldvalue
FROM
MS_CUSTOMFIELDVALUES MS
JOIN
MS_CUSTOMFIELDNAMES AS MSF
ON MSF.fieldID = MS.fieldID
WHERE MSF.fieldname = 'Activity') AS MS
ON S.studentID = MS.studentID
LEFT JOIN
(SELECT ES.studentID, ES.fieldvalue
FROM
ES_CUSTOMFIELDVALUES ES
JOIN
ES_CUSTOMFIELDNAMES AS ESF
ON ESF.fieldID = ES.fieldID
WHERE ESF.fieldname = 'Activity') AS ES
ON S.studentID = ES.studentID
啊,多么可怕的设计啊。动态信息不应该在表名中,而应该在表数据中。当您“简化”时,如果您不更改查询中使用的所有表名和列名,那就太好了。对不起,我修复了“简化”查询以反映示例表而不是真实世界。谢谢。这非常接近,但我没有得到
活动为NULL
的结果(请参见示例中的“Andy”),它仍然将最终结果中的活动列拆分为两个不同的列(即使它们具有相同的'Activity'名称)。我使用合并()
谢谢,COALESCE可以工作。关于确保在活动为空的情况下获得结果的适当方法,有什么想法吗(请参见示例中的“Andy”)我已经更新了答案。将字段名检查移到ON
子句中。感谢您迄今为止的帮助。我还存在的问题是,我正在获取其他自定义字段的结果,这些自定义字段不是活动
。我根据您上次的编辑更新了上面的问题,并将SQL查询放在那里,以创建示例数据,如果这有帮助的话澄清问题。再次感谢你,比姆斯。