sql :多次查询同一列作为不同的列,每行返回多个值 1
sql : query same column multiple times AS different columns, with multiple values returned 1 per row
我需要构建一个结构如下的报告:
姓名,Field_1,Field_2,Field_3
吉姆,opt_1,是的,12
简,opt_2,n,64
等等
我正在从 Moodle 数据库表中提取数据,结构如下图所示。 mdl_user_info_data, mdl_user_info_field、mdl_user 与其他列有相同的列,我从中得到的只是名称,所以我懒得在这里包含它。那部分工作正常。
这是迄今为止我能想到的最好的,所以你可以看到表是如何连接的:
SELECT
CONCAT (u.firstname, u.lastname) Name,
(SELECT d.data FROM mdl_user_info_data d JOIN mdl_user_info_field f ON f.id = d.fieldid WHERE f.shortname = "Field_1" GROUP BY d.userid),
(SELECT d.data FROM mdl_user_info_data d JOIN mdl_user_info_field f ON f.id = d.fieldid WHERE f.shortname = "Field_2" GROUP BY d.userid),
(SELECT d.data FROM mdl_user_info_data d JOIN mdl_user_info_field f ON f.id = d.fieldid WHERE f.shortname = "Field_3" GROUP BY d.userid),
FROM mdl_user u
JOIN mdl_user_info_data d ON d.userid = u.id
JOIN mdl_user_info_field f ON d.fieldid = f.id
GROUP BY d.userid
ORDER BY `Name` ASC
我知道我的子查询树错了,但不确定用什么来代替 GROUP BY。我当前的查询将 return 每行中每个给定 Field_x 的所有值,当我需要 return 时,只需要与第 1 列中命名的用户相对应的值。
非常感谢任何帮助。
我对 moodle 或它的 sql 语法不太满意,但如果常见,您可能会通过多次对 table 进行左连接来获得您想要的结果,每次都有其标准资格,然后只需使用不同的 ALIAS 参考即可获得您的作品...
SELECT
CONCAT (u.firstname, u.lastname) Name,
dFld1.Data as Field1Data,
dFld2.Data as Field2Data,
dFld3.Data as Field3Data
FROM
mdl_user u
LEFT JOIN mdl_user_info_data dFld1
ON u.id = dFld1.userid
LEFT JOIN mdl_user_info_field fFld1
ON dFld1.fieldid = fFld1.id
AND fFld1.shortname = "Field_1"
LEFT JOIN mdl_user_info_data dFld2
ON u.id = dFld2.userid
LEFT JOIN mdl_user_info_field fFld2
ON dFld2.fieldid = fFld2.id
AND fFld2.shortname = "Field_2"
LEFT JOIN mdl_user_info_data dFld3
ON u.id = dFld3.userid
LEFT JOIN mdl_user_info_field fFld3
ON dFld3.fieldid = fFld3.id
AND fFld3.shortname = "Field_3"
ORDER BY
`Name` ASC
如果任何此类链接可能没有值,我将使用 LEFT-JOIN 进行此查询。
至于分组方式,仅当给定用户和字段 1、2 或 3 条目分别有一个或多个基础 tables 有多个条目时才需要这样做。
另一种解决方案。
SELECT u.id, u.firstname, u.lastname, f.fieldname1, f.fieldname2
FROM mdl_user u
JOIN (
SELECT d.userid,
MAX(CASE WHEN f.shortname = 'fieldname1' THEN d.data ELSE null END) AS fieldname1,
MAX(CASE WHEN f.shortname = 'fieldname2' THEN d.data ELSE null END) AS fieldname2
FROM mdl_user_info_field f
JOIN mdl_user_info_data d ON d.fieldid = f.id
WHERE f.shortname IN ('fieldname1', 'fieldname2')
GROUP BY d.userid) f ON f.userid = u.id
Concat 适用于 MySql,但您应该使用数据库兼容函数 - https://docs.moodle.org/dev/Data_manipulation_API#SQL_compatibility_functions
所以使用
的结果
$DB->sql_concat('u.firstname', 'u.lastname');
我需要构建一个结构如下的报告:
姓名,Field_1,Field_2,Field_3
吉姆,opt_1,是的,12
简,opt_2,n,64
等等
我正在从 Moodle 数据库表中提取数据,结构如下图所示。 mdl_user_info_data, mdl_user_info_field、mdl_user 与其他列有相同的列,我从中得到的只是名称,所以我懒得在这里包含它。那部分工作正常。
这是迄今为止我能想到的最好的,所以你可以看到表是如何连接的:
SELECT
CONCAT (u.firstname, u.lastname) Name,
(SELECT d.data FROM mdl_user_info_data d JOIN mdl_user_info_field f ON f.id = d.fieldid WHERE f.shortname = "Field_1" GROUP BY d.userid),
(SELECT d.data FROM mdl_user_info_data d JOIN mdl_user_info_field f ON f.id = d.fieldid WHERE f.shortname = "Field_2" GROUP BY d.userid),
(SELECT d.data FROM mdl_user_info_data d JOIN mdl_user_info_field f ON f.id = d.fieldid WHERE f.shortname = "Field_3" GROUP BY d.userid),
FROM mdl_user u
JOIN mdl_user_info_data d ON d.userid = u.id
JOIN mdl_user_info_field f ON d.fieldid = f.id
GROUP BY d.userid
ORDER BY `Name` ASC
我知道我的子查询树错了,但不确定用什么来代替 GROUP BY。我当前的查询将 return 每行中每个给定 Field_x 的所有值,当我需要 return 时,只需要与第 1 列中命名的用户相对应的值。
非常感谢任何帮助。
我对 moodle 或它的 sql 语法不太满意,但如果常见,您可能会通过多次对 table 进行左连接来获得您想要的结果,每次都有其标准资格,然后只需使用不同的 ALIAS 参考即可获得您的作品...
SELECT
CONCAT (u.firstname, u.lastname) Name,
dFld1.Data as Field1Data,
dFld2.Data as Field2Data,
dFld3.Data as Field3Data
FROM
mdl_user u
LEFT JOIN mdl_user_info_data dFld1
ON u.id = dFld1.userid
LEFT JOIN mdl_user_info_field fFld1
ON dFld1.fieldid = fFld1.id
AND fFld1.shortname = "Field_1"
LEFT JOIN mdl_user_info_data dFld2
ON u.id = dFld2.userid
LEFT JOIN mdl_user_info_field fFld2
ON dFld2.fieldid = fFld2.id
AND fFld2.shortname = "Field_2"
LEFT JOIN mdl_user_info_data dFld3
ON u.id = dFld3.userid
LEFT JOIN mdl_user_info_field fFld3
ON dFld3.fieldid = fFld3.id
AND fFld3.shortname = "Field_3"
ORDER BY
`Name` ASC
如果任何此类链接可能没有值,我将使用 LEFT-JOIN 进行此查询。
至于分组方式,仅当给定用户和字段 1、2 或 3 条目分别有一个或多个基础 tables 有多个条目时才需要这样做。
另一种解决方案。
SELECT u.id, u.firstname, u.lastname, f.fieldname1, f.fieldname2
FROM mdl_user u
JOIN (
SELECT d.userid,
MAX(CASE WHEN f.shortname = 'fieldname1' THEN d.data ELSE null END) AS fieldname1,
MAX(CASE WHEN f.shortname = 'fieldname2' THEN d.data ELSE null END) AS fieldname2
FROM mdl_user_info_field f
JOIN mdl_user_info_data d ON d.fieldid = f.id
WHERE f.shortname IN ('fieldname1', 'fieldname2')
GROUP BY d.userid) f ON f.userid = u.id
Concat 适用于 MySql,但您应该使用数据库兼容函数 - https://docs.moodle.org/dev/Data_manipulation_API#SQL_compatibility_functions
所以使用
的结果$DB->sql_concat('u.firstname', 'u.lastname');