Я выполняю следующий запрос в нашей базе данных и пытаюсь вернуть значение счетчика как 0, если его нет, но с этим возникают проблемы. Может ли кто-нибудь помочь помочь и объяснить, как это сделать
select state, count(phone_number) from VOIP_PHONE_NUMBER_POOL
where status = 3
group by state
order by state asc;
Например, в настоящее время мой запрос возвращает что-то вроде этого
State Count
AZ 25
Когда я хочу, чтобы он возвращал пустые значения и выглядел так
State Count
AZ 25
CA 0
К сожалению, нет, это ограничено этой таблицей. Я провел некоторое исследование перед публикацией, и я знаю, что мог бы сделать это с помощью левого соединения, если бы это было так. Я немного в тупике, как я могу сделать это без этого, хотя.
Как же узнать, какие значения state
вы хотите отобразить в конечном результате? Если VOIP_PHONE_NUMBER_POOL
имеет все значения состояния, но не status = 3
, вы можете выполнить самосоединение, которое предлагает @LittleFoot. Но это будет очень дорого, если предположить, что это достаточно большой стол.
Бесплатных обедов не бывает, @Justin :)
@Littlefoot - Полностью согласен. Однако, если объемы данных не являются действительно странными, я бы настоятельно предпочел создать новую таблицу state
, чтобы иметь нужные вам строки. В частности, если в большой таблице фактов есть некоторые проблемы с качеством данных (я видел множество систем, в которых были данные для 70 или 80 из 50 штатов США :-))
Я согласен, @Justin. Модель данных выглядит как неправильно; по крайней мере, таблица voip_phone_number_pool
не нормализована. Как вы сказали, state
должна быть отдельной таблицей, на которую ссылается voip_...
. Что ж, мой запрос был просто примером того, как «решить» эту проблему.
Это имитирует то, что у вас есть сейчас:
SQL> with voip_phone_number_pool (state, phone_number, status) as
2 (select 'AZ', 1234, 3 from dual union all
3 select 'AZ', 2232, 3 from dual union all
4 select 'AZ', 4444, 3 from dual union all
5 select 'AZ', 7756, 1 from dual union all
6 --
7 select 'CA', 9999, 1 from dual
8 )
9 select state,
10 count(phone_number)
11 from voip_phone_number_pool
12 where status = 3
13 group by state
14 order by state;
ST COUNT(PHONE_NUMBER)
-- -------------------
AZ 3
SQL>
Для состояния CA
, в котором есть status = 3
, нет строки, поэтому этот запрос не возвращает его.
Что вы можете сделать, так это использовать внешнее самосоединение таким образом:
SQL> with voip_phone_number_pool (state, phone_number, status) as
2 (select 'AZ', 1234, 3 from dual union all
3 select 'AZ', 2232, 3 from dual union all
4 select 'AZ', 4444, 3 from dual union all
5 select 'AZ', 7756, 1 from dual union all
6 --
7 select 'CA', 9999, 1 from dual
8 ),
9 states as
10 (select distinct state from voip_phone_number_pool)
11 select s.state,
12 count(v.phone_number)
13 from states s left join voip_phone_number_pool v on v.state = s.state
14 and v.status = 3
15 group by s.state
16 order by s.state;
ST COUNT(V.PHONE_NUMBER)
-- ---------------------
AZ 3
CA 0
SQL>
states
CTE выбирает все состоянияvoip_phone_number_pool
status = 3
) должно быть перемещено в соединение (строка № 14); если вы оставите это в предложении where
, вы не получите желаемого результатаДа, я думаю, что мне придется это сделать, спасибо за помощь с этим.
Если в таблице фактов (VOIP_PHONE_NUMBER_POOL) нет строк с определенным состоянием, вы не получите такого результата только при запросе этой таблицы.
Вам нужно будет соединить вашу таблицу фактов с таблицей измерений (таблицей со всеми возможными состояниями), чтобы получить желаемые значения.
Например, предположим, что у вас есть такая таблица измерений и она называется «state_info»:
SELECT s.state,
COUNT(v.phone_number) AS phone_number_count
FROM state_info s
LEFT OUTER JOIN voip_phone_number_pool v
ON s.state = v.state
GROUP BY s.state;
Если таблица фактов не существует, создайте ее, используя обычное табличное выражение: WITH state_info AS ( SELECT 'AL' AS state FROM DUAL UNION ALL SELECT 'AK' AS state FROM DUAL UNION ALL ...... SELECT 'WY' AS state FROM DUAL ) SELECT s.state, COUNT(v.phone_number) AS phone_number_count FROM state_info s LEFT OUTER JOIN voip_phone_number_pool v ON s.state = v.state GROUP BY s.state;
Спасибо, я создал столбец в одной из наших таблиц для отслеживания состояний, и это сработало.
SELECT s.state,
COUNT(v.phone_number) AS phone_number_count
FROM CORP_ACCT s
LEFT OUTER JOIN voip_phone_number_pool v
ON s.state = v.state
GROUP BY s.state;
работал на меня
Есть ли другая таблица со всеми допустимыми значениями
state
, которые вы хотели бы отобразить в своем результате?