Выберите значения из сгруппированных по набору - PullRequest
0 голосов
/ 23 мая 2018

Как я могу сделать это SQL Fiddle получить результаты из подмножества элементов, возвращаемых GROUP BY?

Таблица

CREATE TABLE IF NOT EXISTS `accounts` (
  `master_id` int(3) unsigned NOT NULL,
  `child_id` int(3) unsigned NOT NULL,
  `name` varchar(200) NOT NULL
);

Данные

INSERT INTO `accounts` (`master_id`, `child_id`, `name`) VALUES
  ('222', '555', 'child_555'),
  ('111', '111', 'master_111'),
  ('111', '999', 'child_999'),
  ('111', '888', 'child_888'),
  ('222', '222', 'master_222'),
  ('222', '777', 'child_777'),
  ('111', '666', 'child_666');

Текущий запрос

SELECT 
master_id, 
name, 
count(*) as "Total Accounts"
FROM `accounts`
GROUP BY master_id ASC;

Результаты

+-----------+------------+-------+
| master_id |    name    | Total |
+-----------+------------+-------+
|       111 | master_111 |     4 |
|       222 | child_555  |     3 |
+-----------+------------+-------+

Ожидаемый

 - Don't count child if child_id == master_id
 - Get correct name

+-----------+------------+-------+
| master_id |    name    | Total |
+-----------+------------+-------+
|       111 | master_111 |     3 |
|       222 | master_222 |     2 |
+-----------+------------+-------+

Ответы [ 6 ]

0 голосов
/ 23 мая 2018

Я думаю, что простое агрегирование с некоторой условной логикой - лучший подход:

SELECT master_id,
       MAX(CASE WHEN child_id = master_id THEN name END) as name,
       SUM(child_id <> master_id) as "Total Accounts"
FROM `accounts`
GROUP BY master_id ASC;

Здесь - это SQL-скрипта для этого.

0 голосов
/ 23 мая 2018

Попробуйте это ...

SELECT master_id, name, count(*) as "Total Accounts" 
FROM accounts where master_id != child_id
GROUP BY master_id ASC;
0 голосов
/ 23 мая 2018
select master_id, name, 
       sum(master_id != child_id) as Total
from `accounts`
group by master_id 
order by master_id ASC; 

Демонстрация по SQL Fiddle

0 голосов
/ 23 мая 2018

Вот решение без самостоятельного объединения

SELECT 
  `master_id`, 
  max(case when `master_id` = `child_id` then `name` end) n,
  count(case when `master_id` != `child_id` then 1 end) as "Total Accounts"
FROM `accounts` a1
GROUP BY master_id ASC;

DEMO

0 голосов
/ 23 мая 2018
SELECT 
b.master_id, 
a.name,
count(*) as "Total Accounts"
FROM accounts b, accounts a
where b.master_id<>b.child_id
and a.child_id = b.master_id
GROUP BY b.master_id ASC;

или, как предложил М. Халид Джунаид:

SELECT 
  b.master_id,
  a.name,
  COUNT(*) AS "Total Accounts" 
FROM
  accounts b 
  JOIN accounts a 
    ON b.master_id <> b.child_id 
    AND a.child_id = b.master_id 
GROUP BY b.master_id ASC 

Результат:

master_id   name        Total Accounts
111         master_111  3
222         master_222  2
0 голосов
/ 23 мая 2018

Используйте case выражение, чтобы выполнить условное агрегирование:

select b.master_id, a.name, 
       sum(case when b.master_id <> b.child_id then 1 else 0 end) as "Total Accounts"
from `accounts` a
inner join `accounts` b on a.child_id = b.master_id
group by b.master_id 
order by b.master_id ASC; 

Однако предложение WHERE также должно выполнить эту работу.

select master_id, name, 
       count(*) as "Total Accounts"
from `accounts`
where master_id != child_id
group by master_id 
order by master_id ASC; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...