Mark duplicated values MySQL without using GROUP BY

血红的双手。 提交于 2021-01-29 08:49:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!