2014-06-17 4 views
0

Привет, мне сложно объединить две записи (из одной таблицы) по одному запросу. Идея заключается в том, что столбец DATE_FIELD - это тип даты, а ColA - целочисленный тип данных.Объединение двух строк в одном запросе на выбор

Для иллюстрации моего вопроса, я приложил изображение ниже

enter image description here

1.) сырой стол. 2.) Является желаемым выходом.

P.S. Фильтр для DATE_FIELD не является простым предложением WHERE DATE_FIELD IN.

Например, я хотел получить DATE_FIELD = 12/30/2013. Тогда мне нужно, чтобы получить Предыдущую Sept DATE_FIELD также, что является 9/30/2013 программно с помощью этого запроса, который я получил от сети:

CASE 
      WHEN MONTH(DATE_FIELD) < 10 
      THEN 
      (cast(CAST((DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
      ELSE 
      (cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
END 

Вот мой текущий сценарий SQL (который не может получить эквивалент COLA для фильтра Предыдущего Sept:

SELECT DATE_FIELD, ColA, 
CASE 
WHEN MONTH(DATE_FIELD) < 10 
THEN 
(cast(CAST((YEAR(DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
ELSE 
(cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
END AS PREVIOUS, 
(
SELECT ColA 
FROM TABLE_A 
WHERE DATE_FIELD = 
CASE 
    WHEN MONTH(DATE_FIELD) < 10 
    THEN 
    (cast(CAST((YEAR(DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    ELSE 
    (cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    END 
) AS PYE_colA 
FROM TABLE_A 
WHERE DATE_FIELD = '12/30/2013' 

Благодаря

+0

В этом случае, ИМО, это имеет значение, когда выход этого запроса идет, потому что объединение данных таким образом, не обязательно является оптимальным. Если вы планируете показывать пользователю, то вы не хотите совмещать этот путь в запросе, а не в пользовательском интерфейсе. Если ему нужно перейти в другую БД, из вашего вопроса неясно, какова основа данных. Вместо кода, пожалуйста, объясните словами, как вы хотите объединить данные (например, как выбрать даты, которые будут объединены в одну строку). –

+0

Привет Омер, главная цель - получить среднее значение между выбранным DATE и SEPT-эквивалентными данными. Я обновляю изображение, чтобы описать, как выбрать сочетаемые строки. – ChiSen

+0

Я не понимаю, как вы добираетесь до данных. Вы начинаете с '12/30/2013 '. Для этой даты есть две записи. Почему вы показываете 99, а не 0? Связано ли это с StoreID (который вы не используете в своем запросе)? И как вы добираетесь с '12/30/2013 'до '09/30/2013'? Это всегда последний день данного месяца минус три? Или как вы доберетесь до сентября и до 30 сентября в частности? –

ответ

1

ли перекрестное соединение с одной и той же таблицей и использовать структуру СЛУЧАЯ только в предложении, где:

SELECT a.DATE_FIELD AS DATE_FIELD_1, 
    a.ColA AS ColA_1, 
    b.DATE_FIELD AS DATE_FIELD_2, 
    b.ColA AS ColA_2 
FROM TABLE_A a 
CROSS JOIN TABLE_A b 
WHERE DATE_FIELD_1 = 'your date' 
AND DATE_FIELD_2 = (
    CASE 
    WHEN MONTH(DATE_FIELD_1) < 10 
    THEN 
     (cast(CAST((YEAR(DATE_FIELD_1) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    ELSE 
     (cast(CAST((YEAR(DATE_FIELD_1)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    END) 
; 

Другая возможность основана на Торстен Kettners замечания:

SELECT a.DATE_FIELD AS DATE_FIELD_1, 
    a.ColA AS ColA_1, 
    b.DATE_FIELD AS DATE_FIELD_2, 
    b.ColA AS ColA_2 
FROM TABLE_A a 
INNER JOIN TABLE_A b 
ON b.DATE_FIELD = (
    CASE 
    WHEN MONTH(a.DATE_FIELD) < 10 
    THEN 
     (cast(CAST((YEAR(a.DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    ELSE 
     (cast(CAST((YEAR(a.DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    END) 
WHERE a.DATE_FIELD = 'your date' 
; 
+2

Это, кстати, не крест. Это внутреннее соединение: * AND ** b **. DATE_FIELD = (CASE ** a **. DATE_FIELD ...) *. Вместо этого вы должны использовать INNER JOIN и переместить предложение в положение ON, чтобы более четко показать, что вы делаете. Более того, на мой взгляд, вы немного запутываете вещи, используя DATE_FIELD_1/2 в своем предложении WHERE, а затем a/b.DATE_FIELD, который будет более четко показывать, как вы присоединяетесь к таблице. –

+0

Ну, по-моему, это сначала крест, а затем его строки ограничены теми, которые соответствуют моему предложению WHERE. Я понимаю это неправильно? –

+0

Да. Перекрестное соединение - это то, где вы соединяете две таблицы * несвязано *. Вы строите так называемый декартовый продукт. Однако, поскольку вы, однако, присоединяетесь к двум таблицам * * (есть критерии, чтобы соответствовать их записям), вы фактически выполняете внутреннее соединение. Только вы скрываете это от читателя (например, чтобы имитировать устаревший синтаксис 'FROM a, b WHERE a.x = b.y'). Не делай этого. –

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