Как преобразовать SQL-запрос с IN, NOT IN, UNION, используя соединения - PullRequest
1 голос
/ 14 марта 2019

Можно ли преобразовать подзапрос с операторами NOT IN, IN и UNION для объединения? Мне нужен этот запрос, используя соединения без подзапросов, поэтому Spring jpa может понять, что

 SELECT * 
  FROM CONTACT 
  WHERE partner_idpartner = (
     SELECT partner_idpartner 
     FROM BUSINESSCHANNEL WHERE idBusinessChannel in (
       select idbusinessFrom from business WHERE idbusiness = 5943
     )
   )  
   and idcontact not in (
     SELECT CONTACT_IDCONTACT FROM businesscontact 
     WHERE BUSINESS_IDBUSINESS=5943
   )   
  UNION
  SELECT *  
  FROM CONTACT 
  WHERE partner_idpartner = (
    SELECT partner_idpartner 
    FROM BUSINESSCHANNEL WHERE idBusinessChannel in (
      select idbusinessTo FROM business WHERE idbusiness = 5943
    )
  )  
   and idcontact not in (
    SELECT CONTACT_IDCONTACT FROM businesscontact 
    WHERE BUSINESS_IDBUSINESS=5943
  ) 

Ответы [ 4 ]

2 голосов
/ 14 марта 2019

Попробуйте это:

SELECT    DISTINCT CONTACT.*
FROM      CONTACT
JOIN      BUSINESSCHANNEL
ON        CONTACT.partner_idpartner = BUSINESSCHANNEL.partner_idpartner
JOIN      business
ON        (BUSINESSCHANNEL.idBusinessChannel = business.idbusinessFrom
AND       business.idbusiness = 5943)
OR        (BUSINESSCHANNEL.idBusinessChannel = business.idbusinessTo)
AND       business.idbusinessroute = 5943)
LEFT JOIN businesscontact
ON        CONTACT.idcontact = businesscontact.CONTACT_IDCONTACT 
AND       BUSINESS_IDBUSINESS = 5943
WHERE     businesscontact.CONTACT_IDCONTACT IS NULL
2 голосов
/ 14 марта 2019

Вы можете преобразовать все эти подзапросы в объединения.Недостатком является то, что вы теряете удобочитаемость и можете получить огромный промежуточный результат, от которого вы должны избавиться с помощью DISTINCT.Это может быть довольно дорого.NOT IN можно преобразовать в анти-объединение (внешнее объединение и затем выбор несогласованных строк), что является еще одним шаблоном, который может привести к нежелательно большому промежуточному результату.

SELECT DISTINCT c.*  
FROM contact c
JOIN businesschannel bc ON bc.partner_idpartner = c.partner_idpartner
JOIN business b ON bc.idbusinesschannel IN (b.idbusinessfrom, b.idbusinessto)
                AND b.idbusiness = 5943 
LEFT JOIN businesscontact bco ON bco.contact_idcontact = c.idcontact
                              AND bco.business_idbusiness = 5943
WHERE bco.contact_idcontact IS NULL;
0 голосов
/ 14 марта 2019

Здесь вы идете

  1. , чтобы заменить где в: используйте внутреннее объединение
  2. , чтобы заменить, где не в: используйте левое внешнее объединение tab2, где tab2.col равен нулю
  3. чтобы заменить объединение, я создаю временную таблицу #mycontact с такой же структурой, что и CONTACT

    выберите * в mycontact из контакта, где 1 = 0

    вставьте в #mycontact SELECT* ОТ КОНТАКТА TA

    внутреннее объединение (ВЫБЕРИТЕ partner_idpartner ОТ БИЗНЕС-КАНАЛА T0 внутреннее объединение (выберите idbusinessFrom из бизнеса WHERE idbusiness = 5943) T1 в T0.idBusinessChannel = T1.idbusinessFrom) оставило внешнее объединение (ВЫБЕРИТЕ CONTACT_IDCONTACT ОТ businesscontact WHERE WHITE= 5943) T2 для T0.idcontact = T2.CONTACT_IDCONTACT, где T2.CONTACT_IDCONTACT равен нулю) TB для TA.partner_idpartner = TB.partner_idpartner

    вставить в # mycontact

    SELECT *
    FROMВнутреннее соединение CONTACT TC (

    (SELECT partner_idpartner FROM BUSINESSCHANNEL  T0
    INNER JOIN (  select idbusinessTo FROM business     WHERE idbusinessroute=5943) T1 on T0.idBusinessChannel=T1.idbusinessFrom)  
    
    left outer join ( SELECT CONTACT_IDCONTACT FROM businesscontact WHERE BUSINESS_IDBUSINESS=5943)  T2
    on T0.idcontact=T2.CONTACT_IDCONTACT
    

    , где T2.CONTACT_IDCONTACT равно нулю)

    TD on TC.partner_idpartner=TD.partner_idpartner
    

    выберите * из # mycontact

0 голосов
/ 14 марта 2019

Попробуйте этот запрос: я не тестировал

DECLARE @tblNotInIUdContact TABLE (  CONTACT_IDCONTACT INT)
DECLARE @tblIdBusinessFrom TABLE (   IdBusiness INT)
DECLARE @tblIdBusinessTo TABLE (     IdBusiness INT)
DECLARE @tblIdPartner TABLE (    partner_idpartner INT)

INSERT INTO @tblNotInIUdContact(CONTACT_IDCONTACT)
SELECT CONTACT_IDCONTACT FROM businesscontact WHERE BUSINESS_IDBUSINESS=5943

INSERT INTO @tblIdBusinessFrom(IdBusiness)
select idbusinessFrom from business  WHERE idbusiness=5943

INSERT INTO @tblIdBusinessTo(IdBusiness)
select idbusinessTo FROM business    WHERE idbusinessroute=5943

INSERT INTO @tblIdPartner(partner_idpartner)
SELECT partner_idpartner FROM BUSINESSCHANNEL bc
INNER JOIN @tblIdBusinessFrom bf ON bc.partner_idpartner = bf.IdBusiness

INSERT INTO @tblIdPartner(partner_idpartner)
SELECT partner_idpartner FROM BUSINESSCHANNEL bc
INNER JOIN @tblIdBusinessTo bf ON bc.partner_idpartner = bf.IdBusiness



SELECT * FROM CONTACT c
    INNER JOIN @tblIdPartner p ON c.partner_idpartner = p.partner_idpartner  
EXCEPT
SELECT * FROM CONTACT c
    INNER JOIN @tblNotInIUdContact ic ON c.idcontact = ic.CONTACT_IDCONTACT
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...