Mysql количество записей из связанных таблиц - PullRequest
0 голосов
/ 27 августа 2018

Я пытаюсь получить количество записей из связанных таблиц.Я могу достичь нужного результата, разбивая запросы и объединяя массивы, но я знаю, что это неэффективно.

Я ищу более чистый и эффективный способ сделать это.Все таблицы один ко многим.Пример: - Один пользователь имеет много объектов. - Один объект имеет много элементов.

Table Users
 ______________
| ID   |  UID  |
 ______________
|  1   |  U1   |
|  2   |  U2   |
 ______________
Table Objects
 ______________
| ObjID | UID  |
 ______________
|  o1   |  U1  |
|  o2   |  U1  |
|  o3   |  U1  |  
 ______________
Table Items
 _________________
| itemID |  ObjID |
 _________________
|  i1    |  o1    |
|  i2    |  o1    |
|  i3    |  o1    |
|  i4    |  o1    |
|  i5    |  o1    |
|  i6    |  o2    |
 _________________

Результат, который я ищу для U1:

| Objects |  Items  |
|   3     |    6    |

вот где я застрял:

    select count(objects.id), count(items.id)
    from users
    left join Objects on objects.uid = users.uid
    left join Items on items.objID = objects.objID 
    where users.uid = 'U1'

Ответы [ 4 ]

0 голосов
/ 27 августа 2018

Рассмотрим следующее:

create table users
(user_id serial primary key,name char(2) unique
);

insert into users values (101,'U1'),(102,'U2');

create table user_objects
(user_id int not null
,object_id int not null
,primary key(user_id,object_id)
);

insert into user_objects values
(101,1),
(101,2),
(101,3);

create table object_items
(object_id int not null
,item_id int not null
,primary key(object_id,item_id)
);

insert into object_items values
(1,1001),
(1,1002),
(1,1003),
(1,1004),
(1,1005),
(2,1001);

select u.name
     , count(distinct uo.object_id) objects
     , count(oi.item_id) items
  from users u
  left
  join user_objects uo 
    on uo.user_id = u.user_id
  left 
  join object_items oi
    on oi.object_id = uo.object_id
group
    by u.user_id;

http://sqlfiddle.com/#!9/d2285/1

0 голосов
/ 27 августа 2018

Попробуйте: хотя я не уверен в количестве ваших предметов

select count(objects.id), count(distinct items.id)
 from Items inner join Objects on objects.ObjID= users.ObjID
 inner join Items on users.uid= objects.uid
 where users.uid = 'U1'
0 голосов
/ 27 августа 2018

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

select count(distinct ObjId) Objects,
       count(distinct ItemId) Items
from Items i
where exists(select 1 from Objects
             where ObjId = i.ObjId and UID = 'U1');
0 голосов
/ 27 августа 2018

Один из быстрых способов получить желаемый результат - использовать коррелированные подзапросы:

select (select count(*) 
        from Objects 
        where UID = 'U1') as Objects,
       (select count(*)
        from Items as i
        inner join Objects as o on i.ObjID = o.ObjID
        where o.UID = 'U1') as Items

Другой способ - создать производную таблицу элементов для каждого объекта и присоединиться к этой таблице, чтобы получить общее количество элементов на пользователя.:

SELECT COUNT(*) AS Objects, SUM(cnt_per_oID) AS Items
FROM Users AS u
JOIN Objects AS o ON u.UID = o.UID
LEFT JOIN 
(
   SELECT ObjID, COUNT(*) cnt_per_oID
   FROM Items
   GROUP BY ObjID
) AS i ON o.ObjID = i.ObjID
WHERE u.UID = 'U1'
GROUP BY u.UID

Демо здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...