Невозможно передать запрос из Oracle SQL в MS SQL, который имеет несколько объединений - PullRequest
2 голосов
/ 27 февраля 2020

У меня есть SQL запрос в Oracle, который выполняется и дает мне правильный результат. Однако мне нужен аналогичный результат в MS SQL, где у меня возникают проблемы с объединениями таблиц.

Ниже мой Oracle SQL:

SELECT
    number_of_inspection.line,
    number_of_inspection.week,
    number_of_inspection.total_records,
    ( visual_fails.fails + qc_fails.fails ) total_fails,
    nvl(round((100 / number_of_inspection.total_records) *(visual_fails.fails + qc_fails.fails), 2), 0) percentage_fails
FROM
    (
        SELECT
            COUNT(*) total_records,
            line,
            to_char(inspection_date, 'IW') week
        FROM
            master_table
        WHERE
            to_char(inspection_date, 'YYYY') = to_char(sysdate, 'YYYY')
            AND inspection_date >= add_months(sysdate, - 3)
        GROUP BY
            line,
            to_char(inspection_date, 'IW')
    ) number_of_inspection,
    (
        SELECT
            line,
            to_char(inspection_date, 'IW') week,
            COUNT(*) fails
        FROM
            master_table
        WHERE
            to_char(inspection_date, 'YYYY') = to_char(sysdate, 'YYYY')
            AND visual_inspection = 'FAIL'
        GROUP BY
            line,
            to_char(inspection_date, 'IW')
    ) visual_fails,
    (
        SELECT
            line,
            to_char(inspection_date, 'IW') week,
            COUNT(*) fails
        FROM
            master_table
        WHERE
            to_char(inspection_date, 'YYYY') = to_char(sysdate, 'YYYY')
            AND visual_inspection != 'FAIL'
            AND nvl(qc_inspection, 'FAIL') = 'FAIL'
        GROUP BY
            line,
            to_char(inspection_date, 'IW')
    ) qc_fails
WHERE
    number_of_inspection.line = visual_fails.line (+)
    AND number_of_inspection.week = visual_fails.week (+)
    AND number_of_inspection.line = qc_fails.line (+)
    AND number_of_inspection.week = qc_fails.week (+)

Правильный результат, который я получаю Oracle:

+--------+------+---------------+------------+-----------------+
| LINE   | WEEK | TOTAL_RECORDS |TOTAL_FAILS | PERCENTAGE_FAILS|
+--------+------+---------------+------------+-----------------+
| Line 1 |  08  |   845         |    6       |   0.71          |
| Line 2 |  08  |   1790        |    11      |   0.61          |
| Line 1 |  09  |   350         |    9       |   2.57          |
| Line 2 |  09  |   1125        |    20      |   1.77          |
+--------+------+---------------+------------+-----------------+

Ниже мой MS SQL запрос:

SELECT number_of_inspection.line, 
       number_of_inspection.week_no, 
       number_of_inspection.total_records, 
       ( visual_fails.fails + qc_fails.fails ) total_fails, 
       Isnull(Round(( 100 / number_of_inspection.total_records ) * ( 
                           visual_fails.fails + qc_fails.fails ), 2), 0) 
                                               percentage_fails 
FROM   (SELECT Count(*)                        total_records, 
               line, 
               Datepart(ww, [inspection date]) Week_No 
        FROM   master_table 
        WHERE  Year([inspection date]) = Year(Getdate()) 
               AND [inspection date] >= Dateadd(month, -1, Getdate()) 
        GROUP  BY line, 
                  Datepart(ww, [inspection date])) number_of_inspection, 
       (SELECT line, 
               Datepart(ww, [inspection date]) AS Week_No, 
               Count(*)                        AS fails 
        FROM   master_table 
        WHERE  Year([inspection date]) = Year(Getdate()) 
               AND [visual inspection] = 'FAIL' 
        GROUP  BY line, 
                  Datepart(ww, [inspection date])) visual_fails, 
       (SELECT line, 
               Datepart(ww, [inspection date]) AS Week_No, 
               Count(*)                        AS fails 
        FROM   master_table 
        WHERE  Year([inspection date]) = Year(Getdate()) 
               AND [visual inspection] != 'FAIL' 
               AND Isnull([qc inspection], 'FAIL') = 'FAIL' 
        GROUP  BY line, 
                  Datepart(ww, [inspection date])) qc_fails, 
       where number_of_inspection 
       LEFT OUTER JOIN visual_fails 
                    ON number_of_inspection.line = visual_fails.line 
                       -- join issue 
                       AND number_of_inspection 
       LEFT OUTER JOIN visual_fails 
                    ON number_of_inspection.week_no = visual_fails.week_no 
                       -- join issue 
                       AND number_of_inspection 
       LEFT OUTER JOIN qc_fails 
                    ON number_of_inspection.line = qc_fails.line -- join issue 
                       AND number_of_inspection 
       LEFT OUTER JOIN qc_fails 
                    ON number_of_inspection.week_no = qc_fails.week_no -- join issue 

I известно, что мы присоединяемся к таблицам в предложении FROM в MS SQL, в отличие от Oracle, где мы также можем присоединиться к предложению WHERE .

Когда я пытаюсь выполнить запрос MS SQL, я получаю следующую ошибку:

Incorrect syntax near the keyword 'WHERE'.

Примечание: Я использую SQL Server 2014 , поэтому я не могу изменить базу данных для изменения Compatibility Level.

Не могли бы вы помочь мне с тем, что я делаю неправильно в моем запросе MS SQL?

Ответы [ 2 ]

5 голосов
/ 27 февраля 2020

Я бы использовал условное агрегирование в любой базе данных. Вот идея на SQL сервере:

select line, datepart(week, [Inspection Date]), 
       count(*) total_records,
       sum(case when visual_inspection = 'FAIL' then 1 else 0 end) as num_visual_fails,
       sum(case when [QC Inspection] = 'FAIL' or [QC Inspection] is null then 1 else 0 end) as num_qc_fails,
       avg(case when visual_inspection = 'FAIL' or
                     [QC Inspection] = 'FAIL' or
                     [QC Inspection] is null
                then 1.0 else 0
            end) as fail_ratio
       . . . 
from master_table
where year(inspection_date) = year(getdate()) and
      inspection_date >= dateadd(month, -3, getdate())
group by line, datepart(week, [Inspection Date]);

Это не совсем ваш запрос. Но это должно дать вам правильное представление о том, как подойти к проблеме.

2 голосов
/ 27 февраля 2020

Я рекомендую ответ Гордона для улучшения вашего кода, но я также хочу, чтобы вы могли понять, как преобразовать старый стиль соединения Oracle в современный стандартный синтаксис объединения (который также работает в Oracle).

Для удобства чтения я отредактировал содержимое ваших подзапросов встроенного представления, но я думаю, что эта идея понятна.

SELECT
    number_of_inspection.line,
    number_of_inspection.Week_No,
    number_of_inspection.total_records,
    (visual_fails.fails + qc_fails.fails) total_fails,
    ISNULL(ROUND((100/number_of_inspection.total_records)*(visual_fails.fails + qc_fails.fails),2),0) percentage_fails
FROM
    (...) number_of_inspection
LEFT OUTER JOIN 
    (...) visual_fails
    ON number_of_inspection.line = visual_fails.line
    AND number_of_inspection.Week_No = visual_fails.Week_No
LEFT OUTER JOIN
    (...) qc_fails
    ON number_of_inspection.line = qc_fails.line
    AND number_of_inspection.Week_No = qc_fails.Week_No
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...