Ответ 1
select count(distinct col1) + count(distinct case when col1 is null then 1 end)
from YourTable
Мне нужно посчитать разные значения в столбце, такие как:
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 значение и использовать отличные, чтобы избежать подсчета повторных значений?
Я изучаю продвинутый SQL, мне нужны эти требования для всех решений:
Постарайтесь минимизировать количество подзапросов, необходимых для решения запроса. Кроме того, вам не разрешено использовать следующие конструкции:
- ВЫБРАТЬ В ОТ или ВЫБРАТЬ. Вам разрешено иметь подзапросы (ВЫБЕРИТЕ в ГДЕ или В НАЛИЧИИ)
- Комбинации функций агрегирования, такие как COUNT (COUNT...)), SUM (COUNT...)) и тому подобное.
- СОЮЗ, если вы можете избежать этого.
- Нестандартные функции (такие как NVL)
- ДЕЛО
select count(distinct col1) + count(distinct case when col1 is null then 1 end)
from YourTable
если hour - это число, то если это может быть только целое число:
select count(distinct coalesce(hour, 0.1)) cnt from test;
иначе, если это может быть любая плавающая точка, измените значение NULL на строку char.
например,
select count(distinct coalesce(to_char(hour), 'a')) cnt from test;
select
count(0)
from
(
select distinct hour from hours
)
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 ;
возможно
select count(distinct hour||' ') from hours;
будет делать?
select count(distinct nvl(hour,0)) from hours;
Я бы сказал, что ваши требования довольно странные, учитывая, что вы почти наверняка получите более эффективный запрос, просто используя 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
| NNH.NOT_NULL_HOURS+NH.NULL_HOURS |
------------------------------------
| 3 |
Это потребует больших усилий, чтобы справиться с требованиями. Гораздо проще использовать NVL
, а затем один из двух простых вариантов:
TO_CHAR
для преобразования значений, отличных от NULL, к типу данных VARCHAR2 и NVL
для преобразования значений NULL
в VARCHAR2 'NULL'
илиNVL
с магическим номером, который, как вы знаете, никогда не будет присутствовать в наборе результатов (т.е. из-за ограничений в таблице).SELECT
COUNT(DISTINCT NVL(TO_CHAR(hour), 'NULL')) using_to_char_null
, COUNT(DISTINCT NVL(hour, -1)) using_magic_number
FROM example_table
| USING_TO_CHAR_NULL | USING_MAGIC_NUMBER |
-------------------------------------------
| 3 | 3 |
Ответа на этот вопрос Andres: это тот, который отвечает требованиям совершенно и без какой-либо функции, кроме COUNT
:
select count(distinct hour||' ') from hours;
Я искал то же самое для другой цели (я мог бы использовать что-либо вообще), но это не показалось мне правильным или эффективным, пока я не увидел это, спасибо Andres, такое простое решение, но мощное.
Ближе всего я могу подобрать критерии, указанные ниже: (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
)
| COUNT(*) |
------------
| 3 |
Не уверен, что псевдоколонка ROWID
разрешена, учитывая другие ограничения, но она работает и изящно обрабатывает значения NULL
. Я не думаю, что ROWID существует вне Oracle, поэтому, вероятно, это противоречит духу вопроса, но оно соответствует указанным критериям.
Вероятно, самый простой способ - использовать DUMP
:
SELECT COUNT(DISTINCT DUMP(hour)) AS distinct_count
FROM hours;
Выход: 3
Джампаоло побеждает
msgstr "выбрать количество (отличный nvl (час, 0)) от часов;"
может ты сможешь попробовать это
выберите 3 из часа;
А.. домашнее задание. Разве это не так просто?
SELECT COUNT(hour)
FROM hours
NULLS не подсчитываются.
Получил! Мой плохой для того, чтобы не правильно читать требования.
SELECT COUNT(DISTINCT COALESCE(hour,-1))
FROM hours
Select count(1)-count(hour) from hours;
Это даст вам вывод 3