如何在表上选择并计算出现一些值

时间:2013-03-12 12:17:00

标签: sql jpa join count oracle11g

我要求你帮忙,因为我不太了解SQL。

我需要计算表格列中的某些值,以实现类似于统计表的效果,如下图所示:

需要的结果:

enter image description here

注释:

我的结果表需要有前两列(contry和site)来自第一个表“Violations”和接下来的5个列,它们将包含每个可能的id值中“Violations”中出现的status_id数量(count)状态表。

说明:

所以,我有两个表:违规和状态。请查看我的sqlfiddle

违反:

  • id long,
  • country varchar(20),
  • site varchar(20),
  • status_id long,< - 这是状态表中的状态ID。
  • ...在这种情况下不重要的其他列

状态:

  • id long,
  • 状态很长 列“status”具有值(1-4),它们映射到字符串值:可疑违规(1),确认违规(2),确认无违规(3),未确定(4)

在我的加入结果中(或仅基于一个表违规)是要包含应包含列的表:

  • 来自违规表:“国家”和“网站”
  • 来自状态表:“可疑违规”,“确认违规”,“确认无违规”,“未确定”,“总计”(此列为违规表中出现的计数器)。

当前状态和新要求:

首先尝试完成(感谢bluefeet),并且几乎完美......

select v.country,
v.site,
    SUM(case when s.id = 1 then 1 else 0 end) Total_SuspectedViolations,
    SUM(case when s.id = 2 then 1 else 0 end) Total_ConfirmedViolations,
    SUM(case when s.id = 3 then 1 else 0 end) Total_ConfirmedNoViolations,
    SUM(case when s.id = 4 then 1 else 0 end) Total_NotDetermined,
    COUNT(*) Total
from violations v
inner join status s
    on v.status_id = s.id
group by v.country, v.site

或没有加入:

select v.country,
v.site,
    SUM(case when v.status_id = 1 then 1 else 0 end) Total_SuspectedViolations,
    SUM(case when v.status_id = 2 then 1 else 0 end) Total_ConfirmedViolations,
    SUM(case when v.status_id = 3 then 1 else 0 end) Total_ConfirmedNoViolations,
    SUM(case when v.status_id = 4 then 1 else 0 end) Total_NotDetermined,
    COUNT(*) Total
from violations v
group by v.country, v.site

...但不包括3个问题,你可以在图片中看到它应该是。我的意思是:

  • “ -​​ 全部 - ”应计算所有国家/地区的出现次数
  • “ -​​ 未知 - ”应计算某些未识别国家/地区的出现次数
  • “ -​​ 全部 - ”(关于每个国家/地区) - 应计算一个国家/地区内的事件

附加说明:

  • -Unknown-含义:

未知应该对国家/地区的事件进行计数,例如在DB国家/地区表中不存在或者名称/ ID错误,这就是为什么在此处理为Unknown(我忘了提到有表{{1}在DB)。 对于站点{1}来说,站点相同意味着有人在Violations.status_id中输入的值不是来自范围(1-4),因为这些只是状态表中存在的可接受值。

  • 我们可以假设表国家看起来像:

国家:

  • id long,
  • name varchar(30)

请帮我写出正确的sql查询,其中包括这3个条件,因为我有一个很大的问题要做。

2 个答案:

答案 0 :(得分:0)

所有 案例可以使用UNION语句轻松完成(有关结果,请参阅sqlFiddle):

(SELECT v.country,
    v.site,
    SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
    SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
    SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
    SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
    COUNT(*) Total,
    0  'isAll'
FROM violations v
GROUP BY v.country, v.site)
union(
SELECT v.country,
    '- All -',
    SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
    SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
    SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
    SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
    COUNT(*) Total,
  1  'isAll'
FROM violations v
GROUP BY v.country)
UNION (
SELECT '- All -',
    '- All -',
    SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
    SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
    SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
    SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
    COUNT(*) Total,
  1  'isAll'
FROM violations v)
ORDER BY country, isAll DESC, site

然而,对于这种查询,性能可能不是很好,所以我并不是说它是最好的解决方案 - 但它确实有效。

版本与'未知'

http://www.sqlfiddle.com/#!2/abfb7/21

(SELECT IF(c.name IS NULL, '- Unknow -', c.name) as name,
    v.site,
    SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
    SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
    SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
    SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
    COUNT(*) Total,
    0  'isAll'
FROM violations v LEFT JOIN country c ON c.name = v.country
GROUP BY c.name, v.site)
union(
SELECT IF(c.name IS NULL, '- Unknow -', c.name) as name,
    '- All -',
    SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
    SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
    SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
    SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
    COUNT(*) Total,
  1  'isAll'
FROM violations v LEFT JOIN country c ON c.name = v.country
GROUP BY c.name)
UNION (
SELECT '- All -',
    '- All -',
    SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
    SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
    SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
    SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
    COUNT(*) Total,
  1  'isAll'
FROM violations v LEFT JOIN country c ON c.name = v.country)
ORDER BY name, isAll DESC, site

答案 1 :(得分:0)

使用with rollup,您将获得所需的总和字段

select v.country,
v.site,
SUM(case when s.id = 1 then 1 else 0 end) Total_SuspectedViolations,
SUM(case when s.id = 2 then 1 else 0 end) Total_ConfirmedViolations,
SUM(case when s.id = 3 then 1 else 0 end) Total_ConfirmedNoViolations,
SUM(case when s.id = 4 then 1 else 0 end) Total_NotDetermined,
COUNT(*) Total
from violations v
     inner join status s
     on v.status_id = s.id
group by v.country, v.site WITH ROLLUP

希望这有帮助

{p> REFER 代表with rollup文档

FIDDLE

相关问题