Присоединяйтесь, чтобы работать, только если запись присутствует в SQL - PullRequest
0 голосов
/ 27 апреля 2019

У меня есть 2 таблицы - table1 и table2.

В таблице 2 есть несколько критериев соответствия записей для таблицы1 на основе:

c_type, h_level, loop, e_id

Я хочу получить записи из ПРАВЫЙ таблицы ТОЛЬКО в случае совпадения ТОЧНО 1. Если нет, element_nm должен быть НЕДЕЙСТВИТЕЛЕН, поэтому у меня есть те же самые записи в выводе как левая таблица.

SELECT   a.*,
         b.element_nm
FROM     table1 a
   LEFT JOIN table2 b ON
         a.c_type = b.c_type
   AND   a.h_level = b.h_level
   AND   a.loop = b.loop
   AND   a.e_id = b.e_id
ORDER BY a.file_name,
         a.line_num asc;

Ответы [ 3 ]

2 голосов
/ 27 апреля 2019

Поскольку это только одно значение, вы можете использовать подзапрос в предложении select. В противном случае вы бы использовали подзапрос в LEFT OUTER JOIN или OUTER APPLY.

SELECT 
  t1.*,
  (
    SELECT MIN(t2.element_nm)
    FROM table2 t2
    WHERE t2.c_type = t1.c_type
      AND t2.h_level = t1.h_level
      AND t2.loop = t1.loop
      AND t2.e_id = t1.e_id
    HAVING COUNT(*) = 1
  ) AS element_nm
FROM table1 t1
ORDER BY t1.file_name, t1.line_num;
2 голосов
/ 27 апреля 2019

Ответ Торстена работает, когда вам нужен только один столбец из второй таблицы. Но если вам нужно несколько столбцов, это немного громоздко.

В качестве альтернативы:

SELECT a.*, b.*
FROM table1 a LEFT JOIN
     (SELECT b.*,
             COUNT(*) OVER (PARTITION BY b.c_type, b.h_level, b.loop, b.e_id) as cnt
      FROM b
     ) b
     ON a.c_type = b.c_type AND
        a.h_level = b.h_level AND
        a.loop = b.loop AND
        a.e_id = b.e_id AND
        b.cnt = 1
ORDER BY a.file_name, a.line_num asc;
0 голосов
/ 27 апреля 2019

вы должны использовать Row_Number, например:

WITH cte AS (
SELECT ROW_NUMBER() OVER(PARTITION BY a.c_type ,a.h_level,a.loop  ,a.e_id   ) rnum
 ,a.c_type ,a.h_level,a.loop  ,a.e_id FROM     table1 a
   LEFT JOIN table2 b ON  a.c_type = b.c_type  AND  a.h_level = b.h_level  AND a.loop = b.loop AND a.e_id = b.e_id
) 
,cte2 AS (SELECT * FROM cte WHERE rnum = 2)
         SELECT   a.*,
  CASE WHEN cte2.element_nm IS NULL then       b.element_nm ELSE NULL END element_nm
FROM     table1 a
   LEFT JOIN table2 b ON  a.c_type = b.c_type  AND  a.h_level = b.h_level  AND a.loop = b.loop AND a.e_id = b.e_id
   LEFT JOIN cte2 ON    a.c_type = cte2.c_type AND  a.h_level = cte2.h_level AND a.loop = cte2.loop AND a.e_id = cte2.e_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...