简体   繁体   中英

MySQL Subquery to count multiple columns with GROUP BY

My table

+---------+----------+---+
| id      | a1 | a2 | a3 |
+---------+----+----+----+
| 1       | 1  |  0 |  0 |
| 2       | 0  |  1 |  0 |
| 3       | 1  |  1 |  1 |
| 4       | 1  |  1 |  0 |
+---------+----+----+----+

What I want as result: Mercedes 3 BMW 3 Ford 1 VW 2

Query I tried ..

SELECT 

    IF(a1=1,'Mercedes', 
    IF(a2=1,'BMW', 
    IF(a3=1,'Ford',
    IF(a4=1,'VW',
    'NO')))) AS marke,

    COUNT(autos.id) AS anzahl FROM autos 

    WHERE autos.land=de GROUP BY marke ORDER BY anzahl DESC

I get the desired result, but only the first row counts correct. How can I add a subquery to query the same table again showing the correct count for each field (a1, a2, a3)

What else die I try: The following subquery fails too!

SELECT 

IF(a1=1,'Mercedes', 
IF(a2=1,'BMW', 
IF(a3=1,'Ford',
IF(a4=1,'VW',
'NO')))) AS marke,

IF(a1=1,(SELECT COUNT( autos.id) FROM marke WHERE a1=1), 
IF(a2=1,(SELECT COUNT( autos.id) FROM marke WHERE a2=1),
IF(a3=1,(SELECT COUNT( autos.id) FROM marke WHERE a3=1),
IF(a4=1,(SELECT COUNT( autos.id) FROM marke WHERE a4=1),
'NO')))) AS anzahl,

FROM autos 

WHERE autos.land=de GROUP BY marke ORDER BY anzahl DESC

Hope this makes my question more understandable what I try to reach.

The use of a column for every make of car is a bad way to design your table, as it makes working with the data complicated in exactly the way you're experiencing.

Don't have a column for every make; have a column that links each car to a particular make instead:

CREATE TABLE car_makes ( 
  make_id bigint unsigned not null auto_increment primary key,
  name varchar(64)
);

CREATE TABLE cars (
  car_id bigint unsigned not null auto_increment primary key,
  make_id bigint 
);

INSERT INTO car_makes (name) VALUES ('Ford'), ('VW'), ('BMW'), ('Mercedes');

/* now let's create some cars that match your desired results */
INSERT INTO cars (make_id) SELECT make_id FROM car_makes; 
INSERT INTO cars (make_id) SELECT make_id FROM car_makes WHERE name IN('VW', 'Mercedes', 'BMW');
INSERT INTO cars (make_id) SELECT make_id FROM car_makes WHERE name IN( 'Mercedes', 'BMW');

Now you can simply group by the make like you want:

SELECT name , count(*) from cars 
JOIN car_makes ON ( car_makes.make_id = cars.make_id) 
GROUP BY car_makes.make_id;

You can see how this helps make the data simpler to manage, and also makes the query more efficient.

+----------+----------+
| name     | count(*) |
+----------+----------+
| Ford     |        1 |
| VW       |        2 |
| BMW      |        3 |
| Mercedes |        3 |
+----------+----------+

从汽车中选择SUM(a1)AS'Mercedes',sum(a2)AS'BMW',sum(a3)AS'FORD'

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