Добавить объединение на основе оператора IF - PullRequest
0 голосов
/ 17 января 2011

Я хочу знать, могу ли я добавить объединение в оператор SQL на основе оператора IF. У меня есть запрос с тремя переменными, и я хочу включить соединение только в том случае, если третья переменная действительно заполнена. Это мой запрос:

-- Returns all new woksteps for a given time period
-- Includes the ability to narrow down to a specific arrangment

DECLARE @start_added_date DATETIME
DECLARE @end_added_date DATETIME
DECLARE @arrang_part_key INT

SET @start_added_date = '1/4/2011'
SET @end_added_date = '1/5/2011'
SET @arrang_part_key = '1230631'

-- Compensate for CST in the database
SET @end_added_date = DATEADD(DAY, 1, @end_added_date)

SELECT DISTINCT
  PWS.Part_Work_Step_Key,
  O.Operation_Code,
  WS.Work_Step,
  PWS.Sort_Order,
  U.User_ID,
  PWS.Added_Date,
  PWS.Cycle_Time,
  ET.ECR_Type,
  E.ECR_No,
  PWS.Effective_Date,
  P.Part_No,
  P.Revision,
  P.Name
FROM Part_V_Part_Work_Step PWS
JOIN Part_V_Work_Step WS
  ON WS.Work_Step_Key = PWS.Work_Step_Key
JOIN Part_V_Operation O
  ON O.Operation_Key = PWS.Operation_Key
JOIN User U
  ON U.User_No = PWS.Added_By
JOIN Part_V_ECR E
  ON E.ECR_Key = PWS.Effective_ECR_Key
JOIN Part_V_ECR_Type ET
  ON E.ECR_Type_Key = ET.ECR_Type_Key
JOIN Part_V_Part_Work_Step_BOM PWSB
  ON PWSB.Part_Work_Step_Key = PWS.Part_Work_Step_Key
JOIN Part_V_BOM B
  ON B.BOM_Key = PWSB.BOM_Key
JOIN Part_V_Part P
  ON P.Part_Key = B.Part_Key

IF @arrang_part_key IS NOT NULL
BEGIN
JOIN 
(
    SELECT
      AGP.Part_Key
    FROM Part_V_Flat_BOM FB
    JOIN Part_V_Part AGP
      ON AGP.Part_Key = FB.Component_Part_Key
    JOIN Part_V_Part_Group PG
      ON AGP.Part_Group_Key = PG.Part_Group_Key
     AND PG.Part_Group = 'Engineering Group'
    WHERE FB.Part_Key = @arrang_part_key
) AG
  ON AG.Part_Key = P.Part_Key
END

WHERE PWS.Part_Key IS NULL
  AND PWS.Added_Date BETWEEN @start_added_date AND @end_added_date
  AND PWS.Active = 1

ORDER BY
  O.Operation_Code,
  PWS.Sort_Order

Но когда я запускаю запрос, я получаю это как результат:

Error: Incorrect syntax near the keyword 'JOIN'
Error: Incorrect syntax near 'AG'

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

Ответы [ 3 ]

2 голосов
/ 17 января 2011

Это недопустимый синтаксис.

У вас есть два варианта:

  • Запись динамического SQL (вероятно, наихудшая практика)
  • Запись двух SELECT операторов.Один на каждую ветвь IF

IF @arrang_part_key IS NOT NULL
  BEGIN
    SELECT ...
      INNER JOIN ...
      ...
  END
ELSE
  BEGIN
    SELECT ...
      ...
  END
0 голосов
/ 17 января 2011

ОК, поэтому добавление объединения блоком IF просто не может работать. Но я нашел способ выполнить мой запрос, а также использовать столько кода для повторного использования, сколько мог придумать.

В запросе было два ключевых элемента:

  1. Постоянно запрашивать таблицу шагов работы
  2. Фильтровать по договоренности иногда

Для этого я использовал комбинацию и табличной переменной, и CTE (общего выражения таблицы), а затем поместил два запроса в мой блок if..else.

Новый запрос выглядит так:

-- Returns all new woksteps for a given time period
-- Includes the ability to narrow down to a specific arrangment

DECLARE @start_added_date DATETIME
DECLARE @end_added_date DATETIME
DECLARE @arrang_part_key INT

SET @start_added_date = '1/4/2011'
SET @end_added_date = '1/5/2011'
SET @arrang_part_key = '1230631'
--SET @arrang_part_key = NULL

-- Compensate for CST in the database
SET @end_added_date = DATEADD(DAY, 1, @end_added_date)

DECLARE @Work_Step_Table TABLE
(
  Customer_Number INT,
  Part_Work_Step_Key INT,
  Operation_Code VARCHAR(255),
  Work_Step VARCHAR(255),
  Sort_Order INT,
  User_Id VARCHAR(255),
  Added_Date DATETIME,
  Cycle_Time Float,
  ECR_Type VARCHAR(255),
  ECR_No INT,
  Effective_Date DATETIME,
  Part_Key INT,
  Part_No VARCHAR(255),
  Revision VARCHAR(255),
  Name VARCHAR(255)
)

