根据描述计算总成本的查询
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";
您的逻辑似乎是:如果供应商的 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 对于没有匹配行和描述的供应商。
我对 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";
您的逻辑似乎是:如果供应商的 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 对于没有匹配行和描述的供应商。