减少结果列表 (SQL)
Reducing the list of results (SQL)
我从 2 天起就坚持 SQL 声明,我希望你能帮助我。
我的 select 的结果是一个包含 4 个属性 A、B、C 和 D 的列表(下面是 5 个数据集的示例列表):
1. A=1 B=100 C=200 D=300
2. A=2 B=200 C=100 D=300
3. A=3 B=300 C=200 D=100
4. A=3 B=100 C=100 D=200
5. A=3 B=300 C=100 D=200
列表应该被缩减,这样每个属性 A
在列表中只出现一次。
在上面的示例中,数据集 1. 和 2. 应该在列表中,因为 A=1
和 A=2
只存在一次。
对于 A=3
,我必须构建一个查询来识别数据集,该数据集将出现在最终列表中。应适用一些规则:
- 取最高值为
B
的数据集;如果不明显那么
- 取最高值为
C
的数据集;如果不明显那么
- 取
D
最高值的数据集。
在上面的示例中,应该采用数据集 3。
预期结果是:
1.A=1 B=100 C=200 D=300
2.A=2 B=200 C=100 D=300
3.A=3 B=300 C=200 D=100
希望您能理解我的问题。我用 HAVING
和 EXISTS
(或 NOT EXISTS
)尝试了各种版本的 SELECT
-statements,但我的 SQL 知识还不够。
SELECT A, MAX(B) AS B, MAX(C) AS C, MAX(D) AS D
FROM table_name
GROUP BY A
这种类型的优先级查询最容易用 row_number()
完成,但我认为 Informix 不支持它。
因此,一种方法是使用相关子查询枚举行:
select t.*
from (select t.*,
(select count(*)
from t t2
where (t2.b > t.b) or
(t2.b = t.b and t2.c > t.c) or
(t2.b = t.b and t2.c = t.c and t2.d > t.d)
) as NumGreater
from t
) t
where NumGreater = 0;
我不知道 Informix
但你可以试试。这适用于 Sql Server
。可能它也适用于 Informix
:
select * from tablename t1
where id = (select first 1 id from tablename t2
where t2.A = t1.A order by B desc, C desc, D desc)
可能有更简单的方法来解决这个问题,但这个方法有效:
CREATE TEMP TABLE TEST (
A INTEGER,
B INTEGER,
C INTEGER,
D INTEGER
);
insert into TEST values (1,1,1,1);
insert into TEST values (2,1,5,1);
insert into TEST values (2,2,1,1);
insert into TEST values (3,1,4,1);
insert into TEST values (3,2,1,4);
insert into TEST values (3,2,3,1);
insert into TEST values (3,3,1,5);
insert into TEST values (3,3,2,3);
insert into TEST values (3,3,2,7);
insert into TEST values (3,3,3,1);
insert into TEST values (3,3,3,2);
select distinct
t1.A,
t2.B as B,
t3.C as C,
t4.D as D
from TEST t1
join (select A ,MAX (B) as B from TEST group by A)t2 on t2.A=t1.A
join (select A, B, MAX(C) as C from TEST group by A,B)t3 on t3.A=t2.A and t3.B=t2.B
join (select A, B, C, MAX (D) as D from TEST group by A,B,C)t4 on t4.A=t3.A and t4.B=t3.B and t4.C=t3.C;
结果:
a b c d
1 1 1 1
2 2 1 1
3 3 3 2
在 IBM Informix Dynamic Server 版本 11.10.FC3 上测试。
我从 2 天起就坚持 SQL 声明,我希望你能帮助我。
我的 select 的结果是一个包含 4 个属性 A、B、C 和 D 的列表(下面是 5 个数据集的示例列表):
1. A=1 B=100 C=200 D=300
2. A=2 B=200 C=100 D=300
3. A=3 B=300 C=200 D=100
4. A=3 B=100 C=100 D=200
5. A=3 B=300 C=100 D=200
列表应该被缩减,这样每个属性 A
在列表中只出现一次。
在上面的示例中,数据集 1. 和 2. 应该在列表中,因为 A=1
和 A=2
只存在一次。
对于 A=3
,我必须构建一个查询来识别数据集,该数据集将出现在最终列表中。应适用一些规则:
- 取最高值为
B
的数据集;如果不明显那么 - 取最高值为
C
的数据集;如果不明显那么 - 取
D
最高值的数据集。
在上面的示例中,应该采用数据集 3。
预期结果是:
1.A=1 B=100 C=200 D=300
2.A=2 B=200 C=100 D=300
3.A=3 B=300 C=200 D=100
希望您能理解我的问题。我用 HAVING
和 EXISTS
(或 NOT EXISTS
)尝试了各种版本的 SELECT
-statements,但我的 SQL 知识还不够。
SELECT A, MAX(B) AS B, MAX(C) AS C, MAX(D) AS D
FROM table_name
GROUP BY A
这种类型的优先级查询最容易用 row_number()
完成,但我认为 Informix 不支持它。
因此,一种方法是使用相关子查询枚举行:
select t.*
from (select t.*,
(select count(*)
from t t2
where (t2.b > t.b) or
(t2.b = t.b and t2.c > t.c) or
(t2.b = t.b and t2.c = t.c and t2.d > t.d)
) as NumGreater
from t
) t
where NumGreater = 0;
我不知道 Informix
但你可以试试。这适用于 Sql Server
。可能它也适用于 Informix
:
select * from tablename t1
where id = (select first 1 id from tablename t2
where t2.A = t1.A order by B desc, C desc, D desc)
可能有更简单的方法来解决这个问题,但这个方法有效:
CREATE TEMP TABLE TEST (
A INTEGER,
B INTEGER,
C INTEGER,
D INTEGER
);
insert into TEST values (1,1,1,1);
insert into TEST values (2,1,5,1);
insert into TEST values (2,2,1,1);
insert into TEST values (3,1,4,1);
insert into TEST values (3,2,1,4);
insert into TEST values (3,2,3,1);
insert into TEST values (3,3,1,5);
insert into TEST values (3,3,2,3);
insert into TEST values (3,3,2,7);
insert into TEST values (3,3,3,1);
insert into TEST values (3,3,3,2);
select distinct
t1.A,
t2.B as B,
t3.C as C,
t4.D as D
from TEST t1
join (select A ,MAX (B) as B from TEST group by A)t2 on t2.A=t1.A
join (select A, B, MAX(C) as C from TEST group by A,B)t3 on t3.A=t2.A and t3.B=t2.B
join (select A, B, C, MAX (D) as D from TEST group by A,B,C)t4 on t4.A=t3.A and t4.B=t3.B and t4.C=t3.C;
结果:
a b c d
1 1 1 1
2 2 1 1
3 3 3 2
在 IBM Informix Dynamic Server 版本 11.10.FC3 上测试。