数据库是Postgres,但任何SQL逻辑都应该有所帮助。
我正在检索包含物料清单中给定产品的销售报价集。我分两步执行此操作:步骤1,检索包含给定产品的所有DISTINCT报价编号(按产品编号)。
第二步,检索完整报价,列出每个唯一报价编号的所有产品。
到目前为止,这么好。现在是艰难的一点。有些行是重复的,有些则不是。那些重复的(报价编号和报价版本和行号)可能会或可能不会对它们进行维护。我想选择维护大于0的行。我要排除的重复行是那些维护为0的行。问题是有些行没有重复,有0维护,所以我不能只过滤维护。
为了让这令人兴奋,该数据库保留了20多年的报价。数据科学家们刚刚承认也许 ETL过程有一些错误......
--- step 0
--- cleanup the workspace
SET CLIENT_ENCODING TO 'UTF8';
DROP TABLE IF EXISTS product_quotes;
--- step 1
--- get list of Product Quotes
CREATE TEMPORARY TABLE product_quotes AS (
SELECT DISTINCT master_quote_number
FROM w_quote_line_d
WHERE item_number IN ( << model numbers >> )
);
--- step 2
--- Now join on that list
SELECT
d.quote_line_number,
d.item_number,
d.item_description,
d.item_quantity,
d.unit_of_measure,
f.ref_list_price_amount,
f.quote_amount_entered,
f.negtd_discount,
--- need to calculate discount rate based on list price and negtd discount (%)
CASE
WHEN ref_list_price_amount > 0
THEN 100 - (ref_list_price_amount + negtd_discount) / ref_list_price_amount *100
ELSE 0
END AS discount_percent,
f.warranty_months,
f.master_quote_number,
f.quote_version_number,
f.maintenance_months,
f.territory_wid,
f.district_wid,
f.sales_rep_wid,
f.sales_organization_wid,
f.install_at_customer_wid,
f.ship_to_customer_wid,
f.bill_to_customer_wid,
f.sold_to_customer_wid,
d.net_value,
d.deal_score,
f.transaction_date,
f.reporting_date
FROM w_quote_line_d d
INNER JOIN product_quotes pq ON (pq.master_quote_number = d.master_quote_number)
INNER JOIN w_quote_f f ON
(f.quote_line_number = d.quote_line_number
AND f.master_quote_number = d.master_quote_number
AND f.quote_version_number = d.quote_version_number)
WHERE d.net_value >= 0 AND item_quantity > 0
ORDER BY f.master_quote_number, f.quote_version_number, d.quote_line_number
过滤重复行的逻辑如下: 对于每个master_quote_number / version_number对,检查是否存在重复的行号。如果是这样,请选择维护&gt; 0.
即使在CASE声明中,我也不确定如何写。
思考?数据库是Postgres,但任何SQL逻辑都应该有所帮助。
答案 0 :(得分:0)
你能做点像......
select
*
from
w_quote_line_d d
inner join
(
select
...
,max(maintenance)
from
w_quote_line_d
group by
...
) d1
on
d1.id = d.id
and d1.maintenance = d.maintenance;
我是否正确理解您的问题?
编辑:忘记小组!
答案 1 :(得分:0)
我想你会想要使用Window Functions。总之,它们很棒。
这是一个将重复删除&#34;根据您的标准:
select *
from (
select
* -- simplifying here to show the important parts
,row_number() over (
partition by master_quote_number, version_number
order by maintenance desc) as seqnum
from w_quote_line_d d
inner join product_quotes pq
on (pq.master_quote_number = d.master_quote_number)
inner join w_quote_f f
on (f.quote_line_number = d.quote_line_number
and f.master_quote_number = d.master_quote_number
and f.quote_version_number = d.quote_version_number)
) x
where seqnum = 1
row_number()
以及所选partition by
和order by
条件的使用保证quote_number / version_number的每个组合只有一行将获得值1,它将是一个维护中具有最高值的人(如果你的同事是对的,那么只有一个值> 0的人)。
答案 2 :(得分:-1)
我不确定,但也许你可以Group By
所有其他列,并使用MAX(Maintenance)
来获得最大的。
您怎么看?