2

在将一些旧的 ASP 文件复制到一些较新的 .NET 2.0 代码中时,我遇到了一些问题。其中一项任务是将 4-5 条 SQL 语句合并为一条。虽然我已经做到了这一点并在性能提升方面取得了一些成功,但 Oracle 对我来说是一个新包。然而,这个问题超出了我自己的 SQL 技能,因为我以前没有这样做过。

基本上,我在一堆销售中的一张表中有一个 QUANTITY。每个销售都有一个整数值。每个销售还附有一个项目。每个项目都有一个转换因子,就像我卖 1 袋东西 = 10 捆东西一样。因此,当我运行报告并想找出最终价值时,我需要将每笔销售及其数量乘以它的转换因子。大多数都是简单的 1 对 1,所以它基本上是 25 * 1、30 * 1 等。

我的问题是我的记录中有过去的销售项目已从我们的系统中删除,因此不存在转换因素。这些记录从我的查询中删除,因为 FACTOR 消失了。

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code 
FROM salesdetails rth, salesheader rsh
WHERE rsh.number = rth.number(+)
AND rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rth.sale_code IN('ITEM07')
AND rth.c_code = 'WLMT'
AND rsh.year = '2008'

这是我的第一个查询。如果我将转换添加到:

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code, rth.quantity * cf.conversion
FROM salesdetails rth, salesheader rsh, conversionfactor cf
WHERE rsh.number = rth.number(+)
AND rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rth.sale_code IN('ITEM07')
AND rth.c_code = 'WLMT'
AND rsh.year = '2008'
AND cf.item_code = rth.item_code
and cf.code = '01'
and cf.loc_code = '00001'

这在一定程度上有效。它列出了所有相同的记录,但缺少任何不存在 CONVERSION 因素的记录。无论如何,我仍然可以在第二个查询中包含 FACTOR 不存在的那些记录,而不是逐行进行转换并以这种方式进行转换。

4

9 回答 9

2

您还可以使用 Coalesce 函数,带有子查询......

< 合并(arg0, arg1, arg2, ..... 等 argN)

依次评估每个参数并返回它找到的第一个不是 Null 的参数。>

Select D.CODE, D.NUMBER, D.QUANTITY, D.sale_code, 
    D.quantity * Coalesce((Select conversion 
                           From conversionfactor
                           Where item_code = H.item_code
                              And code = '01'
                              And loc_code = '00001'), 1.0)
From salesheader H
   Left Join salesdetails D
     On D.Number = H.Number
Where H.customer_code = '05'
   And H.r_code = '01'
   And H.location_code = '12'
   And H.year = '2008'
   And D.sale_code In ('ITEM07')
   And D.c_code = 'WLMT'

当记录不再在转换因子表中时,将子查询末尾的 1.0 替换为您希望转换因子的“默认”值是什么...

于 2008-11-18T16:33:39.067 回答
1

从 rsh 到 rth 的外部连接然后从 rth 到 cf 的内部连接是没有意义的。使它们都成为外部连接。此外, (+) 符号必须出现在 rth 的所有连接条件的“外侧”:

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code,
       rth.quantity * cf.conversion
FROM salesdetails rth, salesheader rsh, conversionfactor cf
WHERE rsh.number = rth.number(+)
AND rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rth.sale_code (+) IN('ITEM07')
AND rth.c_code (+) = 'WLMT'
AND rsh.year = '2008'
AND cf.item_code (+) = rth.item_code
and cf.code (+) = '01'
and cf.loc_code (+) = '00001'

顺便说一句,这是非常老式的语法。为什么不使用更现代的:

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code,
       rth.quantity * cf.conversion
FROM salesheader rsh
LEFT OUTER JOIN salesdetails rth
   ON  rsh.number = rth.number
   AND rth.sale_code IN ('ITEM07')
   AND rth.c_code = 'WLMT'
LEFT OUTER JOIN conversionfactor cf
   ON  cf.item_code = rth.item_code
   AND cf.code = '01'
   AND cf.loc_code = '00001'
WHERE rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rsh.year = '2008'
于 2008-11-18T16:28:45.100 回答
0

现在我无法访问 Oracle。看看这个查询:

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code, rth.quantity * cf.conversion
FROM salesdetails rth, salesheader rsh, conversionfactor cf
WHERE rsh.number = rth.number(+)
AND rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rth.sale_code IN('ITEM07')
AND rth.c_code = 'WLMT'
AND rsh.year = '2008'
AND rth.item_code  =  cf.item_code (+)
and cf.code = '01'
and cf.loc_code = '00001'
于 2008-11-18T16:10:44.713 回答
0

不,我相信 OUTER JOIN 不起作用,因为记录实际上并不存在。它不是空的,它只是不存在了。

于 2008-11-18T16:14:57.077 回答
0

我认为这应该有效。它假设转换因子在不存在时等于 1

select 
    rth.code, rth.number, rth.quantity, rth.sale_code, rth.quantity * coalesce(cf.conversion,1)
from 
    salesdetails rth
    inner join  salesheader rsh on rsh.number = rth.number
    left join conversionfactor cf on cf.item_code = rth.item_code
where 
rsh.customer_code = '05'
and rsh.r_code = '01'
and rsh.location_code = '12'
and rth.sale_code in('item07')
and rth.c_code = 'wlmt'
and rsh.year = '2008'
and cf.code = '01'
and cf.loc_code = '00001'
于 2008-11-18T16:16:27.963 回答
0

我相信 SQL 假设我有一个空记录。我没有,当转换不存在时,我根本没有记录。如果我能找到一种方法为我的数据库中不存在的那些 CONVERSION 返回 null,我可以这样做。

于 2008-11-18T16:23:46.857 回答
0

实际上,您对 OUTER JOIN 的看法是正确的。我当时认为它所做的事情存在技术问题,但我明白为什么它仍然没有包含价值。其他两个条件必须是 (+) 才能包含 NULL。我将它与 COALESCE 结合起来,它似乎正在工作。

于 2008-11-18T16:45:57.717 回答
0

我想你正在丢失记录,因为你试图乘以一个空值。看看将 NVL() 与您的转换因子一起使用,以将其默认为 1 或其他适合您的默认值。

喜欢,

SELECT rth.CODE, rth.NUMBER, rth.QUANTITY, rth.sale_code, rth.quantity * NVL(cf.conversion,1)
FROM salesdetails rth, salesheader rsh, conversionfactor cf
WHERE rsh.number = rth.number(+)
AND rsh.customer_code = '05'
AND rsh.r_code = '01'
AND rsh.location_code = '12'
AND rth.sale_code IN('ITEM07')
AND rth.c_code = 'WLMT'
AND rsh.year = '2008'
AND cf.item_code = rth.item_code
and cf.code = '01'
and cf.loc_code = '00001'

仔细检查 NVL 语法。自从我与 Oracle 合作以来已经有几年了。

于 2008-11-20T04:38:23.987 回答
0

如果您处理空值和数字,请考虑使用“合并”函数,其中列表中的第一个非空值作为结果传回。

于 2013-09-28T13:39:48.483 回答