我正在尝试编写一个查询,查找具有最新期间(年)的特定代码的人,但是如果他们有另一个具有该最新期间(年)的代码则不会。我会明确的,所以我的榜样是有道理的。
我希望拥有代码A1,A2,A3,A4,A5而不是AG,AP,AQ的人。有些人拥有一段时间的A1代码(如2014年)和同一时期的AG代码。我想排除它们。并非每个人都有代码,因此字段值可能为NULL
。
有没有办法以不同的方式表达这一点(即字符数量少)?
SELECT
people.firstName
FROM
people
WHERE EXISTS (
SELECT *
FROM codes
WHERE
codes.people_id = people.id
AND period = (SELECT MAX(period) FROM codes codes2 WHERE codes2.people_id = codes.people_id)
AND code LIKE 'A[1-5]'
)
AND NOT EXISTS (
SELECT *
FROM codes
WHERE
codes.people_id = people.id
AND period = (
SELECT MAX(period)
FROM codes codes2
WHERE codes2.people_id = codes.people_id
)
AND code LIKE 'A[GPQ]'
)
架构如下:
人
代码
答案 0 :(得分:0)
你有很多方法可以做到这一点,我不是SQL专家,但我不能看到你的查询太糟糕了,如果你想尝试减少你可以考虑使用的子查询的数量GROUP BY
clause以及SUM
中的Aggregate function HAVING
clause。
我开始按如下方式更新您的代码:
SELECT
people.firstName
FROM
people
LEFT JOIN codes AS a15 ON a15.people_id = people.id AND a15.code LIKE 'A[1-5]'
LEFT JOIN codes AS agpq ON agpq.people_id = people.id AND agpq.code LIKE 'A[GPQ]'
GROUP BY
people.firstName
HAVING
SUM(CASE WHEN a15.code IS NULL THEN 0 ELSE 1 END) > 0
AND SUM(CASE WHEN agpq.code IS NULL THEN 0 ELSE 1 END) = 0
然而,这并未考虑与描述的期间特定要求有关的任何事项。您可以将句点添加到GROUP BY
子句或将其添加到WHERE
或其中一个JOIN
约束中,但我不完全确定您的描述中确切的内容(我不相信这是通过你自己的任何错误,我只是不能亲自对齐提供给描述的代码)。
我还想指出,上面的SUM
函数无法准确计算匹配代码的数量。这是因为如果A[GPQ]
和A[1_5]
都返回至少一行,则每个约束返回的数字将乘以另一个约束返回的数字,但它可用于确定是否存在“任何“退回的项目,如果条件匹配,它将具有SUM(...) > 0
我确信一个更有经验的SQL Developer / DBA将能够在我提出的查询中挖出许多漏洞,但它可能会给他们或其他人一些工作,并希望能为您提供使用子查询的替代方案的想法。