查询根据描述计算总成本

时间:2015-01-05 11:50:05

标签: sql oracle

我对sql脚本有疑问。我有一个自定义视图,下面是数据

================================================================================
ql_siteid | ql_rfqnum | ql_vendor | ql_itemnum | totalcost_option | description
================================================================================
SGCT      | 1002      | VND001    | ITEM002    | 12500            |
SGCT      | 1002      | VND001    | ITEM001    | 1350             |
SGCT      | 1002      | VND002    | ITEM002    | 11700            |
SGCT      | 1002      | VND002    | ITEM001    | 1470             | Nikon
SGCT      | 1002      | VND002    | ITEM001    | 1370             | Asus
================================================================================

我希望得到如下表所示的结果:

VND001 = 13850 
VND002 = Asus 13070, Nikon 13170

其中13850来自12500 + 1350,13070来自11700 + 1370,13170来自11700 + 1470。所有成本均来自totalcost_option,并将根据供应商

进行分组

所以请给我一些建议

3 个答案:

答案 0 :(得分:1)

要获得所需的确切输出,请使用以下语句:(其中test_table是您的表名):

SELECT ql_vendor || ' = ' || 
       LISTAGG( LTRIM(description||' ')||totalcost, ', ')
       WITHIN GROUP (ORDER BY description)
FROM (
  WITH base_cost AS (
    SELECT ql_vendor, SUM(totalcost_option) sumcost
    FROM test_table WHERE description IS NULL
    GROUP BY ql_vendor
  ),
  individual_cost AS (
    SELECT ql_vendor, totalcost_option icost, description
    FROM test_table WHERE description IS NOT NULL
  )
  SELECT ql_vendor, sumcost + NVL(icost,0) totalcost, description
  FROM base_cost LEFT OUTER JOIN individual_cost USING (ql_vendor)
)
GROUP BY ql_vendor;

详细说明:

外部选择只获取各行并将它们组合成字符串表示。只需删除它,每个供应商/描述组合就会得到一行。

内部选择加入两个子选择。第一个通过汇总所有行而没有描述来获取每个供应商的base_cost。第二行通过描述获得每行的单独成本。

连接组合它们 - 左外连接显示没有匹配行描述的供应商的base_cost。

答案 1 :(得分:0)

假设您拥有Oracle 11g或更高版本的版本,使用ListAgg将为您执行逗号分隔元组的组合。字符串的其余部分是通过简单地将组件从中间表连接在一起生成的 - 我在这里使用了派生表(X),但您也可以使用CTE。

修改

正如评论中指出的那样,在我原来的答案中遗漏的Null描述项目中缺少一大堆逻辑。

以下相当混乱的查询会预测所需的结果,但我相信这可能表明需要重新考虑表格设计。即使供应商没有基本/无描述成本项,FULL OUTER JOIN也应确保返回行。

WITH NullDescriptions AS
(
  SELECT "ql_vendor", SUM("totalcost_option") AS "totalcost_option"
  FROM MyTable
  WHERE "description" IS NULL
  GROUP BY "ql_vendor"
),
NonNulls AS
(
  SELECT COALESCE(nd."ql_vendor", mt."ql_vendor") AS "ql_vendor", 
         NVL(mt."description", '') || ' '
         || CAST(NVL(mt."totalcost_option", 0) 
                    + nd."totalcost_option" AS VARCHAR2(30)) AS Combined
  FROM NullDescriptions nd
  FULL OUTER JOIN MyTable mt
    ON mt."ql_vendor" = nd."ql_vendor"
    AND mt."description" IS NOT NULL
)
SELECT x."ql_vendor" || ' = ' || ListAgg(x.Combined, ', ') 
                                       WITHIN GROUP (ORDER BY x.Combined)
FROM NonNulls x
WHERE x.Combined <> ' '
GROUP BY x."ql_vendor";

Updated SqlFiddle here

答案 2 :(得分:0)

您的逻辑似乎是:如果供应商的description始终为NULL,那么您希望将其作为总费用。否则,您希望将描述的NULL值添加到所有其他值。以下查询实现此逻辑。输出的格式与您的答案不同 - 此格式与SQL结果集更加一致:

select ql_vendor,
       (sum(totalcost_option) +
        (case when description is not null then max(totalcost_null) else 0 end)
       )
from (select v.*, max(description) over (partition by ql_vendor) as maxdescription,
             sum(case when description is null then totalcost_option else 0 end)  over (partition by ql_vendor) as totalcost_null
      from view v
     ) t
where maxdescription is null or description is not null
group by ql_vendor, description;