我在SQL Server中执行此查询并且它工作正常但是当我尝试在Oracle中执行它时,它没有给出相同的结果。
你可以在我附带的照片中看到一个客户的数据,它有代码1,2,4,8,他应该得到0.70值代码1,2,4然后代码为8他应该得到0.75所以在乘法后它应该返回0.52作为值。我在Oracle中通过nvl替换为null来尝试它,但它返回1而不是0.52。请帮助我在oracle支持的查询中转换此查询,该查询将返回相同的结果。
这是我的查询
SELECT [id] ,[name],r = isnull(nullif(
max(CASE WHEN [code] IN (1,2,4) then 0.70 else 0 end)
,0),1)
* isnull(nullif(
min(CASE WHEN [code] IN (1,2) then 0 else 1 end)
* max(CASE WHEN [code] IN (4) then 0.20 else 0 end)
,0),1)
* isnull(nullif(
max(CASE WHEN [code] IN (8) then 0.75 else 0 end)
,0),1)
FROM (values (1, 'ali',4)
,(1, 'ali',1)
,(1, 'ali',8)
,(1, 'ali',2)
,(2, 'sunny',1)
,(4, 'arslan',4)) as t(id, name,code)
GROUP BY id, name;
答案 0 :(得分:0)
由于你现在正在增加得分,首先我们需要决定,如果不匹配代码,得分是多少。我想,它应该是0。 接下来,我们应该将所有可能的代码分成独立的组,即哪些结果不依赖于其他组成员。这里是(1,2,4)和(8)。并为每个组定义规则。 所以
SELECT [id] ,[name],r =
-- At least one of values needed to get score > 0
MAX(CASE WHEN code IN (1,2,4, 8) THEN 1.0 ELSE 0.0 END) *
-- Now rules for every independent set of codes. Rule should return score if matched or 1.0 if not matched
-- (1,2,4)
coalesce(MAX(CASE WHEN [code] IN (1,2,4) THEN 0.70 END), 1.0 ) *
-- (8)
coalesce(MAX(CASE WHEN [code] IN (8) THEN 0.75 END), 1.0)
-- more ?
FROM (values (1, 'ali',4)
,(1, 'ali',1)
,(1, 'ali',8)
,(1, 'ali',2)
,(2, 'sunny',1)
,(4, 'arslan',4)) as t(id, name,code)
GROUP BY id, name;
答案 1 :(得分:0)
查询中有一些SQL Server的东西不是标准的SQL:
[]
- 删除它们;你在这里不需要它们(否则你会使用标准的SQL引号"")r = expression
- 代表别名。将其更改为标准SQL expression AS r
ISNULL(expression, value)
- 将其更改为标准SQL COALESCE(expression, value)
或Oracle NVL(expression, value)
NULLIF(expression, value)
- 你可以保留; Oracle也支持它values (), (), ...
- 替换为SELECT FROM DUAL UNION ALL子查询你得到:
select
id,
name,
coalesce(nullif( max(case when code in (1,2,4) then 0.70 else 0 end), 0), 1) *
coalesce(nullif( min(case when code in (1,2) then 0 else 1 end) *
max(case when code in (4) then 0.20 else 0 end) , 0), 1) *
coalesce(nullif( max(case when code in (8) then 0.75 else 0 end), 0), 1) as r
from
(
select 1 as id, 'ali' as name, 4 as code from dual
union all
select 1 as id, 'ali' as name, 8 as code from dual
union all
select 1 as id, 'ali' as name, 2 as code from dual
union all
select 2 as id, 'sunny' as name, 1 as code from dual
union all
select 4 as id, 'arslan' as name, 4 as code from dual
)
group by id, name;
然而,计算不必要地复杂化:
coalesce(nullif( max(case when code in (1,2,4) then 0.70 else 0 end), 0), 1)
表示如果至少有一个匹配,则0.70否则0变为null,变为1.所以它与
相同min(case when code in (1,2,4) then 0.70 else 1 end)
所以,如果我没有弄错的话,整个计算就变成了:
case when max(case when code in (1,2) then 1 end) = 1
then 0.7 else max(case when code = 4 then 0.14 else 1 end) end *
min(case when code = 8 then 0.75 else 1 end) as r
或
case when max(case when code in (1,2) then 1 end) = 1 then 0.7
when max(case when code = 4 then 1 end) = 1 then 0.14
else 1
end *
min(case when code = 8 then 0.75 else 1 end) as r
嗯,有很多方法可以写这个。
答案 2 :(得分:0)
以下代码应该为您提供您期望的答案;
CREATE TABLE #TestData (ID int, Name varchar(10), Code int)
INSERT INTO #TestData (ID, Name, Code)
VALUES
(1,'ali',4)
,(1,'ali',1)
,(1,'ali',8)
,(1,'ali',2)
,(2,'sunny',1)
,(4,'arslan',4)
SELECT DISTINCT
a.id
,a.Name
,COALESCE(b.HasCode1, b.HasCode2, b.HasCode4,1) * COALESCE(b.HasCode8,1) Result
FROM (SELECT ID, Name FROM #TestData GROUP BY ID, Name) a
LEFT JOIN
(
SELECT
ID
,Name
,SUM(CASE WHEN CODE = 1 THEN 0.7 END) HasCode1
,SUM(CASE WHEN CODE = 2 THEN 0.7 END) HasCode2
,SUM(CASE WHEN CODE = 4 THEN 0.7 END) HasCode4
,SUM(CASE WHEN CODE = 8 THEN 0.75 END) HasCode8
FROM #TestData
GROUP BY
ID
,Name
) b
ON a.ID = b.ID
AND a.Name = b.Name
DROP TABLE #TestData
答案 3 :(得分:0)
如果我了解你之后的情况(即,对于每种情况,id / name组合需要指定所有代码),那么这可能会完成你之后的工作。你可能想在val列上添加某种trunc / floor / round函数,如果你在2位小数的答案之后,但是:
with t as (select 1 id, 'ali' name, 4 code from dual union all
select 1 id, 'ali' name, 1 code from dual union all
select 1 id, 'ali' name, 8 code from dual union all
select 1 id, 'ali' name, 2 code from dual union all
select 2 id, 'ali' name, 4 code from dual union all
select 2 id, 'ali' name, 8 code from dual union all
select 3 id, 'bob' name, 1 code from dual union all
select 3 id, 'bob' name, 2 code from dual union all
select 3 id, 'bob' name, 8 code from dual),
res as (select id,
name,
case when count(distinct case when code in (1, 2, 4) then code end) = 3 then 0.7
when count(distinct case when code in (1, 2) then code end) = 2 then 0.5
else 1
end case_1_2_and_poss_4,
case when count(distinct case when code = 8 then code end) = 1 then 0.75 else 1 end case_8
from t
group by id, name)
select id,
name,
case_1_2_and_poss_4 * case_8 val
from res;
ID NAME VAL
---------- ---- ----------
1 ali 0.525
2 ali 0.75
3 bob 0.375