#mysql
#mysql
Вопрос:
это моя скрипка https://dbfiddle.uk/?rdbms=mysql_5.7amp;fiddle=19b6e1298eba9eaa92ba2c726916d5d2
предположим, у меня есть эта таблица
CREATE TABLE Prime_Table (
user_Id varchar(100),
join_date date,
platform varchar(100),
country varchar(30)
);
INSERT INTO Prime_Table VALUES
('895A8F53-C61C-471A-B934-CC2795286E19', '2020-01-01','IOS', 'United States'),
('2B4C47D7-0DDC-4007-B1CF-4E3C802E5D5D', '2020-01-02', 'IOS', 'United States'),
('5309F361-DBF9-4AF9-8B6B-79F377C3647C', '2020-01-02', 'IOS', 'United States'),
('79077D38-F49D-44E0-B47B-030954F6FE33', '2020-01-02', 'IOS', 'United States'),
('569D79E4-8EA8-4D0D-83F3-6EC3F4B307D9', '2020-01-03', 'IOS', 'Indonesia'),
('CF29B015-7337-429E-A055-EE9640033E69', '2020-01-03', 'IOS', 'United Kingdom'),
('4759E38F-7DEE-4D0E-91ED-9B8CB7C545FA', '2020-01-03', 'IOS', 'Lebanon'),
('499B35D0-84D9-43CE-B684-43A50F107866', '2020-01-04', 'IOS', 'Canada'),
('5C1ED286-BA84-434B-8FC7-97AF5235D051', '2020-01-04', 'IOS', 'Indonesia');
-------------------------------------- ------------ ---------- ----------------
| user_Id | join_date | platform | country |
-------------------------------------- ------------ ---------- ----------------
| 895A8F53-C61C-471A-B934-CC2795286E19 | 2020-01-01 | IOS | United States |
| 2B4C47D7-0DDC-4007-B1CF-4E3C802E5D5D | 2020-01-02 | IOS | United States |
| 5309F361-DBF9-4AF9-8B6B-79F377C3647C | 2020-01-02 | IOS | United States |
| 79077D38-F49D-44E0-B47B-030954F6FE33 | 2020-01-02 | IOS | United States |
| 569D79E4-8EA8-4D0D-83F3-6EC3F4B307D9 | 2020-01-03 | IOS | Indonesia |
| CF29B015-7337-429E-A055-EE9640033E69 | 2020-01-03 | IOS | United Kingdom |
| 4759E38F-7DEE-4D0E-91ED-9B8CB7C545FA | 2020-01-03 | IOS | Lebanon |
| 499B35D0-84D9-43CE-B684-43A50F107866 | 2020-01-04 | IOS | Canada |
| 5C1ED286-BA84-434B-8FC7-97AF5235D051 | 2020-01-04 | IOS | Indonesia |
-------------------------------------- ------------ ---------- ----------------
я хочу, чтобы отображение из каждой страны пользователей принадлежало, я могу сделать отображение следующим образом
SELECT COALESCE(country, 'Total') AS `country`,
COUNT(a.user_id) AS `Count_User`,
round(COUNT(a.user_id) / any_value(totalcount) * 100, 1) AS `Count_User(%)`
FROM Prime_Table a
JOIN ( SELECT
COUNT(user_id) totalcount
FROM Prime_Table
) totals
GROUP BY a.country WITH ROLLUP;
and this is the output
---------------- ------------ ---------------
| country | Count_User | Count_User(%) |
---------------- ------------ ---------------
| Canada | 1 | 11.1 |
| Indonesia | 2 | 22.2 |
| Lebanon | 1 | 11.1 |
| United Kingdom | 1 | 11.1 |
| United States | 4 | 44.4 |
| Total | 9 | 100.0 |
---------------- ------------ ---------------
но как разделить все эти страны на 2 категории, например, США (Соединенные Штаты) и неамериканские (Соединенные Штаты), чтобы ожидаемые результаты стали такими
------------------- ------------- ----------------
| country | count_users | count_users(%) |
------------------- ------------- ----------------
| United States | 4 | 44.44% |
| Non-United States | 5 | 55,56% |
| Total | 9 | 100 |
------------------- ------------- ----------------
Комментарии:
1. Используйте
SUM(country = 'United States')
иSUM(country != 'United States')
соответственно вместоCOUNT(user_id)
, иGROUP BY country = 'United States'
2. @Akina сделать это ответом?
3. @ysth Ответ нужно переписать запрос до правильного — слишком ленив. Сделайте это, если хотите.
4. я просто следую вашей инструкции, но становлюсь таким dbfiddle.uk /…
Ответ №1:
Самое простое изменение — это просто заменить таблицу FROM на подзапрос, который изменяет страны, отличные от США:
SELECT COALESCE(country, 'Total') AS `country`,
COUNT(a.user_id) AS `Count_User`,
round(COUNT(a.user_id) / any_value(totalcount) * 100, 1) AS `Count_User(%)`
FROM (
SELECT user_id, CASE WHEN country != 'United States' THEN 'Non-United States' ELSE country END AS country
FROM Prime_Table a
) a
JOIN ( SELECT
COUNT(user_id) totalcount
FROM Prime_Table
) totals
GROUP BY a.country WITH ROLLUP;
https://dbfiddle.uk/?rdbms=mysql_5.7amp;fiddle=5492fdcf37a63e65773aa8a6d146144d
Ответ №2:
Вероятно, не самый эффективный способ, но способ. Расширение ваших текущих запросов. Дамп первого результата во временной таблице
CREATE TEMPORARY TABLE stats
SELECT COALESCE(country, 'Total') AS `country`,
COUNT(a.user_id) AS `Count_User`,
round(COUNT(a.user_id) / any_value(totalcount) * 100, 1) AS `Count_User(%)`
FROM Prime_Table a
JOIN ( SELECT
COUNT(user_id) totalcount
FROM Prime_Table
) totals
GROUP BY a.country WITH ROLLUP;
А затем group by case
в этой таблице:
select
(case
when country like '%United States%' then 'United States'
when country like '%Total%' then 'Total'
else 'Non-United States' end) as country,
sum(Count_User),
sum(`Count_User(%)`
from stats
group by
(case
when country like '%United States%' then 'United States'
when country like '%Total%' then 'Total'
else 'Non-United States' end
) order by 3,1 desc;
Комментарии:
1. большое спасибо, пожалуйста, взгляните на мою скрипку dbfiddle.uk / … , можете ли вы сделать так, чтобы итоговые данные были внизу, а не посередине?
2. @FachryDzaky отредактировал ответ. Просто добавьте предложение order by после group by
3. Есть какие-либо разъяснения относительно того, почему
order by 3
? и как это работает?4. @tcadidot0 order by 3 представляет 3-й столбец в запросе select, который равен user%, и мы знаем, что пользовательский% от общего числа всегда будет максимальным.
5. @hsnsd но если есть только США или только неамериканские страны, то не итоговые значения будут иметь одинаковый%, и заказ не обязательно будет иметь общее последнее