我在SQL中有一个表格结构如下:
Name Value1 Value2
A .2 .3
A .1 .05
A .5 .3
B .2 .4
B .1 .08
C .3 .4
C .2 .5
C .1 .3
对于与名称关联的每一行,如何获取Value1小于Value2的所有名称?在上面的示例中,我只想提取名称C.
我读过这篇文章:Select in MySQL where all rows meet a condition
但我不认为这适用于我的问题,因为此解决方案假设您正在将行与固定值进行比较。
答案 0 :(得分:3)
其他一些答案的变体,也使用条件聚合:
SELECT Name
FROM yourTable
GROUP BY Name
HAVING SUM(CASE WHEN value1 >= value2 THEN 1 ELSE 0 END) = 0;
上述查询断言每个匹配的名称组都没有value1
大于或等于value2
的任何记录。
答案 1 :(得分:1)
您可以使用group by
和having
:
select name
from t
group by name
having count(*) = sum(case when value1 < value2 then 1 else 0 end);
还有其他方法可以表达这一点,例如:
select distinct name
from t
where not exists (select 1 from t t2 where t2.name = t.name and t2.value2 >= t2.value1);
或者:
select name
from t
except
select name
from t
where value2 >= value1;
答案 2 :(得分:0)
您可以使用EXIST
检查该值是否存在于您所需的条件中,其中按特定名称的所有行的值都大于value1。
SELECT *
FROM TableName a
WHERE EXISTS (SELECT 1
FROM TableName b
WHERE a.name = b.Name
GROUP BY b.name
HAVING COUNT(case when b.value1 < b.value2 THEN 1 END) = COUNT(*))
这是Demo。
这将显示有效name
的所有行。但是,如果您只想显示不同的name
,请检查其他答案。
答案 3 :(得分:0)
您可以使用in
子句
declare @table table (name varchar(10), value1 float, value2 float)
insert @table
select 'A', '0.2', '.3'
union all
select 'A' , '.1', '.05'
union all
select 'A', '.5', '.3'
union all
select 'B', '.2', '.4'
union all
select 'B', '.1' , '.08'
union all
select 'C', '.3' , '.4'
union all
select 'C', '.2' , '.5'
union all
select 'C' , '.1' , '.3'
使用value1<value2
select * from @table where value1<value2
and name not in ( select name from @table where value1>value2)