【问题标题】:SQL change a query to return results for all usersSQL 更改查询以返回所有用户的结果
【发布时间】:2016-06-14 20:38:35
【问题描述】:

我使用 sql server 并且我有表格:

tbl_GroupUser:
user_id, group_id

这是一个包含用户及其所在组的表(每个组有多个 user_id,每个用户有多个组)。

tbl_group:
id, name

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

tbl_Group 的 id 与 group_id 以及 tbl_User 的 id 与 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

【问题讨论】:

  • 使用更新的答案并标记为有帮助

标签: sql sql-server


【解决方案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

【讨论】:

  • 我认为它有效,但结果是四舍五入的,而不是我想要的小数。
  • 不是它添加 00 而不是在该点之后真正应该添加的内容。例如,显示 76.00 而不是 76.11940298507
  • still int :/ 我什至改变了 - 声明 @Percentage int - 从 int 到 decimal
【解决方案2】:

你不是在尝试这么简单的事情吗?

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;

【讨论】:

  • 我得到:将 int 转换为数据类型 numeric 的算术溢出错误。
  • 已删除所有演员表。这适用于所有工作案例。
  • 你计算了什么?我想要用户所在的具有 2 个用户的组的百分比 - 用户所在的具有 2 个用户的群组的数量 * 100 / 用户所在的群组总数
【解决方案3】:

使用窗口函数即时统计组成员,然后汇总每个用户的数据:

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

【讨论】:

  • 在对答案投反对票时,至少应该对原因发表评论。我注意到我的查询在when 之前缺少关键字case。一个小错误很快就修复了,除此之外,我的查询是标准 SQL,可能是在 SQL Server 中解决问题的直接方法。请注意,该表只读一次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-08
  • 1970-01-01
相关资源
最近更新 更多