2016-06-14 2 views
0

Я использую SQL сервер и у меня есть таблицы:SQL изменить запрос, возвращающий результаты для всех пользователей

tbl_GroupUser: 
user_id, group_id 

который представляет собой таблицу, содержащую пользователей и группы, они находятся в (каждая группа имеет более чем один user_id, и каждый пользователь имеет более одной группы).

tbl_group: 
id, name 

tbl_User: 
id, age,....(information about the user) 

Существует один ко многим отношений между идентификатором tbl_Group к GROUP_ID и между идентификатор tbl_User к user_id.

Я создал запрос, возвращающий процент групп, в котором для них есть только 2 пользователя, и мне нужен запрос, который возвращает результаты для всех пользователей. Это запрос, я сделал:.

SELECT cast((SELECT count(*) FROM 
(SELECT user_id FROM tbl_GroupUser WHERE group_id in 
(SELECT group_id FROM (SELECT t1.group_id, count(distinct t1.user_id) as numberOfUsers 
FROM tbl_GroupUser as t1 JOIN tbl_GroupUser as t2 ON t1.group_id = t2.group_id group by 
t1.group_id) y WHERE y.numberOfUsers = 2)) as x WHERE x.user_id = 'user') as decimal) * 100/
(SELECT count(*) FROM tbl_GroupUser WHERE user_id = 'user') 

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

Пример что я хочу:

tbl_GroupUser:

group_id | user_id 
------------------ 
1  | 1 
1  | 2 
2  | 1 

результаты:

user_id | p_Grp2 
---------------- 
1  | 50.0 
2  | 100.0 
+0

использовать обновленный ответ и отметьте, как полезно –

ответ

1

просто создать пользователя определить функцию и использовать в запросе на выборку

alter function UDF_GetPercentage(@UserId int) 
returns decimal(18,10) 
as begin 

declare @Percentage decimal(18,10) 
SELECT @Percentage = cast(
(SELECT count(*) FROM 
(SELECT user_id FROM tbl_GroupUser WHERE group_id in 
(SELECT group_id FROM (SELECT t1.group_id, count(distinct t1.user_id) as numberOfUsers 
FROM tbl_GroupUser as t1 JOIN tbl_GroupUser as t2 ON t1.group_id = t2.group_id group by 
t1.group_id) y 
WHERE y.numberOfUsers = 2) 
) 
as x 

WHERE x.user_id in (@UserId) 
) as decimal) 
* 100 
/
(SELECT count(*) FROM tbl_GroupUser WHERE user_id in (@UserId)) 

return @Percentage 

end 

и использовать в запросе на выборку, как этот

SELECT user_id, dbo.UDF_GetPercentage(user_id) as p_Grp2 
FROM  tbl_GroupUser 
group by user_id 
+0

Я думаю, что это работает, но результаты округлены а не десятичной, как я хотел. –

+0

не добавляет 00 вместо того, что действительно должно быть после точки. Например, вместо 76.11940298507 он показывает 76.00 –

+0

ok проверить снова i обновлено –

-1

Вы не пытаетесь что-то же просто, как это?

SELECT user_id, 100.0/COUNT(0) as p_Grp 
FROM tbl_User u 
INNER JOIN tbl_GroupUser gu ON gu.userId = u.Id 
GROUP BY user_id; 
+0

Я получаю: Ошибка арифметического переполнения, преобразующая int в тип данных числовой. –

+0

Я по-прежнему получаю ту же ошибку:/ –

+0

Удалили все броски. Это отлично работает для всех случаев работы. –

-1

члены графа групп на лету с функцией окна, то совокупные данные для каждого пользователя:

select user_id, 100.0 * count(case when cnt = 2 then 1 end)/count(*) 
from 
(
    select 
    user_id, 
    count(*) over (partition by group_id) as cnt -- cnt = 2 marks a "two" group 
    from tbl_groupuser 
) 
group by user_id 
having count(case when cnt = 2 then 1 end) > 0; -- user in at least one "two" group 
+0

Когда downvoting ответ должен по крайней мере оставить комментарий о том, почему. Я заметил, что в моем запросе не было ключевого слова 'case' до' when'. Небольшая ошибка, которая была быстро исправлена, и, кроме того, мой запрос является стандартным SQL и, предположительно, прямым способом решить проблему в SQL Server. Обратите внимание, что таблица читается только один раз. –

Смежные вопросы