我有三个表:
1.table person
id, others
1, x
2, y
3, z
4, w
2表跟踪,外键(person_id
)参考person
(id
)
id, person_id, ftime, details
1, 1, '2018-01-12', 'json_1'
2, 1, '2018-04-21', 'json_2'
3, 2, '2017-12-16', 'json_3'
4, 2, '2018-01-17', NULL
5, 3, '2018-06-02', 'json_5'
6, 4, '2018-01-19', NULL
3.table followup_track,外键(fid
)参考followup
(id
)
id, fid, ftime, details
1, 1, '2018-01-27', 't_json_1'
2, 2, '2018-05-07', 't_json_2'
3, 5, '2018-06-17', 't_json_3'
现在,我想查找每个人的所有最后一次ftime,并且在跟踪和/或跟踪跟踪中,详细信息不为空。
我想要得到的结果是(这里的pid是人的身份证):
pid, ftime, details
1, '2018-05-07', 't_json_2'
2, '2017-12-16', 'json_3'
3, '2018-06-17', 't_json_3'
因为person.id = 4没有detalis!= NULL,所以结果不需要pid = 4。
由于person.id = 1的最后一次是'2018-05-07',因此需要该列。
我创建一个像这样的视图
CREATE VIEW view_full_flup AS
SELECT
p.id AS pid, fp.ftime, fp.details
FROM
((followup_track fp
LEFT JOIN followup ON (fp.fid = followup.id))
LEFT JOIN person p ON (followup.person_id = p.id))
WHERE
fp.details IS NOT NULL
UNION
SELECT
f.person_id AS pid, f.ftime, f.details
FROM
followup f
WHERE
f.details IS NOT NULL
然后,我使用sql:
SELECT *, MAX(`ftime`) FROM view_full_flup GROUP BY pid;
我的解决方案对吗?详细信息无法建立索引,而且速度很慢。请问如何正确执行此操作?
答案 0 :(得分:0)
您不能选择star group by(嗯,您可能可以在MySQL中进行选择,具体取决于它的设置方式,但是要掌握sql技能的可移植性不是一个好习惯),必须指定一个列表您选择的列进行分组,或者将它们分组(在分组中放入列名称),或者对它们进行汇总(将列名称传递到聚合函数中)
感觉您的左联接逻辑倒退了-person是您知道记录所在的唯一表,因此它应该在联接的左侧。其他表可能是无记录的
这是我的查询,我会写得更像是:
select
Pid,
Max(case when ft.ftime > f.ftime then ft.ftime else f.ftime end) maxft
From
Person p
Left join (select * from followup where details is not null) f on f.person_id = p.id
Left join (select * from follup_track where details is not null) ft on ft.fid = f.id
Group by pid
我们只连接了一组表,已经过滤掉了其中任一表的详细信息的记录,然后从任一表中获取了最大日期
请注意,如果您有记录(即使填写了详细信息),但date列为null,则此查询可以返回空日期。如果不希望有这些记录,则用HAVING过滤下摆或将整个内容包装在另一个select中,然后使用一个地方
Ps;从目前的情况来看,该查询似乎并不是特别有用,因为尽管您知道最近的日期,但是您没有任何其他数据。如果只是您想知道的全部(我无法从您的原始帖子中得知,因为描述和查询在他们所说的内容上是不同的),那么很好,但是如果您想要其他信息,也许使用mysql 8的新分析查询更适合:
Select * from
(
select
Pid,
Row_number over(partition by pid order by (case when ft.ftime > f.ftime then ft.ftime else f.ftime end) desc) rown
From
Person p
Left join (select * from followup where details is not null) f on f.person_id = p.id
Left join (select * from follup_track where details is not null) ft on ft.fid = f.id
) a where rown = 1