我有一个包含用户、文件和文件期限的 MySQL 表,如下所示。
用户 | 文件 | 文件年龄 |
---|---|---|
A | 1 | 42 |
A | 2 | 17 |
A | 3 | 4 |
B | 4 | 85 |
B | 5 | 73 |
B | 6 | 11 |
C | 7 | 6 |
C | 8 | 9 |
C | 9 | 3 |
现在我需要选择年龄大于10的特定用户的所有文件的名称。没有或只有一些年龄> 10的文件的用户将不会被选择。
按照上面的例子,结果应该是:
用户 | 文件 | 文件年龄 |
---|---|---|
B | 4 | 85 |
B | 5 | 73 |
B | 6 | 11 |
我假设 SQL ALL 运算符和子查询是我的朋友,但我在这里没有得到令人满意的结果。因此,很高兴听到一些想法。
非常感谢!
本
解决这个问题的方法有很多,其中有:
使用窗口聚合:
select users, files, file_age
from (
select *, Min(file_age) over(partition by Users) MinAge
from t
)t
where MinAge > 10;
在相关查询中使用聚合:
select *
from t
where exists (
select * from t t2
where t2.users = t.users
having Min(file_age) > 10
);
有多种选择。
一种可能性是
left join
,然后检查 null
:
SELECT t1.*
FROM mytable t1 LEFT OUTER JOIN mytable t2
ON t1.users = t2.users AND t2.fileage <= 10
WHERE t2.fileage IS NULL
另一种可能性是使用
not exists
:
SELECT *
FROM mytable t1
WHERE NOT EXISTS
(
SELECT *
FROM mytable t2
WHERE t1.users = t2.users AND t2.fileage <= 10
)
另一种可能性是使用
< ALL
(正如您在问题中提到的):
SELECT *
FROM mytable t1
WHERE 10 <= ALL
(
SELECT fileage
FROM mytable t2
WHERE t2.users = t1.users
)
你可以在这里看到一个小提琴。
我编辑了我的答案,使用
<=
而不是仅仅 <
,因为我的边界条件错误。