2013-06-29 5 views
0

Рассмотрите следующее заявление SELECT, где я получаю разные значения от licensee & таблиц и получаю результаты, которые я хочу.Oracle Select statement подсчет числа из двух таблиц

SELECT 
    licensee.license_type_id, 
    COUNT(*) AS count_all, 
    COUNT(CASE WHEN licensee.citizen = 'US' THEN 1 ELSE NULL END) AS count_a, 
    COUNT(CASE WHEN licensee.citizen = 'Other' AND licensee.flag = 'Y' THEN 1 ELSE NULL END) AS count_b, 
    COUNT(CASE WHEN licensee.flag = 'N' THEN 1 ELSE NULL END) AS count_c 
FROM licensee 
INNER JOIN license_type ON licensee.license_type_id = license_type.id 
GROUP BY licensee.license_type_id; 

Сценарий: Основная таблица «лицензиат» разделен на две таблицы сказать «licensee_us» и «licensee_other» на основе «гражданина» колонны. Обе новые таблицы не имеют столбца «гражданин». Таблица «licensee_us» имеет записи из таблицы «licensee» (citizen = 'US') & Аналогично таблица «licensee_other» имеет записи из таблицы «licensee» (citizen = «Other») & обе таблицы имеют столбец JOIN-ing «license_type_id» '& column' flag '.

Теперь, КАКОЙ ЭФФЕКТИВНЫЙ способ получить те же самые значения, что и предыдущий запрос SELECT, с новыми двумя таблицами GROUP-ed by license_type_id? Дайте мне знать, если необходимо какое-либо разъяснение. Я действительно ищу «ЭФФЕКТИВНЫЙ» способ сделать это. Что-то другое, кроме необходимости использовать UNION, если таковой имеется.

ответ

0

Я ожидаю, что наиболее эффективным способом будет использование UNION ALL для повторного объединения двух таблиц и выполнения запроса точно так же, как у вас есть. По какой-то причине, я чувствую, что это не то, что вы хотите услышать:

SELECT 
     licensee.license_type_id, 
     COUNT(*) AS count_all, 
     COUNT(CASE WHEN licensee.citizen = 'US' THEN 1 ELSE NULL END) AS count_a, 
     COUNT(CASE WHEN licensee.citizen = 'Other' AND licensee.flag = 'Y' THEN 1 ELSE NULL END) AS count_b, 
     COUNT(CASE WHEN licensee.flag = 'N' THEN 1 ELSE NULL END) AS count_c 
    FROM 
(select 'US' as citizen, licensee_us.* UNION ALL SELECT 'Other' as citizen, licensee_other.*) as licensee 
    INNER JOIN license_type ON licensee.license_type_id = license_type.id 
    GROUP BY licensee.license_type_id; 

Вы можете попробовать кучу суб-выбирает, но я не думаю, что они будут особенно эффективными. Вы знаете свои данные, хотя, возможно, стоит попробовать.

Почему вы их раскалываете? Я не говорю, что вы не должны этого делать, если это имеет смысл, но, возможно, поддерживает одну и ту же структуру таблицы и имеет возможность фильтровать US &. Другие для использования в других сценариях - это путь.

+0

Изменение структуры таблиц вне моего контроля или сферы применения этого вопроса. UNION ALL - это то, что я тоже подумал, и по какой-то причине я не чувствую себя самым эффективным способом. Извините, я должен был упомянуть об этом в моем первоначальном вопросе. – Bala

+0

Вам нужно будет фактически попробовать различные решения, но я бы просто сделал это, чтобы обойти меняющуюся структуру таблицы и справиться с производительностью/эффективностью, если возникнет такая необходимость. Вы действительно хотите рассчитывать на объединение двух таблиц, поэтому вряд ли это необоснованный подход. – LoztInSpace

0

Возможно, попробуйте сгруппировать по licensee.license_type_id, гражданин, флаг?

SELECT licensee.license_type_id, COUNT(*) AS count_all , count(decode(licensee.flag,'N',null) as count_c FROM licensee INNER JOIN license_type ON licensee.license_type_id = license_type.id GROUP BY licensee.license_type_id , licensee.citizen , licensee.flag;

, если есть больше различных значений в столбцах licensee.citizen, фильтровать их в ИНЕКЕ. таким образом вы получите все требуемые счеты по-другому, вы можете использовать univot, если вы хотите их переупорядочить, обратите внимание на столбец count_c, декодирование - это просто другой синтаксис для аргумента case.

Я надеюсь, что это вам помогло, наслаждайтесь :)

Смежные вопросы