根据描述计算总成本的查询

Query to Calculate totalcost based on description

我对 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计算,将根据供应商

分组

所以请多多指教

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

编辑

正如评论中所指出的,我在原始答案中遗漏的 Null 描述项周围缺少一大堆逻辑。

以下相当混乱的查询确实预测了所需的结果,但我认为这可能表明 table 设计重新思考是必要的。 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

您的逻辑似乎是:如果供应商的 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;

要获得您需要的确切输出,请使用以下语句:(其中 test_table 是您的 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;

详情:

外部 select 只是获取单独的行并将它们组合成字符串表示形式。只需将其删除,每个 vendor/description 组合都会得到一行。

内部select连接两个子select。第一个通过汇总所有没有描述的行来获得每个供应商的 base_cost。第二个获取带有描述的每一行的单独成本。

联接将它们组合在一起 - 左外部联接显示 base_cost 对于没有匹配行和描述的供应商。