我正在为我的公司创建一份流量报告,但我真的被这段代码困住了..
我有一个报告编号,以及数字表示的事故类型,即; 1个轻微,2个严重,3个致命,4个没有受伤。
通常情况报告包含多个号码,例如:
报告编号2014123有一名严重受伤的司机'2',乘客未受伤'4'。
所以当我触发报告编号= 2014123的选择查询时,我得到两条记录,一条记录为'2',另一条记录为'4'。
在上述情况中,事故被视为“严重”,因为它包含“2”。由于乘客没有受伤,因此不考虑'4'。 (轻微,严重,致命)伤害代码的处理高于(未受伤)。
如何生成严重受伤的报告(即代码'2'),伤害计数为'2'(自两条记录以来)?
我尝试过的方法:
我尝试了SQL Case语句:
(Case WHEN InjuryCode IN ('1','2','4') THEN 'Serious'
WHEN InjuryCode IN ('1','2','3','4') THEN 'FATAL'
WHEN InjuryCode IN ('1','4') THEN 'SLIGHT'
ELSE 'UNKNOWN'
END) AS ACCIDENT_STATUS
但我得到的只是重复和不正确的数据。
以下列方式优先考虑伤害代码: 3→2→1→4
例如:包含伤害代码的事故:
1,4- slight
2,4- serious
3,4- fatal
<1,2> 1,2,3,4致命(因为3是最高伤害代码)等等。
我希望这不会让你感到困惑,但请耐心等待我,我在开始时完全感到困惑,但我现在正在拍照,尽管没有解决方案,请帮忙!
编辑(评论中的完整查询):
SELECT REPORTNUMBER, INJURYCODE,
(CASE WHEN InjuryCode IN ('1','2','4') THEN 'Serious'
WHEN INJURYCODE IN ('1','2','3','4') THEN 'FATAL'
WHEN INJURYCODE IN ('1','4') THEN 'SLIGHT' ELSE 'UNKNOWN'
END) AS ACCIDENT_STATUS
FROM ACCIDENTS
WHERE REPORTNUMBER=20140302
答案 0 :(得分:1)
使用injuryCode
表示您需要Injury
表(如果您还没有表)。理想情况下,这包括您可以订购的某种严重性列 - 如下所示:
CREATE TABLE Injury (injuryCode CHAR(1),
severity INTEGER,
description VARCHAR(20));
INSERT INTO Injury VALUES ('1', 1, 'Slight'),
('2', 2, 'Serious'),
('3', 3, 'Fatal'),
('4', 0, 'Not Injured');
严格来说,你之前尝试过的是基于伤害的明显id进行排序 - 唯一应该使用的id是连接,否则应该被认为是随机/未定义的值(也就是说,实际值是不重要 - 它是否有连接到它这是重要的)。事实上,这些恰好是数字代码(显然存储为字符数据 - 这是完全可以接受的)并不重要。
无论如何,通过定义排序表,我们现在可以安全地查询数据:
SELECT AggregateAccident.reportNumber, Injury.injuryCode, Injury.description,
AggregateAccident.victimCount
FROM (SELECT Accidents.reportNumber, MAX(Injury.severity) as severity,
COUNT(*) as victimCount
FROM Accidents
JOIN Injury
ON Injury.injuryCode = Accidents.injuryCode
GROUP BY Accidents.reportNumber) AggregateAccident
JOIN Injury
ON Injury.severity = AggregateAccident.severity
ORDER BY AggregateAccident.reportNumber
(和SQL Fiddle example。感谢Turophile的骨架。使用SQL Server,但这应该适用于任何RDBMS。)
如果您无法创建永久表,您可以创建一个临时表:
WITH Injury AS (SELECT a AS injuryCode, b AS severity, c AS description
FROM (VALUES ('1', 1, 'Slight'),
('2', 2, 'Serious'),
('3', 3, 'Fatal'),
('4', 0, 'Not Injured')) I(a, b, c))
SELECT AggregateAccident.reportNumber, Injury.injuryCode, Injury.description,
AggregateAccident.victimCount
FROM (SELECT Accidents.reportNumber, MAX(Injury.severity) as severity,
COUNT(*) as victimCount
FROM Accidents
JOIN Injury
ON Injury.injuryCode = Accidents.injuryCode
GROUP BY Accidents.reportNumber) AggregateAccident
JOIN Injury
ON Injury.severity = AggregateAccident.severity
ORDER BY AggregateAccident.reportNumber
(和updated SQL Fiddle)
WITH
子句构造了所谓的公用表表达式(CTE),基本上是内联视图或临时表定义。这也可以使用子查询来完成,但是当我引用Injury
两次时,使用CTE意味着我只需要编写包含的信息一次(如果CTE是其他查询的结果,这可能有帮助表现也是如此)。最新/当前的RDBMS支持此功能(特别是MySQL不支持),包括DB2。
答案 1 :(得分:0)
这样的东西? (未经测试)。
SELECT REPORTNUMBER,
CASE INJURYCODE
WHEN 1 THEN 'SLIGHT'
WHEN 2 THEN 'Serious'
WHEN 3 THEN 'FATAL'
ELSE 'UNKNOWN'
END ACCIDENT_STATUS,
INJURYCOUNT
FROM (
SELECT REPORTNUMBER,
MAX(CASE INJURYCODE WHEN 4 THEN 0 ELSE INJURYCODE END) INJURYCODE,
COUNT(1) INJURYCOUNT,
FROM ACCIDENTS
GROUP BY REPORTNUMBER
)
答案 2 :(得分:0)
这不是一个答案,而是一种提高技能的尝试。
如果您将伤害代码存储为如下数字:
0 = Not injured 1 = Slight 2 = Serious 3 = Fatal
然后你可以使用这个简单明了的SQL:
select reportnumber, max(injurycode) as injurycode, count(*) as involved
from accidents
group by reportnumber
这是一个小提琴来说明它:http://sqlfiddle.com/#!2/87faf/1