无论如何都有' compact' SQL查询的结果?
结果如下:
Project
.select("projects.*, max(project_reports.created_at) as latest_report")
.joins(:project_reports)
.order("latest_report desc")
.group("projects.id")
.preload(:project_reports)
.map { |p| "#{p.name}: #{p.latest_report_number}" }
但我希望它看起来像这样:
+----+-----------+----------+-----------+-------------+--------+
| ID | Firstname | Lastname | Hobby | Job | Age |
+----+-----------+----------+-----------+-------------+--------+
| 1 | John | Doe | (null) | (null) | 30 |
| 1 | John | Doe | Chess | (null) | (null) |
| 2 | Adam | Jackson | (null) | Accountant | (null) |
| 2 | Adam | Jackson | (null) | (null) | 55 |
| 3 | Michael | Smith | Knitting | (null) | (null) |
| 3 | Michael | Smith | (null) | Banker | (null) |
+----+-----------+----------+-----------+-------------+--------+
我尝试使用+----+-----------+----------+-----------+-------------+--------+
| ID | Firstname | Lastname | Hobby | Job | Age |
+----+-----------+----------+-----------+-------------+--------+
| 1 | John | Doe | Chess | (null) | 30 |
| 2 | Adam | Jackson | (null) | Accountant | 55 |
| 3 | Michael | Smith | Knitting | Banker | (null) |
+----+-----------+----------+-----------+-------------+--------+
,但它只接受数据库中每个人的第一个自定义字段。
我在这里设置了一个SQL小提琴:http://sqlfiddle.com/#!9/39563/2
设置有点奇怪,但由于我正在处理的数据库,我需要保留该结构。
答案 0 :(得分:2)
您可以使用max
聚合函数group by
来平整结果,如下所示:
select
p.id as "User ID",
p.firstname Firstname,
p.lastname as Lastname,
max(case when cf.fieldname = 'Hobby' then cfv.value end) as "Hobby",
max(case when cf.fieldname = 'Job' then cfv.value end) as "Job",
max(case when cf.fieldname = 'Age' then cfv.value end) as "Age"
from CustomFields cf
join CustomFieldValues cfv on cfv.fieldid = cf.id
join People p on cfv.relid = p.id
where cf.fieldname in ('Hobby', 'Job', 'Age')
group by p.id, p.firstname, p.lastname
order by p.id;
此外,字符串文字应包含在单引号中,您可以使用别名来减少查询文本并使其更具可读性。
答案 1 :(得分:0)
使用组中的group_concat函数作为字符串值的函数和数字字段的最大函数。
SELECT id, FirstName, LastName,
GROUP_CONCAT(CASE WHEN Hobby IS NOT NULL THEN Hobby END) AS Hobby,
GROUP_CONCAT(CASE WHEN Job IS NOT NULL THEN Job END AS Job,
MAX(Age) AS Age
FROM TableGROUP BY id
答案 2 :(得分:0)
您应该将MAX计算移动到派生表中,以便在加入之前应用聚合。这将提高性能:
select p.id as "User ID", p.firstname Firstname, p.lastname as Lastname,
cf.Hobby,
cf.Job,
cf.Age
from
(
select cfv.relid,
max(case when cf.fieldname = "Hobby" then cfv.value end) as "Hobby",
max(case when cf.fieldname = "Job" then cfv.value end) as "Job",
max(case when cf.fieldname = "Age" then cfv.value end) as "Age"
from CustomFields as cf inner join CustomFieldValues as cfv
on cfv.fieldid = cf.id
where cf.fieldname = "Hobby"
or cf.fieldname = "Job"
or cf.fieldname = "Age"
group by cfv.relid
/* -- apply additional conditions here, e.g. "all three fields must be set"
having Hobby is not null
and Job is not null
and age is not null
*/
) as cf
inner join People as p
on cf.relid = p.id
order by p.id