问题
Can you please help to mark duplicated values in an additional column without grouping duplicated values?
See my example data (Example what I have and What I need to achieve on the right):
As you can see I have Product ID with suffix E (Power) and G (Gas). Some Product IDs are duplicated: the same Product ID - one with E and the second one with G makes Dual Product.
Product ID only with E makes Power_Only_product, Product ID only with G makes Gas_Only_product, the same Product ID with E and G makes Dual Product.
The tricky thing is to add a column on the right site with information which ID is Dual Product and which one is Power Only or Gas Only.
Can you help me to get such column without grouping the Product IDs? Thank you in advance! Pawel
回答1:
SELECT t1.*,
CASE WHEN t2.CustomerAccount IS NOT NULL
THEN 'Dual Product'
WHEN t1.Product = 'Gas'
THEN 'Gas Only'
WHEN t1.Product = 'Power'
THEN 'Power Only'
ELSE 'Wrong product type'
END ProductType
FROM sourcetable t1
LEFT JOIN sourcetable t2 ON t1.CustomerAccount = t2.CustomerAccount
AND t1.Product != t2.Product
The query do NOT use ProductID
and do NOT check that it matches CustomerAccount
and/or Product
. It will be excess work without any profit.
回答2:
If you are running MySQL 8.0, you can do this with window functions only, without joins, subqueries or CTEs.
I would suggest to just compare the maximum and the minimum values of product
for each customer; when they differ, you have have a "dual product".
select
t.*,
case when min(product) over(partition by customer_account) <> max(product) over(partition by customer_account)
then 'Dual Product'
else concat(product, ' Only')
end single_or_dual_product
from mytable t
回答3:
You don't mention which database you are using, so I'll assume it's MySQL 8.x.
It's probably better to separate the ID
from the TYPE
using a CTE. Then, the query gets far easier. For example:
with
x as ( -- this CTE just to separate the ID from the TYPE
select *,
substring(productid, 1, char_length(productid) - 1) as id,
right(productid, 1) as type
from t
)
select x.*, case when y.id is null then 'Power Only' else 'Dual' end
from x
left join y on x.id = y.id and y.type = 'G'
where x.type = 'E'
union all
select x.*, case when y.id is null then 'Gas Only' else 'Dual' end
from x
left join y on x.id = y.id and y.type = 'E'
where x.type = 'G'
order by id, type
Note that I use UNION ALL
. This is because MySQL does not (yet) implement FULL OUTER JOINs. The trick here is to repeat the query somewhat reversed.
来源:https://stackoverflow.com/questions/60977262/mark-duplicated-values-mysql-without-using-group-by