2015-08-06 6 views
2

Я получил SelfJoin запросSQL SelfJoin + Left Outer РЕГИСТРИРУЙТЕСЬ Календарь

;WITH t as 
(
SELECT 
ROW_NUMBER() OVER (ORDER BY dbo.DIM_PROJECT_TECH_OBJ.FUNCTIONAL_LOCATION,DATEADD(ms, DATEDIFF(ms, '00:00:00', CONVERT(VARCHAR,REPLACE(dbo.FACT_MEASUREMENT.Doc_Time,'24:00:00','23:59:59'),102)), CONVERT(DATETIME, dbo.DIM_TIME_USAGE.DATE)) ASC) AS Rowy, 
dbo.FACT_MEASUREMENT.FACT_MEASUREMENT_KEY, 
    dbo.FACT_MEASUREMENT.Doc_Number, 
    dbo.FACT_MEASUREMENT.Created_By, 
    dbo.FACT_MEASUREMENT.Text, 
    dbo.FACT_MEASUREMENT.Doc_Time, 
    dbo.FACT_MEASUREMENT.Date_Loaded, 
    dbo.DIM_VC_MEASURE.VALUATION_CODE_AND_DESC, 
    dbo.DIM_TIME_USAGE.DATE, 
    dbo.DIM_PROJECT_TECH_OBJ.FUNCTIONAL_LOCATION, 
    dbo.DIM_VC_MEASURE.VALUATION_CODE, 
CONVERT(VARCHAR,REPLACE(dbo.FACT_MEASUREMENT.Doc_Time,'24:00:00','23:59:59'),102) AS TIME, 
DATEADD(ms, DATEDIFF(ms, '00:00:00', CONVERT(VARCHAR,REPLACE(dbo.FACT_MEASUREMENT.Doc_Time,'24:00:00','23:59:59'),102)), CONVERT(DATETIME, dbo.DIM_TIME_USAGE.DATE)) AS DATUM 
FROM 
    dbo.DIM_PROJECT_TECH_OBJ INNER JOIN dbo.FACT_MEASUREMENT ON (dbo.FACT_MEASUREMENT.PROJECT_TECH_OBJ_KEY=dbo.DIM_PROJECT_TECH_OBJ.PROJECT_TECH_OBJ_KEY) 
    INNER JOIN dbo.DIM_TIME_USAGE ON (dbo.FACT_MEASUREMENT.TIME_KEY=dbo.DIM_TIME_USAGE.TIME_KEY) 
    INNER JOIN dbo.DIM_VC_MEASURE ON (dbo.DIM_VC_MEASURE.VALUATION_CODE_KEY=dbo.FACT_MEASUREMENT.VALUATION_CODE_KEY) 
WHERE 
    dbo.FACT_MEASUREMENT.Measurement_Position = 'AVAILABILITY' 
    AND 
    dbo.DIM_PROJECT_TECH_OBJ.FUNCTIONAL_LOCATION IN ('XXX','YYY','ZZZ') 
    ) 
select t.*, tprev.DATUM AS PRE_DATUM, tprev.VALUATION_CODE AS PRE_CODE, DATEDIFF (minute,tprev.DATUM, t.DATUM) AS DELTA_MIN 
from t join 
    t tprev 
    on tprev.rowy = t.rowy - 1 AND tprev.FUNCTIONAL_LOCATION = t.FUNCTIONAL_LOCATION ; 

Это возвращает набор из поля

FUNTIONAL LOC DATUM CODE PRE_DATUM PRE_CODE (-> Other fields) 
XXX    01/07/2015 A 06/06/2015 Y 
XXX    05/07/2015 B 01/07/2015 A 
XXX    10/07/2015 C 05/07/2015 B 
YYY    03/07/2015 B 15/06/2015 K 
YYY    09/07/2015 C 03/07/2015 B 
YYY    15/07/2015 A 09/07/2015 C 

Теперь я хотел бы создать внешнее соединение с календарем (изображение из 01/07 до 10/07) даты и получить что-то вроде:

FUNTIONAL LOC DATUM CODE PRE_DATUM PRE_CODE 
XXX    01/07/2015 A 06/06/2015 Y 
XXX    02/07/2015  06/06/2015 Y 
XXX    03/07/2015  06/06/2015 Y 
XXX    04/07/2015  06/06/2015 Y 
XXX    05/07/2015 B 01/07/2015 A 
XXX    06/07/2015  01/07/2015 A 
XXX    07/07/2015  01/07/2015 A 
XXX    08/07/2015  01/07/2015 A 
XXX    09/07/2015  01/07/2015 A 
XXX    10/07/2015 C 05/07/2015 B 
YYY    01/07/2015  15/06/2015 K 
YYY    02/07/2015  15/06/2015 K 
YYY    03/07/2015 B 15/06/2015 K 
YYY    09/07/2015 C 03/07/2015 B 
YYY    10/07/2015  03/07/2015 B 

в основном, когда код не найден на календарные данных u предыдущий.

Любое предложение/идея? Спасибо заранее.