INSERT INTO @Work_Step_Table
SELECT DISTINCT
  P.Customer_Number,
  PWS.Part_Work_Step_Key,
  O.Operation_Code,
  WS.Work_Step,
  PWS.Sort_Order,
  U.User_ID,
  PWS.Added_Date,
  PWS.Cycle_Time,
  ET.ECR_Type,
  E.ECR_No,
  PWS.Effective_Date,
  P.Part_Key,
  P.Part_No,
  P.Revision,
  P.Name
FROM Part_V_Part_Work_Step PWS
JOIN Part_V_Work_Step WS
  ON WS.Work_Step_Key = PWS.Work_Step_Key
JOIN Part_V_Operation O
  ON O.Operation_Key = PWS.Operation_Key
JOIN User U
  ON U.User_No = PWS.Added_By
JOIN Part_V_ECR E
  ON E.ECR_Key = PWS.Effective_ECR_Key
JOIN Part_V_ECR_Type ET
  ON E.ECR_Type_Key = ET.ECR_Type_Key
JOIN Part_V_Part_Work_Step_BOM PWSB
  ON PWSB.Part_Work_Step_Key = PWS.Part_Work_Step_Key
JOIN Part_V_BOM B
  ON B.BOM_Key = PWSB.BOM_Key
JOIN Part_V_Part P
  ON P.Part_Key = B.Part_Key

WHERE PWS.Part_Key IS NULL
  AND PWS.Added_Date BETWEEN @start_added_date AND @end_added_date
  AND PWS.Active = 1


IF (@arrang_part_key > 0)
BEGIN 
;WITH Arrangement_Groups (PCN, Arrangement_Part_Key, Component_Part_Key) AS
(
    SELECT
      AGP.Customer_Number,
      FB.Part_Key AS Arrangement_Part_Key,
      AGP.Part_Key AS Component_Part_Key      
    FROM Part_V_Flat_BOM FB
    JOIN Part_V_Part AGP
      ON AGP.Part_Key = FB.Component_Part_Key
    JOIN Part_V_Part_Group PG
      ON AGP.Part_Group_Key = PG.Part_Group_Key
     AND PG.Part_Group = 'Engineering Group'
    WHERE FB.Part_Key = @arrang_part_key
)
SELECT
  *
FROM @Work_Step_Table WST
JOIN Arrangement_Groups AG 
  ON AG.Component_Part_Key = WST.Part_Key  
ORDER BY
  WST.Operation_Code,
  WST.Sort_Order
END

ELSE
 BEGIN
  SELECT
    *
  FROM @Work_Step_Table WST
  ORDER BY
    WST.Operation_Code,
    WST.Sort_Order
 END

Переменная таблицы всегда будет создаваться и заполняться соответствующими записями для диапазона дат. Блок IF..Else проверит наличие дополнительного ключа аранжировки и при необходимости создаст дополнительный CTE и отфильтрует его.

0 голосов
/ 17 января 2011

Вы должны полностью запросить обе таблицы в обоих сценариях, а затем выполнить фильтрацию, поэтому попробуйте ...

-- Returns all new woksteps for a given time period
-- Includes the ability to narrow down to a specific arrangment

DECLARE @start_added_date DATETIME
DECLARE @end_added_date DATETIME
DECLARE @arrang_part_key INT

SET @start_added_date = '1/4/2011'
SET @end_added_date = '1/5/2011'
SET @arrang_part_key = '1230631'

-- Compensate for CST in the database
SET @end_added_date = DATEADD(DAY, 1, @end_added_date)

SELECT DISTINCT
  PWS.Part_Work_Step_Key,
  O.Operation_Code,
  WS.Work_Step,
  PWS.Sort_Order,
  U.User_ID,
  PWS.Added_Date,
  PWS.Cycle_Time,
  ET.ECR_Type,
  E.ECR_No,
  PWS.Effective_Date,
  P.Part_No,
  P.Revision,
  P.Name
FROM Part_V_Part_Work_Step PWS
JOIN Part_V_Work_Step WS
  ON WS.Work_Step_Key = PWS.Work_Step_Key
JOIN Part_V_Operation O
  ON O.Operation_Key = PWS.Operation_Key
JOIN User U
  ON U.User_No = PWS.Added_By
JOIN Part_V_ECR E
  ON E.ECR_Key = PWS.Effective_ECR_Key
JOIN Part_V_ECR_Type ET
  ON E.ECR_Type_Key = ET.ECR_Type_Key
JOIN Part_V_Part_Work_Step_BOM PWSB
  ON PWSB.Part_Work_Step_Key = PWS.Part_Work_Step_Key
JOIN Part_V_BOM B
  ON B.BOM_Key = PWSB.BOM_Key
JOIN Part_V_Part P
  ON P.Part_Key = B.Part_Key
JOIN 
(
    SELECT
      AGP.Part_Key
    FROM Part_V_Flat_BOM FB
    JOIN Part_V_Part AGP
      ON AGP.Part_Key = FB.Component_Part_Key
    JOIN Part_V_Part_Group PG
      ON AGP.Part_Group_Key = PG.Part_Group_Key
     AND PG.Part_Group = 'Engineering Group'
    WHERE FB.Part_Key = 
) AG
  ON AG.Part_Key = P.Part_Key and (@arrang_part_key = P.Part_Key And Not @arrang_part_key is Null )
END

WHERE PWS.Part_Key IS NULL
  AND PWS.Added_Date BETWEEN @start_added_date AND @end_added_date
  AND PWS.Active = 1

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