Oracle SQL - левый Join на 2 таблицы не запускается - PullRequest
1 голос
/ 11 августа 2011

У кого-нибудь есть идеи, почему, когда я пытаюсь выполнить этот запрос, он просто выполняется вечно и не останавливается ??

Запросы в предложениях «С» выполняются самостоятельно.Просто когда я пытаюсь присоединиться к ним, я не могу заставить его работать должным образом ??

--Process name and input
With ProcessIn as
(
select Data.Scan_time, equipment.equipment_desc, data.serial_number

from Data, equipment

where Data.equipment = equipment.equipm_barcode and data.quality_plan = 'N/A' and        data.error_code = 'N/A' 
)

--Total process defects
,ProcessDefect as
(
select Data.Scan_time, equipment.equipment_desc, data.serial_number

from Data, equipment

where Data.equipment = equipment.equipm_barcode and (data.quality_plan <> 'N/A' or     data.error_code <> 'N/A')
)

Select concat(to_char(ProcessIn.SCAN_TIME, 'mm'), to_char(ProcessIn.SCAN_TIME, 'dd')) as "Date", ProcessIn.equipment_desc, count(ProcessIn.serial_number), count(ProcessDefect.serial_number)

from ProcessIn 
Left Join ProcessDefect
On concat(to_char(ProcessIn.SCAN_TIME, 'mm'),to_char(ProcessIn.SCAN_TIME, 'dd')) = concat(to_char(ProcessDefect.SCAN_TIME, 'mm'),to_char(ProcessDefect.SCAN_TIME, 'dd')) 
and ProcessIn.equipment_desc = ProcessDefect.equipment_desc

group by concat(to_char(ProcessIn.SCAN_TIME, 'mm'), to_char(ProcessIn.SCAN_TIME, 'dd')), ProcessIn.equipment_desc
;

ОБНОВЛЕНИЕ 20110816 Я использовал некоторые из предложений, чтобы уточнить мой запрос безуспешно.У кого-нибудь есть другие предложения?Кроме того, в любом случае, чтобы убедиться, что мой индекс используется должным образом, поскольку я новичок в их создании / использовании.Я просто использовал интерфейс Oracle для создания индекса на основе serial_number и smalldate.

Спасибо

With ProcessIn as
(
select data.smalldate, mip.mip_step_description, data.part_serial_number

from Data, MIP

where Data.equipment = MIP.equipment and data.quality_plan is null and data.error_code is null
)

,ProcessDefect as
(
select data.smalldate, mip.mip_step_description, data.part_serial_number

from Data, MIP

where Data.equipment = MIP.equipment and (data.quality_plan is not null or data.error_code is not null)
)

Select ProcessIn.smalldate, ProcessIn.mip_step_description, count(ProcessIn.part_serial_number),  count(ProcessDefect.part_serial_number)

from ProcessIn 
Left Join ProcessDefect
On ProcessIn.smalldate = ProcessDefect.smalldate
and ProcessIn.mip_step_description = ProcessDefect.mip_step_description

group by ProcessIn.smalldate, ProcessIn.mip_step_description

ОБНОВЛЕНИЕ 110820

Так что я добился определенного прогресса, но мне нужнопомогите понять одну последнюю вещь.Теперь я изменил структуру запросов так, чтобы она выглядела так:

select data.smalldate, mip.mip_step_description, error_code.error_code_en, count(case when (error_code is null and quality_plan is null) then data.part_serial_number end) as "Input", count(case when error_code is not null then data.part_serial_number end) as "Defects"

from Data

left join MIP
On data.equipment = mip.equipment

left join error_code
on data.error_code = error_code.error_code_sn 

group by data.smalldate, mip.mip_step_description, error_code.error_code_en

order by data.smalldate, mip.mip_step_description, count(data.part_serial_number) desc

Как вы можете видеть в операторе select, я использую операторы case в своих функциях count.Это отлично работает.Вывод данных выглядит следующим образом:

Date    MIP_Desc    Error_Code    Input    Defects
1/1/2011    MIP Z    (null)       100      0
1/1/2011    MIP Z    A            0        10
1/1/2011    MIP Z    B            0        15

Я бы хотел заполнить одно и то же входное значение во входном столбце во всех строках с одинаковой датой и MIP.

Вывод должен выглядеть следующим образом

Date    MIP_Desc    Error_Code    Input    Defects
1/1/2011    MIP Z    (null)       100      0
1/1/2011    MIP Z    A            100      10
1/1/2011    MIP Z    B            100      15

Любые советы ??Еще раз спасибо за помощь

Ответы [ 2 ]

1 голос
/ 11 августа 2011

Еще один способ упростить это

concat (to_char (ProcessIn.SCAN_TIME, 'mm'), to_char (ProcessIn.SCAN_TIME, 'dd')) = concat (to_char (ProcessDefect.SCAN_TIME, 'mm'), to_char (ProcessDefect.SCAN_TIME, 'dd') ))

было бы сказать что-то вроде

to_char (ProcessIn.SCAN_TIME, 'ddmm') = to_char (ProcessDefect.SCAN_TIME, 'ddmm').

Для повышения производительности вы можете создавать индексы на основе функций

создать индекс scan_time_idx для ProcessIn (to_char (ProcessIn.SCAN_TIME, 'ddmm'));

создать индекс scan_time_idx для ProcessIn (to_char (ProcessDefect.SCAN_TIME, 'ddmm'));

См. http://www.akadia.com/services/ora_function_based_index_2.html для получения дополнительной информации об индексах на основе функций.

В качестве альтернативы вы можете сохранить scan_time в отдельном столбце с именем monthday в таблице 'data' в формате to_char (tablename.SCAN_TIME, 'ddmm') и индексировать новый столбец.

После создания ваш запрос будет выглядеть следующим образом: -

With ProcessIn as
(
select Data.Scan_time, equipment.equipment_desc, data.serial_number,Data.monthday

from Data, equipment

where Data.equipment = equipment.equipm_barcode and data.quality_plan = 'N/A'    and        data.error_code = 'N/A' 
)

--Total process defects
,ProcessDefect as
(
select Data.Scan_time, equipment.equipment_desc, data.serial_number,Data.monthday

from Data, equipment

where Data.equipment = equipment.equipm_barcode and (data.quality_plan <> 'N/A' or         data.error_code <> 'N/A')
)

Select monthday as "Date", ProcessIn.equipment_desc,                                     count(ProcessIn.serial_number),     count(ProcessDefect.serial_number)

from ProcessIn 
Left Join ProcessDefect
On ProcessIn.monthday = ProcessDefect.monthday
and ProcessIn.equipment_desc = ProcessDefect.equipment_desc
group by ProcessIn.monthday, ProcessIn.equipment_desc
;
1 голос
/ 11 августа 2011

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

On concat(to_char(ProcessIn.SCAN_TIME, 'mm'),to_char(ProcessIn.SCAN_TIME, 'dd')) =
    concat(to_char(ProcessDefect.SCAN_TIME, 'mm'),to_char(ProcessDefect.SCAN_TIME, 'dd')) 

В SQL Server это довольно сильныйиндикатор того, что у оптимизатора будут проблемы с использованием индексов для выполнения операции соединения.Если ваши подзапросы дают большие наборы записей, выполнение JOIN может занять очень и очень много времени.

Если вы можете изменить предложение ON так, чтобы оно не требовало вызова функций (по возможности с обеих сторон, но по крайней мере с1) это, вероятно, немного улучшит производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...