如何在SELECT查询中“默认”一列

时间:2009-12-04 04:58:34

标签: sql select db2 query-optimization

假设我有一个包含4个字段A,B,C和D的数据库表T.A,B和C是主键。对于[A,B]的任何组合,总有一行C == spacesC != spaces可能有也可能没有其他行。我有一个查询可以获取所有行[A, B] == [in_a, in_b],以及C == in_c如果存在这样的行,或C == spaces如果in_c行不存在。所以,如果有一行匹配特定的C值,我想要那个,否则我想要一个空格。非常重要的是,如果存在匹配的C行,则不会返回空格。

我有一个有效的查询,但速度不是很快。这是在DB2 for z / OS上执行的。我可以完全控制这些表,因此我可以根据需要定义新的指​​标。现在表上唯一的索引是主键[A, B, C]。这个SQL有点混乱,我觉得这是完成这个任务的更好方法。我该怎么做才能使这个查询更快?

我现在的查询是:

SELECT A, B, C, D FROM T
WHERE A = :IN_A AND B > :IN_B AND
       (C = :IN_C 
        OR (NOT EXISTS(
            SELECT B FROM T WHERE 
              A = :IN_A AND B > :IN_B AND C = :IN_C)) 
            AND C = " ");

3 个答案:

答案 0 :(得分:1)

Caveat emptor ,因为我不熟悉DB2 SQL ...

您可以尝试使用ORDER BY子句对匹配的行进行排序,使得c = spaces的行在排序集中排在最后,然后只检索集合的第一行。类似的东西:

select first
    A, B, C, D
  from T
  where A = :IN_A
    and B = :IN_B
  order by C desc;

这假定FIRST和ORDER BY DESC条款按照我的期望行事。

答案 1 :(得分:0)

这将适用于DB2 LUW,不确定order by子句是否适用于DB2 Z:

select 
   a, b, c, d 
  from t 
 where a = :IN_A 
   and b = :IN_B 
   and c in (:IN_C,'  ') 
order by 
   case c when '  ' then 2 else 1 end 
fetch first 1 row only

确保''值与列的实际值匹配。

祝你好运,

答案 2 :(得分:0)

为什么不启动索引顾问并阅读其建议? (或者这只是在DB2 for i / OS上?)

我们在非常大的生产环境中使用顾问,并提供了很好的建议。但话虽如此,从一个好的陈述开始总是好的。