S.

+0

У вас есть, например, '02/07/2015' для FUNCTIONAL_LOCATION = 'XXX' в CTE? –

+0

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

+0

Здравствуйте, я использую SQL как базу данных. Результат имеет больше столбцов, но я только что заметил те, которые имеют решающее значение для моего желаемого результата. Но я могу опубликовать весь полный запрос, если это необходимо и необходимо. Спасибо – SimonFreeman

ответ

1

Вы можете попробовать следующие шаги:

  • определяют этот промежуточный результат и «календарь» стол в качестве цепи WITH заявления
  • выполнить LEFT JOIN из «календарного» таблицы и промежуточный результат, определенный на точке выше (некоторые БД требует указания LEFT OUTER JOIN)
  • выполнить row- насчитывающий присоединиться к технике снова по результатам двух этапов выше

Пример первых двух этапов:

WITH t as (...), 
t2 as (select t.*, tprev.time 
    from t left join 
    t tprev 
    on tprev.rowy = t.rowy - 1), 
cal as (...) 
SELECT * 
FROM cal 
LEFT JOIN t2 
ON cal.DATUM = t2.DATUM; 

Пожалуйста, обратите внимание, что:

  • промежуточный результат вашего первоначального вопроса теперь определяется как t2
  • в конечном результате вы издевались, вы не можете сохранять значения DATUM как исходные промежуточные результаты как re портирован в ваш вопрос, потому что значения отсутствуют, и я полагаю, что вы хотите, чтобы действительно отображать все значения календаря вместо этого.
  • Третью точку вышеприведенных шагов можно получить, выполнив ту же технику, что и в исходном вопросе.
  • вам нужно будет указать порядок в окончательных результатах.

Надеюсь, это поможет!

1

Вы должны cross join результат запроса с calender таблицы. Что-то вроде этого

WITH t 
    AS (SELECT Row_number() 
        OVER (
        ORDER BY Q2.FUNCTIONAL_LOCATION) AS Rowy, 
       Q1.FACT_MEASUREMENT_KEY, 
       CONVERT(VARCHAR(255), Q1.Doc_Time, 102) AS TIME 
     FROM dbo.DIM_PROJECT_TECH_OBJ Q2 
       INNER JOIN dbo.FACT_MEASUREMENT Q1 
         ON Q1.PROJECT_TECH_OBJ_KEY = Q2.PROJECT_TECH_OBJ_KEY 
     WHERE Q1.Measurement_Position = 'XXX'), 
    result 
    AS (SELECT t.*, 
       tprev.time 
     FROM t 
       LEFT JOIN t tprev 
         ON tprev.rowy = t.rowy - 1), 
    date_cook 
    AS (SELECT FUNTIONAL_LOC, 
       c.dates, 
       PRE_DATUM, 
       PRE_CODE 
     FROM result r 
       CROSS JOIN calender c 
     WHERE c.dates BETWEEN '2015-07-01' AND '2015-07-10') 
SELECT dc.FUNTIONAL_LOC, 
     dc.dates   AS DATUM, 
     Isnull(r.code, '') AS code, 
     dc.PRE_DATUM, 
     dc.PRE_CODE 
FROM date_cook dc 
     LEFT OUTER JOIN result r 
        ON dc.FUNTIONAL_LOC= r.FUNTIONAL_LOC 
         AND dc.dates = r.DATUM 
         AND dc.PRE_DATUM = r.PRE_DATUM 
         AND dc.PRE_CODE = r.PRE_CODE 
+0

Привет, индийский, спасибо: попробовал, но не успел. Ошибка: неправильный синтаксис рядом с ключевым словом «SELECT». SQLState: S1000 ErrorCode: 156 Не могли бы вы объяснить мне, как использовать таблицу календаря? Я обновил все подробные запросы по предложению Гордона. – SimonFreeman

+0

Я снова попытался, и у меня есть дубликаты (все записи FLOC x Day умножаются за все хиты во временном фрагменте) – SimonFreeman

0

мне удалось за счет создания LEFT JOIN (Календарь записей Результата записи): В этом случае я избегаю декартовы продукты, полученные перекрестное соединение и все дублируется. Для PRE-CODE Я думал использовать автообъединение на столе Результат:

WITH t as (
     SELECT ROW_NUMBER() OVER (ORDER BY Q2.FUNCTIONAL_LOCATION) AS Rowy, 
      Q1.FACT_MEASUREMENT_KEY, 
      CONVERT(VARCHAR(255), Q1.Doc_Time, 102) AS TIME 
     FROM dbo.DIM_PROJECT_TECH_OBJ Q2 INNER JOIN 
      dbo.FACT_MEASUREMENT Q1 
      ON Q1.PROJECT_TECH_OBJ_KEY = Q2.PROJECT_TECH_OBJ_KEY 
     WHERE Q1.Measurement_Position = 'XXX' 
    ) 
select t.*, tprev.time 
from t left join 
    t tprev 
    on tprev.rowy = t.rowy - 1;