문제

나는 많은 SQL을하지 않으며 대부분의 경우 CRUD 작업을하고 있습니다. 때때로 나는 좀 더 복잡한 것을 얻을 것이다. 따라서이 질문은 초보자 질문 일지 모르지만 준비가되었습니다. 나는 방금 몇 시간 동안 이것을 알아 내려고 노력했지만 아무 소용이 없었습니다.

따라서 다음 테이블 구조를 상상해보십시오.

> | ID | Col1 | Col2 | Col3 | .. | Col8 |

ID와 계산 된 열을 선택하고 싶습니다. 계산 된 열에는 0-8 범위가 있으며 쿼리와의 일치 수가 포함되어 있습니다. 또한 특정 수의 일치가있는 행만 포함하도록 결과 세트를 제한하고 싶습니다.

따라서이 샘플 데이터에서 :

> | 1 | 'a' | 'b' | 1 | 2 |  
> | 2 | 'b' | 'c' | 1 | 2 |  
> | 3 | 'b' | 'c' | 4 | 5 |  
> | 4 | 'x' | 'x' | 9 | 9 |  

col1 = 'a'또는 col2 = 'c'또는 col3 = 1 또는 col4 = 5에서 계산 된 결과> 1에서 쿼리하고 싶습니다. 결과 세트가 다음과 같습니다.

> | ID | Cal |
> | 1  |  2  |
> | 2  |  2  |
> | 3  |  2  |

중요한 경우 T-SQL 및 SQL Server 2005를 사용하고 있으며 DB 스키마를 변경할 수 없습니다.

또한 하나의 독립적 인 쿼리로 유지하고 저장된 절차 또는 임시 테이블을 만들 필요가 없습니다.

도움이 되었습니까?

해결책

이 답변은 CTE를 사용하여 파생 된 테이블을 약간 정리하여 SQL 2005와 함께 작동합니다.

WITH Matches AS
(
    SELECT ID, CASE WHEN Col1 = 'a' THEN 1 ELSE 0 END + 
                CASE WHEN Col2 = 'c' THEN 1 ELSE 0 END +
                CASE WHEN Col3 = 1  THEN 1 ELSE 0 END +
                CASE WHEN Col4 = 5  THEN 1 ELSE 0 END AS Result
    FROM Table1
    WHERE Col1 = 'a' OR Col2 = 'c' OR Col3 = 1 OR Col4 = 5 
)
SELECT ID, Result
FROM Matches
WHERE Result > 1 

다른 팁

다음은 부울 비교가 정수 1 또는 0을 반환한다는 사실을 활용하는 솔루션입니다.

SELECT * FROM (
  SELECT ID, (Col1='a') + (Col2='c') + (Col3=1) + (Col4=5) AS calculated
  FROM MyTable
) q
WHERE calculated > 1; 

부울 비교를 괄호로 묶어야합니다. + 보다 우선 순위가 높습니다 =. 또한 일반적으로 열 별칭을 WHERE 동일한 쿼리 조항.

a를 사용해야하는 것처럼 보일 수 있습니다 WHERE 하위 쿼리의 조항은 행을 제한하지만, 어쨌든 전체 테이블 스캔으로 끝날 것이므로 아마도 큰 승리가 아닙니다. 반면에, 그러한 제한이 매우 하위 쿼리 결과의 행 수를 줄이면 가치가 있습니다.


Quassnoi의 의견, 부울 표현을 정수 값으로 취급 할 수 없다면 부울 조건을 약간 장황하더라도 부울 조건을 정수에 매핑하는 방법이 있어야합니다. 예를 들어:

SELECT * FROM (
  SELECT ID, 
      CASE WHEN Col1='a' THEN 1 ELSE 0 END
    + CASE WHEN Col2='c' THEN 1 ELSE 0 END 
    + CASE WHEN Col3=1   THEN 1 ELSE 0 END
    + CASE WHEN Col4=5   THEN 1 ELSE 0 END AS calculated
  FROM MyTable
) q
WHERE calculated > 1;

이 쿼리는 인덱스 친화적입니다.

SELECT  id, SUM(match)
FROM    (
        SELECT  id, 1 AS match
        FROM    mytable
        WHERE   col1 = 'a'
        UNION ALL
        SELECT  id, 1 AS match
        FROM    mytable
        WHERE   col2 = 'c'
        UNION ALL
        SELECT  id, 1 AS match
        FROM    mytable
        WHERE   col3 = 1
        UNION ALL
        SELECT  id, 1 AS match
        FROM    mytable
        WHERE   col4 = 5
        ) q
GROUP BY
        id
HAVING  SUM(match) > 1

이것은 단지 효율적입니다 모두 당신이 검색하는 열은 먼저 색인화되었으며, 둘째는 높은 카디널리티 (많은 뚜렷한 값)를 가지고 있습니다.

성능 세부 정보는 내 블로그 에서이 기사를 참조하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top