Очень упрощенная настройка проблемы.объединить несколько запросов выбора в один, чтобы избежать множественного прохода над огромной таблицей
Таблица A содержит столбцы rz_id и sHashA. Таблица A очень большая.
Таблица B содержит столбцы scode и sHashB. Может быть много значений sHashB , соответствующих конкретному значению scode. Таблица B относительно велика меньше, чем таблица A.
Для каждого из значений scode (около 200 из них) я должен выполнить запрос, как показано ниже (в этом случае в этом случае scode равен 500).
select count(distinct rz_id) from A where substr(sHashA, 1, 5) in (select substr(sHashB, 1, 5) from B where scode = 500);
Для каждого значения SCODE я пишу запрос, как выше, так что я в конечном итоге с 200 запросов, как так
select count(distinct rz_id) from A where substr(sHashA, 1, 5) in (select substr(sHashB, 1, 5) from B where scode = 500);
select count(distinct rz_id) from A where substr(sHashA, 1, 5) in (select substr(sHashB, 1, 5) from B where scode = 501);
select count(distinct rz_id) from A where substr(sHashA, 1, 5) in (select substr(sHashB, 1, 5) from B where scode = 502);
.
.
.
select count(distinct rz_id) from A where substr(sHashA, 1, 5) in (select substr(sHashB, 1, 5) from B where scode = 700);
Проблема в том, что это в конечном итоге происходит за большим столом 200 раз , что отнимает много времени. Я хочу добиться этого с помощью одного прохода (один запрос).
Я подумал о сделать таблицу с таким количеством строк, как таблицы А и столько дополнительных столбцов как таблицы B с помощью запроса, как
select /*+ streamtable(a) */ a.*, if(substr(sHashA, 1, 5) in (select
substr(sHashB, 1, 5) from B where scode = 500, 1, 0) as scode_500,
if(substr(sHashA, 1, 5) in (select substr(sHashB, 1, 5) from B where
scode = 501, 1, 0) as scode_501, ... if(substr(sHashA, 1, 5) in
(select substr(sHashB, 1, 5) from B where scode = 700, 1, 0) as
scode_700 from A a;
Это было бы выход 0 или 1, в каждом из 200 столбцов соответствующий scode для строки таблицы A. Позже я смог подвести итоги столбцам, чтобы получить счет. Поскольку я также заинтересован в оценке перекрытия отсчетов между любыми двумя кодами, которые я думал о приведенной выше таблице.
Но я получаю ошибку синтаксического анализа, и я подозреваю, что запросы недопустимы внутри операторов IF.
Вопрос в конце концов заключается в следующем: как я могу свести все эти запросы к одному запросу, чтобы в итоге я столкнулся с строками огромной таблицы только один раз? Также представьте альтернативные способы обработки этого счета, учитывая, что я также заинтересован в перекрытии.
Спасибо. Не могли бы вы объяснить, как «substr (sHashA, ..) = substr (sHashB, ..)» будет работать, если для одного кода может быть несколько sHashB? Обмен «in» с «=» и устранение подзапроса select не ясен для меня. – awhan
Это внутреннее соединение, которое имеет такой же эффект с вашим «in (subquery)». Присоединиться получает все матчи. Единый sHashB, несколько sHashB или без sHashB для данного кода не являются проблемами. Все покрыто. То, что вы сделали в своем запросе, заключалось в том, чтобы реализовать внутреннее соединение по-другому. –
Единственное, что можно считать разницей в том, что: этот запрос не возвращает коды, которые не используются. Поэтому подсчет недостающих кодов равен нулю. –