我需要在列上计算不同的值,例如:
Hours
1
1
2
null
null
null
结果必须是: 3 。我的疑问是:
select count(distinct hour) from hours;
但它返回:2。我也测试过:
select count(*) from hours group by hour
但它返回三行:
(1) 3
(2) 2
(3) 1
如何将空值计算为1值并使用distinct来避免计算重复值?
我正在学习高级SQL,他们想要我对所有解决方案的这些要求:
尽量减少解决查询所需的子查询数量。 此外,您不能使用以下结构:
- FROM或SELECT中的SELECT。您可以拥有子查询(在WHERE或HAVING中选择)
- 聚合函数的组合,例如COUNT(COUNT。...),SUM(COUNT ...))等。
- UNION如果可以避免它。
- 非标准功能(如NVL)
- CASE
答案 0 :(得分:23)
select count(distinct col1) + count(distinct case when col1 is null then 1 end)
from YourTable
答案 1 :(得分:17)
如果小时是一个数字,那么它是否只能是一个整数:
select count(distinct coalesce(hour, 0.1)) cnt from test;
否则,如果它可以是任何浮点,则将NULL更改为char字符串。
例如
select count(distinct coalesce(to_char(hour), 'a')) cnt from test;
答案 2 :(得分:7)
select
count(0)
from
(
select distinct hour from hours
)
答案 3 :(得分:2)
SELECT
( SELECT COUNT(DISTINCT hour)
FROM hours
)
+ CASE WHEN EXISTS
( SELECT *
FROM hours
WHERE hour IS NULL
)
THEN 1
ELSE 0
END
AS result
FROM dual ;
答案 4 :(得分:2)
也许
select count(distinct hour||' ') from hours;
会吗?
答案 5 :(得分:2)
<textarea>
答案 6 :(得分:1)
我认为您的要求非常奇怪,因为您几乎肯定只需使用NVL()
,COALESCE()
或CASE
即可获得更高效的查询。但是,我设法仅使用子查询获得正确的结果(并且应对NULL
值的存在与否)。如果不在FROM
子句中使用子查询,我就无法做到这一点。
查询1 :
SELECT nnh.not_null_hours + nh.null_hours
FROM (
SELECT COUNT(DISTINCT t.hour) not_null_hours
FROM example_table t
) nnh
CROSS JOIN (
SELECT 1 null_hours
FROM dual
WHERE EXISTS (
SELECT 1
FROM example_table t
WHERE t.hour IS NULL
)
UNION ALL
SELECT 0 null_hours
FROM dual
WHERE NOT EXISTS (
SELECT 1
FROM example_table t
WHERE t.hour IS NULL
)
) nh
<强> Results 强>:
| NNH.NOT_NULL_HOURS+NH.NULL_HOURS |
------------------------------------
| 3 |
这需要付出很多努力来应对这些要求。一个更简单的选择是使用NVL
,然后使用两个简单选择之一......:
TO_CHAR
将非NULL值转换为数据类型VARCHAR2和NVL
,以将NULL
值转换为VARCHAR2 'NULL'
或NVL
一个您知道在结果集中永远不会出现的幻数(即由于表格上的限制)。<强> Query 1 强>:
SELECT
COUNT(DISTINCT NVL(TO_CHAR(hour), 'NULL')) using_to_char_null
, COUNT(DISTINCT NVL(hour, -1)) using_magic_number
FROM example_table
<强> Results 强>:
| USING_TO_CHAR_NULL | USING_MAGIC_NUMBER |
-------------------------------------------
| 3 | 3 |
答案 7 :(得分:1)
除了COUNT
之外,Andres的答案是完全符合要求并且完全不使用任何功能的答案:
select count(distinct hour||' ') from hours;
我为了另一个目的寻找相同的东西(我可以使用任何东西)但是在我看到这个之前它对我来说似乎不正确或有效,谢谢Andres,这样一个简单的解决方案,但却是一个强大的解决方案。 / p>
答案 8 :(得分:0)
我最接近指定标准的是: (SQL Fiddle)
查询1 :
SELECT COUNT(*)
FROM example_table t1
WHERE t1.ROWID IN (
SELECT MAX(t2.ROWID)
FROM example_table t2
GROUP BY t2.hour
)
<强> Results 强>:
| COUNT(*) |
------------
| 3 |
在给定其他限制的情况下,不确定是否允许ROWID
伪列,但它可以正常处理NULL
值。我不认为ROWID存在于Oracle之外,因此这可能违背了问题的精神,但它至少符合列出的标准。
答案 9 :(得分:-1)
SELECT COUNT(hour)
FROM hours
NULLS不计算在内。
知道了!我不能正确阅读要求。
SELECT COUNT(DISTINCT COALESCE(hour,-1))
FROM hours
答案 10 :(得分:-1)
Select count(1)-count(hour) from hours;
它将为您提供输出3