Sql 你很普通。它们被称为“信用备忘录”,是为了退货和退款等目的而发行的。也许我不会在pay列中将它们建模为负值,但我也不会首先创建一个包含八个“pay”列的表。当这是您的初始数据模型时,我会说您处于“一切皆有可能”的领域。我喜欢您使用基数处理空值的方式符合OP
Sql 你很普通。它们被称为“信用备忘录”,是为了退货和退款等目的而发行的。也许我不会在pay列中将它们建模为负值,但我也不会首先创建一个包含八个“pay”列的表。当这是您的初始数据模型时,我会说您处于“一切皆有可能”的领域。我喜欢您使用基数处理空值的方式符合OP,sql,oracle,distinct,Sql,Oracle,Distinct,你很普通。它们被称为“信用备忘录”,是为了退货和退款等目的而发行的。也许我不会在pay列中将它们建模为负值,但我也不会首先创建一个包含八个“pay”列的表。当这是您的初始数据模型时,我会说您处于“一切皆有可能”的领域。我喜欢您使用基数处理空值的方式符合OP的要求。就我个人而言,我不会对UNIQUEPAYS计算一个空的支付值,但问题是。我认为,VALUES()比dual union all@Hogan的好-据我所知,只有SQL Server和PostgreSQL支持类似值(1,'asdf1',10
你很普通。它们被称为“信用备忘录”,是为了退货和退款等目的而发行的。也许我不会在pay列中将它们建模为负值,但我也不会首先创建一个包含八个“pay”列的表。当这是您的初始数据模型时,我会说您处于“一切皆有可能”的领域。我喜欢您使用
基数
处理空值的方式符合OP的要求。就我个人而言,我不会对UNIQUEPAYS计算一个空的支付值,但问题是。我认为,VALUES()
比dual union all@Hogan的好-据我所知,只有SQL Server和PostgreSQL支持类似值(1,'asdf1',10,20,10),(2,'asdf2',…),…
的构造。如果你是这个意思的话。Oracle只允许在insert语句中使用值
。。呃。。一组值。SQL标准的另一部分Oracle不支持?我只是在google上搜索了@Hogan-OK,然后JavaDB也支持它。不幸的是,Oracle RDBMS仍然没有。(Oracle的doc站点涵盖了他们的所有产品,包括MySQL,这也引起了很多混乱。)有趣的是,这里的一个贡献者。
ID Description Pay1 Pay2 Pay3 #UniquePays
1 asdf1 10 20 10 2
2 asdf2 0 10 20 3
3 asdf3 100 100 100 1
4 asdf4 0 10 3
nvl(length(length(Pay1)),0)
+nvl(length(length(Pay2)),0)
+nvl(length(length(Pay3)),0) "NumPays"
CREATE TYPE number_list AS TABLE OF NUMBER;
with t (ID, Description, Pay1, Pay2, Pay3) as (
select 1, 'asdf1', 10, 20, 10 from dual
union all select 2, 'asdf2', 0, 10, 20 from dual
union all select 3, 'asdf3', 100, 100, 100 from dual
union all select 4, 'asdf4', null, 0, 10 from dual
)
SELECT id,
description,
pay1,
pay2,
pay3,
(SELECT COUNT (DISTINCT NVL (TO_CHAR (COLUMN_VALUE), '#NULL#'))
FROM TABLE (number_list (pay1, pay2, pay3))) uniquepays
FROM t;
ID DESCR PAY1 PAY2 PAY3 UNIQUEPAYS
---------- ----- ---------- ---------- ---------- ----------
1 asdf1 10 20 10 2
2 asdf2 0 10 20 3
3 asdf3 100 100 100 1
4 asdf4 0 10 3
select id, description, count(*) unique_pays from (
select id, description, nvl(pay1, -1) from mytable
union select id, description, nvl(pay2, -1) from mytable
union select id, description, nvl(pay3, -1) from mytable
union select id, description, nvl(pay4, -1) from mytable
union select id, description, nvl(pay5, -1) from mytable
union select id, description, nvl(pay6, -1) from mytable
union select id, description, nvl(pay7, -1) from mytable
union select id, description, nvl(pay8, -1) from mytable
) x
group by id, description
ID Description Pay1 Pay2 Pay3
1 asdf1 10 20 10
ID seq Description Pay
1 1 asdf1 10
1 2 asdf1 20
1 3 asdf1 10
cardinality(set(t_num(pay1, pay2, pay3))) as uniquepays
cardinality(set(t_num(pay1, pay2, pay3, pay4, pay5, pay6, pay7, pay8))) as uniquepays
create type t_num as table of number
/
with t (ID, Description, Pay1, Pay2, Pay3) as (
select 1, 'asdf1', 10, 20, 10 from dual
union all select 2, 'asdf2', 0, 10, 20 from dual
union all select 3, 'asdf3', 100, 100, 100 from dual
union all select 4, 'asdf4', null, 0, 10 from dual
)
select id, description, pay1, pay2, pay3,
cardinality(set(t_num(pay1, pay2, pay3))) as uniquepays
from t
order by id;
ID DESCR PAY1 PAY2 PAY3 UNIQUEPAYS
---------- ----- ---------- ---------- ---------- ----------
1 asdf1 10 20 10 2
2 asdf2 0 10 20 3
3 asdf3 100 100 100 1
4 asdf4 0 10 3
with
inputs( ID, Description, Pay1, Pay2, Pay3 ) as (
select 1, 'asdf1', 10, 20, 10 from dual union all
select 2, 'asdf2', 0, 10, 20 from dual union all
select 3, 'asdf3', 100, 100, 100 from dual union all
select 4, 'asdf4', cast(null as number), 0, 10 from dual
)
-- End of TEST data (not part of solution!) SQL query begins BELOW THIS LINE.
select id, description, pay1, pay2, pay3,
1
+ case when nvl(pay2, -1) not in (nvl(pay1, -1))
then 1 else 0 end
+ case when nvl(pay3, -1) not in (nvl(pay1, -1), nvl(pay2, -1))
then 1 else 0 end
as distinct_pays
from inputs
order by id -- if needed
;
ID DESCRIPTION PAY1 PAY2 PAY3 DISTINCT_PAYS
-- ------------ ------- ------- ------- -------------
1 asdf1 10 20 10 2
2 asdf2 0 10 20 3
3 asdf3 100 100 100 1
4 asdf4 0 10 3
4 rows selected.