2013-07-29 5 views
2

Я видел другие подобные вопросы, и я попытался реализовать множество решений, но до сих пор ничего не понял. Эти конкретные вопросы требуют немного большей сложности. Что мне нужно сделать, так это создать таблицу и соединить столбцы с правой стороны в зависимости от определенного критерия. Это кажется достаточно простым, но есть несколько ударов, с которыми я сталкиваюсь.Расширенные инструкции SQL Select и Union

таблицы следующим образом:

ADC_DATA_COLLECTION_HEADER 

(PK)Transaction_ID | BEMSID | DEVICE | TIMESTAMP | CONFIG_NAME 

ADC_DATA_COLLECTION_APPS 

(FK)CONFIG_NAME | NUM_DATA_ELEMENTS | DATA_ELEMENT1 | DATA_ELEMENT2 | DATA_ELEMENT3 | DATA_ELEMENT4 


ADC_DATA_COLLECTION_DATA 

(FK)TRANSACTION_ID | DATA_ELEMENT_NUMBER | DATA 

Я хочу, чтобы мой конечный результат выглядеть следующим образом:

TRANSACTION_ID | DEVICE | CONFIG_NAME | DATA | DATA | DATA | DATA 

колонка «данные» заполняется с использованием таблицы ADC_DATA_COLLECTION_DATA. Первым экземпляром «данных» будет поле данных в ADC_DATA_COLLECTION_DATA, где DATA_ELEMENT_NUMBER = 1. Второй экземпляр «данных» будет полем «данные» в ADC_DATA_COLLECTION_DATA, где DATA_ELEMENT_NUMBER = 2 ... и так далее.

Самое дальнее, что я получил, это использование инструкции объединения, за исключением того, что у меня есть нули в местах, где я их не хочу. Код, который я использовал, и результаты публикуются ниже. Пока я только написал код для первых двух столбцов данных.

SELECT 
ADC_Data_Collection_header.BEMSID, 
ADC_Data_Collection_header.DEVICE, 
ADC_Data_Collection_header.CONFIG_NAME, 
null AS locationlabel, 
null AS partno 
/*null AS partno2, 
null AS DE4, 
null AS DE5, 
null AS DE6 */ 
FROM 
ADC_Data_Collection_header, 
ADC_Data_Collection_apps, 
ADC_Data_Collection_data 
WHERE 
ADC_Data_Collection_header.CONFIG_NAME = 'mobileScanning' 
AND ADC_Data_Collection_header.BEMSID = '2386531' 
AND ADC_Data_Collection_header.CONFIG_NAME = ADC_Data_Collection_apps.CONFIG_NAME 
AND (TO_DATE('7/19/2013','MM/DD/YYYY') <= timestamp AND TO_DATE('7/27/2013','MM/DD/YYYY') >= timestamp) 
AND ADC_DATA_COLLECTION_HEADER.transaction_ID = ADC_DATA_COLLECTION_DATA.Transaction_ID 

UNION 
SELECT 
null as BEMSID, 
null as DEVICE, 
null as CONFIG_NAME, 
ADC_Data_Collection_DATA.DATA AS locationlabel, 
null as partno 
FROM 
ADC_DATA_COLLECTION_DATA, 
ADC_Data_Collection_header, 
ADC_Data_Collection_apps 
WHERE 
ADC_DATA_COLLECTION_DATA.DATA_ELEMENT_NUMBER = 3 
AND ADC_Data_Collection_header.CONFIG_NAME = 'mobileScanning' 
AND (TO_DATE('7/19/2013','MM/DD/YYYY') <= timestamp AND TO_DATE('7/27/2013','MM/DD/YYYY') >= timestamp) 
AND ADC_DATA_COLLECTION_HEADER.transaction_ID = ADC_DATA_COLLECTION_DATA.Transaction_ID 

UNION 
SELECT 
null as BEMSID, 
null as DEVICE, 
null as CONFIG_NAME, 
null as locationlabel, 
ADC_Data_Collection_DATA.DATA AS partno 
FROM 
ADC_DATA_COLLECTION_DATA, 
ADC_Data_Collection_header, 
ADC_Data_Collection_apps 
WHERE 
ADC_DATA_COLLECTION_DATA.DATA_ELEMENT_NUMBER = 4 
AND ADC_Data_Collection_header.CONFIG_NAME = 'mobileScanning' 
AND (TO_DATE('7/19/2013','MM/DD/YYYY') <= timestamp AND TO_DATE('7/27/2013','MM/DD/YYYY') >= timestamp) 
AND ADC_DATA_COLLECTION_HEADER.transaction_ID = ADC_DATA_COLLECTION_DATA.Transaction_ID 

