如何改进此SQL查询?

时间:2008-10-29 19:13:47

标签: sql postgresql

我正在检查in_fmd中是否存在一行,而我查找的ISBN可以是ISBN参数,也可以是交叉数字表中可能有也可能没有行的其他ISBN。

select count(*)
from in_fmd i
where (description='GN')
    and ( i.isbn in
    (
        select bwi_isbn from bw_isbn where orig_isbn = ?
        union all
        select cast(? as varchar) as isbn
    )
) 

我实际上并不关心行的数量,而只是存在至少一行。

这曾经是三个单独的查询,我把它压成一个,但我认为还有进一步改进的余地。它是PostgreSQL 8.1,如果重要的话。

5 个答案:

答案 0 :(得分:4)

为什么要打扰UNION ALL

select count(*)
from in_fmd i
where (description='GN')
    and (
        i.isbn in (
            select bwi_isbn from bw_isbn where orig_isbn = ?
        )
        or i.isbn = cast(? as varchar)
    )

我可能会使用LEFT JOIN风格的查询而不是IN,但这更偏向个人:

select count(*)
from in_fmd i
left join bw_isbn
    on bw_isbn.bwi_isbn = i.isbn
    and bw_isbn.orig_isbn = ?
where (i.description='GN')
    and (
        bw_isbn.bwi_isbn is not null
        or i.isbn = cast(? as varchar)
    )

通过IM讨论的反演:

SELECT SUM(ct)
FROM (
    select count(*) as ct
    from in_fmd i
    inner join bw_isbn
        on bw_isbn.bwi_isbn = i.isbn
        and bw_isbn.orig_isbn = ?
        and i.isbn <> cast(? as varchar)
        and i.description = 'GN'

    UNION

    select count(*) as ct
    from in_fmd i
    where i.isbn = cast(? as varchar)
        and i.description = 'GN'
) AS x

答案 1 :(得分:1)

  

我实际上并不关心行的数量,而只是存在至少一行。

那么如何查询SELECT ... LIMIT 1并检查调用程序是否有一个结果行?

答案 2 :(得分:1)

SELECT SUM(ct)
FROM (select count(*) as ct
      from in_fmd i
      inner join bw_isbn
         on bw_isbn.bwi_isbn = i.isbn
        and bw_isbn.orig_isbn = ?
        and i.isbn <> cast(? as varchar)
        and i.description = 'GN'
      UNION
      select count(*) as ct
      from in_fmd i
      where i.isbn = cast(? as varchar)
        and i.description = 'GN'
     ) AS x

答案 3 :(得分:1)

除了其他海报所说的,只是改变

选择计数(*)

存在(..)

improve things相当多

答案 4 :(得分:0)

select count(*)
from in_fmd i
where description = 'GN'
  and exists (select 1 
              from bwi_isbn 
              where bw_isbn.bwi_isbn = in_fmd.isbn)