[sql] JOIN 조건에서 CASE 문을 사용할 수 있습니까?

다음 이미지는 Microsoft SQL Server 2008 R2 시스템 뷰의 일부입니다. 이미지에서 sys.partitions와 의 관계는 sys.allocation_units의 값에 따라 달라집니다 sys.allocation_units.type. 그래서 그것들을 합치려면 다음과 비슷한 것을 쓰십시오.

SELECT  *
FROM    sys.indexes i
        JOIN sys.partitions p
            ON i.index_id = p.index_id 
        JOIN sys.allocation_units a
            ON CASE
               WHEN a.type IN (1, 3)
                   THEN a.container_id = p.hobt_id 
               WHEN a.type IN (2)
                   THEN a.container_id = p.partition_id
               END 

그러나 위 코드는 구문 오류를 발생시킵니다. 나는 그것이 CASE성명서 때문이라고 생각합니다 . 누구든지 조금 설명하는 데 도움이 될 수 있습니까?


오류 메시지 추가 :

메시지 102, 수준 15, 상태 1, 줄 6 ‘=’근처의 구문이 잘못되었습니다.

이것은 이미지입니다



답변

CASE표현식의 값 리턴 THEN절의 부. 따라서 다음과 같이 사용할 수 있습니다.

SELECT  * 
FROM    sys.indexes i 
    JOIN sys.partitions p 
        ON i.index_id = p.index_id  
    JOIN sys.allocation_units a 
        ON CASE 
           WHEN a.type IN (1, 3) AND a.container_id = p.hobt_id THEN 1
           WHEN a.type IN (2) AND a.container_id = p.partition_id THEN 1
           ELSE 0
           END = 1

리턴 값으로 무언가를 수행해야합니다 (예 : 1과 비교). 명령문이 지정 값을 리턴하거나 동등성에 대해 테스트하려고했으나 CASE/ THEN절의 컨텍스트에서 의미가 없습니다 . ( BOOLEAN데이터 유형 인 경우 동등성 테스트가 적합합니다.)


답변

대신 두 테이블 모두에 조인하고 SELECT 절에서 다음과 일치하는 데이터를 반환합니다.

이 링크 를 SQL Server의 조건부 조인JOIN ON 절의 T-SQL 사례 설명 링크로 이동하는 것이 좋습니다.

예 :

    SELECT  *
FROM    sys.indexes i
        JOIN sys.partitions p
            ON i.index_id = p.index_id
        JOIN sys.allocation_units a
            ON a.container_id =
            CASE
               WHEN a.type IN (1, 3)
                   THEN  p.hobt_id
               WHEN a.type IN (2)
                   THEN p.partition_id
               END 

편집 : 의견에 따라.

수행중인 조인 조건을 지정할 수 없습니다. 오류가없는 위의 쿼리를 확인하십시오. 공통 열을 꺼내고 오른쪽 열 값이 조건에 따라 평가됩니다.


답변

이 시도:

...JOIN sys.allocation_units a ON
  (a.type=2 AND a.container_id = p.partition_id)
  OR (a.type IN (1, 3) AND a.container_id = p.hobt_id)


답변

두 가지 사례 진술이 필요하다고 생각합니다.

SELECT  *
FROM    sys.indexes i
    JOIN sys.partitions p
        ON i.index_id = p.index_id
    JOIN sys.allocation_units a
        ON
        -- left side of join on statement
            CASE
               WHEN a.type IN (1, 3)
                   THEN a.container_id
               WHEN a.type IN (2)
                   THEN a.container_id
            END
        =
        -- right side of join on statement
            CASE
               WHEN a.type IN (1, 3)
                   THEN p.hobt_id
               WHEN a.type IN (2)
                   THEN p.partition_id
            END             

이 때문입니다:

  • CASE 문은 END에서 단일 값을 리턴합니다.
  • ON 문은 두 값을 비교합니다
  • CASE 문이 CASE 문 내부 에서 비교를 수행했습니다 . CASE 문을 SELECT에 넣으면 CASE 문이 True 또는 False로 평가되는지 여부를 나타내는 부울 ‘1’또는 ‘0’이 나타납니다.

답변

나는 당신의 예를 들어서 편집했습니다.

SELECT  *
FROM    sys.indexes i
    JOIN sys.partitions p
        ON i.index_id = p.index_id
    JOIN sys.allocation_units a
        ON a.container_id = (CASE
           WHEN a.type IN (1, 3)
               THEN p.hobt_id
           WHEN a.type IN (2)
               THEN p.partition_id
           ELSE NULL
           END)


답변

이거 좋아 보인다

https://bytes.com/topic/sql-server/answers/881862-joining-different-tables-based-condition

FROM YourMainTable
LEFT JOIN AirportCity DepCity ON @TravelType = 'A' and DepFrom =  DepCity.Code
LEFT JOIN AirportCity DepCity ON @TravelType = 'B' and SomeOtherColumn = SomeOtherColumnFromSomeOtherTable


답변

그래 넌 할수있어. 다음은 예입니다.

SELECT a.*
FROM TableA a
LEFT OUTER JOIN TableB j1 ON  (CASE WHEN LEN(COALESCE(a.NoBatiment, '')) = 3
                                THEN RTRIM(a.NoBatiment) + '0'
                                ELSE a.NoBatiment END ) = j1.ColumnName