sql:查询同一列多次AS不同的列,每行返回多个值1

时间:2016-04-12 16:59:20

标签: sql moodle

我需要构建一个结构如下的报告:

名称,Field_1,Field_2,Field_3

Jim,opt_1,y,12

Jane,opt_2,n,64

诸如此类

我从Moodle数据库表中提取,结构如下图所示。 mdl_user_info_datamdl_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。当我需要返回与第1列中指定的用户相对应的值时,我当前的查询将返回每行中每个给定Field_x的所有值。

任何帮助都非常感激。

2 个答案:

答案 0 :(得分:1)

我对moodle或它的sql语法不是肯定的,但是如果常见的话,你可以通过多次对表进行左连接来获得你想要的东西,每个都有它的标准限定,然后只使用不同的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进行此查询。

对于group by,仅当给定用户的一个或多个基础表有多个条目以及分别为1,2或3个字段时,才需要这样做。

答案 1 :(得分:0)

另一种解决方案。

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');