SQL条件语句

时间:2017-05-30 15:06:15

标签: postgresql

我试图从trans_type ='RM'的表中获取所有记录但是如果没有trans_type ='RM'我想要返回trans_type ='AD'的所有记录

技术上我在PostgreSQL服务器上使用xtupls MetaSQL所以使用任何一个的解决方案很棒我可以上传我的metaSQL语句需要但我真的只需要一种方法

-- Group: lotserial 
-- Name: detail
-- Notes: 
-- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/EULA for the full text of the software license.

SELECT ls_number,
   ls_notes, 
   formatlotserialnumberbarcode(ls_number) AS lotserial_barcode,
   item_number, 
   item_descrip1, 
   item_descrip2,
   charass_char_id,
   charass_value,
   poitem_id,
   poitem_vend_item_descrip,
   char_name, 
   formatqty(itemloc_qty) as lotqty,
   lshist.*
FROM   
   itemloc, 
   ls
   JOIN item ON (item_id=ls_item_id)
   LEFT JOIN charass ON (charass_target_id=ls_id)
   LEFT JOIN "char" ON (char_id=charass_char_id),
   lshist (<? value("itemid") ?>,<? value("warehouseid") ?>,ls_number,
           <? value("pattern") ?>,<? value("transType") ?>,<? value("startDate") ?>,
           <? value("endDate") ?>,<? value("trace") ?>,1)


     LEFT JOIN pohead ON(pohead_number=(TRIM(SUBSTRING(lshist_ordernumber FROM '-.*-'),'-')))

     LEFT JOIN poitem ON(poitem_pohead_id=pohead_id)

   <? if exists('ls_id') ?>
   WHERE ls_id=<? value("ls_id") ?>
   <? endif ?>
   <? if exists('ls_number') ?>
   WHERE ls_number=<? value("ls_number") ?>
   <? endif ?>


   AND lshist_warehous_code='PS'

   <? if exists(TRIM(SUBSTRING(lshist_ordernumber FROM '.*-'),'-')='PO')?>
   AND poitem_linenumber = CAST(TRIM(SUBSTRING(lshist_ordernumber FROM '[^-]*$'),'-') AS INTEGER)
   <? endif ?>

   AND ls_id = itemloc_ls_id
   AND charass_target_type = 'LS'


 /*
   <? if exists(lshist_transtype='RM')?>
   AND lshist_transtype='RM'
   <? elseif exists(lshist_transtype='AD')?>
   AND lshist_transtype='AD'
   <? elseif exists(lshist_transtype='RL')?>
   AND lshist_transtype='RL' 
   <? elseif exists(lshist_transtype='SH')?>
   AND lshist_transtype='SH'  
   <? elseif exists(lshist_transtype='IM')?>
   AND lshist_transtype='IM'
    <? elseif exists(lshist_transtype='TR')?>
   AND lshist_transtype='TR'
   <? elseif exists(lshist_transtype='RP')?>
   AND lshist_transtype='RP' 
   <? endif ?>

2 个答案:

答案 0 :(得分:3)

您可以使用公用表表达式:

WITH rm AS (
  SELECT * FROM my_table WHERE trans_type = 'RM'
)
SELECT *
FROM data
UNION ALL
SELECT * FROM my_table
WHERE trans_type = 'AD'
AND NOT EXISTS (
  SELECT * FROM rm
)

这将避免在EXPLAIN ANALYZE调用中看到的第二次扫描,但与在客户端做出决策相比,仍然有一点开销,可能是由于CTE实现(这是PostgreSQL特有)。

I've benchmarked this for an small data set. There seems to be a 5% - 10% overhead in PostgreSQL over running two queries from pgplsql.因此,在大多数情况下,对于像这样的简单查询,Laurenz's solution是首选。

可能有更复杂的查询设置,其中单个查询更适合两个单独的查询,因为单个查询可以重复使用中间结果。

答案 1 :(得分:1)

我只会运行两个查询,第一个使用WHERE trans_type='RM',如果第一个查询返回空结果,则仅使用WHERE trans_type='AD'运行第二个查询。

我认为试图将其压缩成单个查询会使事情变得过于复杂,而且可能也不会更快 - 我想不出可以避免第二次扫描的方法。