好的,所以我一直在研究这个查询,我很确定必须有一个更好的方法,而不是我当前的方法,它是在语句之后嵌套语句。
这是我的两个主要表格(快速重写,因此它们可能不是完美的'创建表'代码)
CREATE TABLE `person` (
`personid` INT PRIMARY KEY AUTO_INCREMENT,
`personuuid` VARCHAR(64),
`flags` INT,
`last_updated` DATETIME,
`first_name` VARCHAR(64),
`last_name` VARCHAR(64)
);
CREATE TABLE `person_status` (
`person_statusid` INT PRIMARY KEY AUTO_INCREMENT,
`person_statusesid` INT,
`personuuid` VARCHAR(64),
`groupsuuid` VARCHAR(64),
`start_date` DATE
);
简要说明:正如您所看到的,个人可能(可能)具有多种状态。最新状态由开始日期(具有最大开始日期)确定。每个人还可能在人员表中有多个条目。 (帮助跟踪更新用户信息)最新信息将是具有最新last_updated值的信息。
我正在尝试做什么:我正在尝试获取所有人(也称为personuuid)的列表,以便:
这是我正在运行的查询:
SELECT personuuid FROM (
SELECT personuuid, flags FROM (
SELECT DISTINCT personuuid, flags
FROM person
JOIN (
SELECT personuuid, t2.person_statusesid FROM (
SELECT personuuid, groupsuuid, t1.person_statusesid FROM (
SELECT personuuid, groupsuuid, p1.person_statusesid
FROM person_status as p1
ORDER BY start_date DESC, person_statusid DESC
) as t1
GROUP BY personuuid, groupsuuid
) as t2
WHERE groupsuuid='xxxxxxxxxx' AND person_statusesid = X
) AS t3 USING (personuuid)
WHERE (first_name LIKE '%TEST%' OR last_name LIKE '%TEST%')
ORDER BY person_statusesid, last_name, first_name, last_updated DESC
) as t4
GROUP BY personuuid
) as t5
WHERE flags <> 2;
正如您所看到的,我正在使用一个表来命名人状态,然后按group和statusesid进行过滤。然后我拿两个连接的表,按名称过滤,然后我试图抓住最近的人行并确保它有正确的标志。
我认为,因为这看起来像一个有趣的谜题,我想请你们看看有人能想出一个像样的解决方案。我不是这些东西中最专家的所以我只知道更多基本的SQl命令,所以任何建议都是有益的。谢谢=)
答案 0 :(得分:0)
我会通过在一个地方汇集我需要的数据来解决这个问题。也就是说,最近的状态记录和最近的人员记录。这需要查找两个表的最新更新日期,然后将各种表和子查询连接在一起:
select ps.*, p.*
from person_status ps join
(select personuuid, max(last_updated) as maxlu
from person_status ps
group by person_status
) psm
on psm.personuuid = psm.personuuid and psm.maxlu = ps.last_updated join
(select personuuid, max(last_updated) as maxlu
from person p
group by personuuid
) pm
on pm.personuuid = ps.personuuid join
person p
on pm.personuuid = p.personuuid and pm.maxlu = p.lastupdated
where p.flags = 0 and
ps.groupsuuid in (<list of groups>) and
additional filtering;
如果您要为记录设置一个带有“生效日期”(lastupdated
)的数据结构,您应该考虑使用“结束日期”。这在更新中需要更多工作(通常需要一个触发器),但它会使这样的查询变得更加容易。
编辑:
您的原始查询中包含相当数量的子查询。在任何情况下,您都可以在没有子查询的情况下重写它以简化问题。对于以下内容,性能需要personuuid, lastupdated
(对于两个表)的索引。
select ps.*, p.*
from person_status ps join
person p
on ps.personuuid = p.personuuid and
p.lastupdated = (select p2.lastupdated
from person p2
where p2.personuuid = p.personuuid
order by p2.lastupdated desc
limit 1
) and
ps.lastupdated = (select ps2.lastupdated
from person_status ps2
where ps2.personuuid = ps.personuuid
order by ps2.lastupdated desc
limit 1
)
where p.flags = 0 and
ps.groupsuuid in (<list of groups>) and
additional filtering;
在此版本中,子查询是相关的,并将转换为索引查找。