我试图从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 ?>
答案 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'
运行第二个查询。
我认为试图将其压缩成单个查询会使事情变得过于复杂,而且可能也不会更快 - 我想不出可以避免第二次扫描的方法。