Результат этого появляется с нулевыми значениями, которые я не хочу иметь.

Если вы можете предложить явное решение, используя заявление объединения или исправить этот союзный подход, это было бы очень признательно. Заранее спасибо!

+0

Может поворотное запрос, что вам нужно: http://asktom.oracle.com/ pls/asktom/f? p = 100: 11: 0 :::: p11_question_id: 766825833740 –

+0

Что значит «нули в местах?» Вы можете использовать COALESCE(), чтобы изменить Nulls на все, что захотите. e, g COALESCE (locationlabel, 'NA') – rheitzman

ответ

1

Я хотел бы использовать стержень для этого:

select 
    h.transaction_id, 
    h.device, 
    h.config_name, 
    d.data1, 
    d.data2, 
    d.data3, 
    d.data4 
from 
    ADC_DATA_COLLECTION_HEADER h 
    inner join (
     select * 
     from ADC_DATA_COLLECTION_DATA 
     pivot 
     (
      max(data) 
      for data_element_number in (1 as data1, 2 as data2, 3 as data3, 4 as data4) 
    ) 
    ) d 
     on d.transaction_id = h.transaction_id 
where 
    (TO_DATE('7/19/2013','MM/DD/YYYY') <= timestamp AND TO_DATE('7/27/2013','MM/DD/YYYY') >= timestamp); 

Я поставил вместе пример SQL скрипку на: http://www.sqlfiddle.com/#!4/fe1c94/9/0

+0

. Я попробовал это, и это выглядит очень жизнеспособным решением, но я просто не могу сделать головы или хвосты этого из-за моего собственного отсутствия опыта с таблицами Pivot. –

+0

На самом деле это заняло всего несколько исследований. Я понимаю это, и он работает до совершенства! Большое спасибо за Вашу помощь! –

3

UNION дает дополнительные строки, поэтому это не подходящий инструмент для этой ситуации.

Это сокращенная версия, использующая только таблицу ADC_DATA_COLLECTION_DATA; Вы должны быть в состоянии включить это в вашем запросе:

SELECT 
    Transaction_ID, 
    MAX(CASE WHEN Data_Element_Number = 1 THEN Data END) AS Data1, 
    MAX(CASE WHEN Data_Element_Number = 2 THEN Data END) AS Data2, 
    MAX(CASE WHEN Data_Element_Number = 3 THEN Data END) AS Data3, 
    MAX(CASE WHEN Data_Element_Number = 4 THEN Data END) AS Data4 
FROM ADC_DATA_COLLECTION_DATA 
GROUP BY Transaction_ID 

Это довольно распространенная «Сводная таблица» хак для Oracle (и MySQL и SQL Server). Oracle также поддерживает PIVOT queries, но я не так хорош с ними.

Обратите внимание, что после того, как вы разместите свой окончательный запрос вместе с столбцами и Config_Name, вам нужно будет добавить эти столбцы в GROUP BY.

+0

Это дает мне огромный головной убор, но есть еще одна неточность, которую нужно исправить. Функция max возвращает только одно значение, когда мне нужно все элементы данных, которые нужно вернуть. Как стоит, я могу получить только 1 запись из этого запроса. Есть ли способ, которым мы можем вытащить несколько записей? И для пояснения, в таблице данных_секументов в общей таблице есть перекрытия, но только один идентификатор данных_ELement_Number для идентификатора транзакции. –

+0

Является ли неточность чем-то в моем запросе? Кроме того, пожалуйста, проверьте ответ от @craig, который, в отличие от меня, * освоил запрос Oracle 'PIVOT'.Нажмите ссылку в ответе Craig, чтобы увидеть и запустить запрос. –

+0

То, что я считаю неправильным, - это ограничение максимальной функции. Моя таблица результатов может возвращать максимальное значение всех данных с помощью Data_Element_Number 1. То, что я хочу, это данные, связанные со всеми данными «data_Element_number 1» –

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