CTE并加入2个查找表

时间:2014-11-12 20:32:29

标签: sql oracle oracle11g common-table-expression

我有两个CTE查询,我已经简化了,并且下面的一个选择语句希望加入两个查找表:

with salesCTE (itemCode, custCode, quantity) as (
    select
        itemCode as itemCode,
        customerCode as custCode,
        sum(quantity) as quantity
    from sales
    group by itemCode, customerCode
    order by 1
),
paymentsCTE (itemCode, custCode, quantity) as (
    select
        itemCode as itemCode,
        customerCode as custCode,
        sum(quantity) as quantity
    from payments
    group by itemCode, customerCode
    order by 1
)
select 
    il.itemCode as itemCode,
    il.itemName as itemName,
    cl.customerCode as customerCode,
    cl.customerName as customerName,
    sal.quantity as quantitySold,
    pay.quantity as quantityPaid,
    sal.quantity - pay.quantity as quantityBalance
from
--This is where I'm having issues

所以我尝试了各种条款,但我要么没有得到结果集,要么只是预期结果的一小部分。

我尝试过的最合乎逻辑的一点是没有工作(没有回复):

from items il
join salesCTE sal on il.itemCode = sal.itemCode
join paymentsCTE pay on il.itemCode = pay.itemCode
join customers cl on (cl.customerCode = sal.custCode OR cl.customerCode = pay.custCode)
where 0=0

我也尝试过:

from items il, customers cl, salesCTE sal, paymentsCTE pay
where 0=0
and (il.itemCode = sal.itemCode OR il.itemCode = pay.itemCode)
and (cl.customerCode = sal.custCode OR il.itemCode = pay.custCode)

我是否尝试使用此查询执行太多操作?

我还设置了一个带有一些虚拟数据的SQL小提琴:http://sqlfiddle.com/#!4/4de7b/7

以下是customerCode =' 102'

的预期结果
╔══════════╦══════════════╦══════════════╦══════════════╦══════╦══════╦═════════╗
║ ItemCode ║   ItemName   ║ CustomerCode ║ CustomerName ║ Sold ║ Paid ║ Balance ║
╠══════════╬══════════════╬══════════════╬══════════════╬══════╬══════╬═════════╣
║      903 ║ Cowl         ║          102 ║ Clark Kent   ║    0 ║    1 ║      -1 ║
║      900 ║ Web Shooters ║          102 ║ Clark Kent   ║    0 ║    3 ║      -3 ║
╚══════════╩══════════════╩══════════════╩══════════════╩══════╩══════╩═════════╝

这个想法是,如果在sales表中插入了一条记录,对于ItemCode 900,Sold将为1,余额为-2。

1 个答案:

答案 0 :(得分:1)

with salesCTE (itemCode, custCode, quantity) as (
    select
        itemCode as itemCode,
        customerCode as custCode,
        sum(quantity) as quantity
    from sales
    group by itemCode, customerCode
    order by 1
),
paymentsCTE (itemCode, custCode, quantity) as (
    select
        itemCode as itemCode,
        customerCode as custCode,
        sum(quantity) as quantity
    from payments
    group by itemCode, customerCode
    order by 1
)
select 
    il.itemCode as itemCode,
    il.itemName as itemName,
    cl.customerCode as customerCode,
    cl.customerName as customerName,
    sal.quantity as quantitySold,
    pay.quantity as quantityPaid,
    sal.quantity - pay.quantity as quantityBalance
from salesCTE sal 
     full outer join paymentsCTE pay on (sal.itemCode = pay.itemCode)
     join items il on nvl(sal.itemCode, pay.itemCode) = il.itemCode 
     join customers cl on (case when pay.itemCode is null then sal.custCode else pay.custCode end) = cl.customerCode;

据我了解,您希望获得有关商品付款和销售的信息。

在这种情况下,您需要完全加入销售和付款才能检索所有商品代码。

然后,您只需加入客户和商品即可获得更多信息(您需要通过付款或销售的列加入)。

P.S。您的小提琴数据有一个奇怪的事情 - 销售包含不在项目表中的项目代码。如果是这种情况你可以使用LEFT JOIN项而不是JOIN项(但这真的很奇怪)

更新:我认为您只是在插入小提琴中的销售时混淆了列值

另一种选择 - 如果您需要获取每个项目和客户的信息。

在这种情况下,您需要通过itemcode和custCode完全加入:

with salesCTE (itemCode, custCode, quantity) as (
    select
        itemCode as itemCode,
        customerCode as custCode,
        sum(quantity) as quantity
    from sales
    group by itemCode, customerCode
    order by 1
),
paymentsCTE (itemCode, custCode, quantity) as (
    select
        itemCode as itemCode,
        customerCode as custCode,
        sum(quantity) as quantity
    from payments
    group by itemCode, customerCode
    order by 1
)
select 
    il.itemCode as itemCode,
    il.itemName as itemName,
    cl.customerCode as customerCode,
    cl.customerName as customerName,
    nvl(sal.quantity, 0) as quantitySold,
    nvl(pay.quantity, 0) as quantityPaid,
    nvl(sal.quantity, 0) - nvl(pay.quantity, 0) as quantityBalance
from salesCTE sal 
     full outer join paymentsCTE pay on (sal.itemCode = pay.itemCode 
                                         and sal.custCode = pay.custCode)
     join items il on nvl(sal.itemCode, pay.itemCode) = il.itemCode 
     join customers cl on nvl(sal.custCode, pay.custCode) = cl.customerCode;