简体   繁体   中英

mysql return same rows union

In my database i have categories, offers and coupons. i would like to count offers and coupons that exist in each category. when i use union it returns the same category twice. i have the below query that returning same category rows with same name. i try to use union distinct but it does not work.

(SELECT 
        cat1.id AS cat1id, cat1.title AS title,
        count(offers.id) AS offercounter

    FROM cat1

    INNER JOIN offers 
    ON offers.category=cat1.title

    GROUP BY cat1.id
    order by cat1.order)
     UNION
    (SELECT 
        cat1.id AS cat1id, cat1.title AS title,
        count(coupons.id) AS couponscounter

    FROM cat1

    INNER JOIN coupons 
    ON coupons.category=cat1.title

    GROUP BY cat1.id
    order by cat1.order)

the result

cat1id  title         offercounter
 2       Food              5388
 23      Clothes           6000(this is offers)
 32      Technology         499
 40      Clothes            4(this is coupons)

i would like clothes to be (offercounter + couponscounter). example: clothes=6004 and not two different rows

the desired result would be :

cat1id  title         offercounter
 2       Food              5388
 23      Clothes           6004(offers+coupons)
 32      Technology         499

Union returns distinct rows. Your returned rows are distinct indeed. What you need to do to get your desired result is aggregate after unioning.

select min(cat1id) as cat1id, title, sum(offercounter) as offercounter
 from 
(your_query) as subquery
group by title

replace your_query with your existing query

Alternative avoiding unions or sub queries is to use a couple of LEFT OUTER JOINS, and count the distinct ids from each table:-

SELECT cat1.id AS cat1id, 
        cat1.title AS title,
        COUNT(DISTINCT offers.id) + COUNT(DISTINCT coupons.id) AS offercounter
FROM cat1
LEFT OUTER JOIN offers ON offers.category = cat1.title
LEFT OUTER JOIN coupons ON coupons.category = cat1.title
GROUP BY cat1.id AS cat1id, 
        cat1.title AS title

EDIT

A left outer join will return a row of nulls when there is no matching row.

For example if there was a row on cat1 with a matching row on offers but no matching row on coupons then the resulting row would consist of the row from cat1, the row from offers and the fields from coupons would be null.

This SQL will get every combination of matching rows. So if you had:-

cat1 fields     offers fields       coupons fields
id  title       id      category    id      category
1   fred        99      fred        77      fred
1   fred        99      fred        88      fred
1   fred        100     fred        77      fred
1   fred        100     fred        88      fred
2   burt        120     fred        NULL    NULL
2   burt        121     fred        NULL    NULL

Hence the count uses DISTINCT to only could each id within a category once. As COUNT(field name) only counts non null values, with this example data for the 2nd category the count from coupons will be 0.

Why don't you simple sum up the offercounter and use group by with order by cat1id .

SELECT cat1id,title,sum(offercounter) as offercounter 
FROM offers GROUP BY title ORDER BY cat1id

View : SQL Fiddle

Output :

cat1id   title            offercounter
 2       Food             5388
 23      Clothes          6004
 32      Technology       499

May be this can help.

SELECT cat1.id AS cat1id, cat1.title AS title ,((SELECT COUNT(offers.id) FROM offers WHERE offers.category=cat1.title)+(SELECT COUNT(coupons.id) FROM coupons WHERE coupons.category=cat1.title)) AS offercounter
FROM cat1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM