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

Rom*_*man 8 sql jpa join count oracle11g

我请求你帮忙,因为我不太了解SQL.

我需要从表列中计算出现一些值来实现像统计表一样的效果,如下图所示:

需要的结果:

在此输入图像描述

评论:

我的结果表需要有前两列(contry和site)来自第一个表"Violations"和接下来的5个列,它们将在Status表的每个可能值的"Violations"中包含出现status_id的数量(计数).

说明:

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

违规行为:

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

状态:

  • id很长,
  • status 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
Run Code Online (Sandbox Code Playgroud)

或没有加入:

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
Run Code Online (Sandbox Code Playgroud)

...但不包括3个问题,如图所示.我的意思是:

  • " - 全部 - "应计算所有国家/地区的出现次数
  • " - 未知 - "应计算某些未被承认的国家/地区的出现次数
  • " - 全部 - "(关于每个国家) - 应计算一个国家内的事件

附加说明:

  • -Unknown- 含义:

未知应该计算例如在DB Country表中不存在或具有错误名称/ id的国家/地区的出现次数,这就是为什么在这里被视为Unknown(我忘了提到CountryDB 中有表).站点,Unknown站点的相同意味着有人在Violations.status_id中放错了值而不是范围(1-4),因为这些只是状态表中存在的可接受值.

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

国家:

  • id很长,
  • name varchar(30)

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

Mar*_*zek 0

All情况可以使用语句轻松完成(有关结果,参阅sqlFiddle ):UNION

(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
Run Code Online (Sandbox Code Playgroud)

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

带有“未知”的版本

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
Run Code Online (Sandbox Code Playgroud)