SQL "IN" 절에서 튜플 사용
group_id 및 group_type 필드가 포함된 테이블이 있는데, 이 테이블에서 튜플 목록에서 튜플(그룹 ID, 그룹 유형)이 있는 모든 레코드를 쿼리하려고 합니다.예를 들어 다음과 같은 작업을 수행할 수 있습니다.
SELECT *
FROM mytable
WHERE (group_id, group_type) IN (("1234-567", 2), ("4321-765", 3), ("1111-222", 5))
sql in 절에서 튜플을 사용하는 것과 매우 유사한 질문이 이미 에 있지만, 제안된 솔루션은 튜플 목록을 다른 테이블에서 가져올 것으로 가정합니다.이 경우 튜플 값이 하드 코딩되어 있기 때문에 작동하지 않습니다.
한 가지 해결책은 문자열 연결을 사용하는 것입니다.
SELECT *
FROM mytable
WHERE group_id + STR(group_type, 1) IN ("1234-5672", "4321-7653", "1111-2225")
그러나 문제는 테이블이 상당히 크고 각 레코드에 대해 문자열 연결 및 변환을 수행하는 데 비용이 매우 많이 든다는 것입니다.
제안할 것이 있습니까?
매우 작은 수정이 주어지면 (큰따옴표를 단일 따옴표로 바꾸고 다음을 추가합니다.VALUES
키워드), 제안한 구문이 유효한 표준 SQL-92 구문입니다.
SELECT *
FROM mytable
WHERE (group_id, group_type) IN (
VALUES ('1234-567', 2),
('4321-765', 3),
('1111-222', 5)
);
안타깝게도 MSFT는 이 기능을 SQL Server에 추가하지 않았으며 '계획되지 않은' 기능으로 간주하고 있습니다.
FWIW PostgreSQL 및 SQLite는 이 구문을 지원하는 SQL 제품의 예입니다.
SQL Server 2008에서는 다음과 같은 작업을 수행할 수 있습니다.
select *
from mytable as T
where exists (select *
from (values ('1234-567', 2),
('4321-765', 3),
('1111-222', 5)) as V(group_id, group_type)
where T.group_id = V.group_id and
T.group_type = V.group_type
)
편집: 이 답변은 날짜가 지정된 답변입니다. 2011년에 승인된 답변이지만, 더 많은 표를 가진 다른 답변은 더 최근의 접근 방식을 반영합니다.
OR 문을 구성하는 것이 어떻습니까?
SELECT *
FROM mytable
WHERE (group_id = '1234-567' and group_type = 2)
OR (group_id = '4321-765' and group_type = 3)
OR (group_id = '1111-222' and group_type = 5)
물론, 당신의 컨셉 예처럼 멋지고 깔끔해 보이지는 않지만, 그것은 그 일을 할 것입니다(그리고 만약 당신이IN
튜플이 존재했다면, 커버 아래에서 정확히 같은 방식으로 구현했을 것입니다.
공통 테이블 식을 사용하여 다음 튜플이 다른 테이블에 있는 것처럼 가장할 수 있습니다.
;WITH Tuples as (
select '1234-567' as group_id, 2 as group_type union all
select '4321-765', 3 union all
select '1111-222', 5
)
SELECT * /* TODO - Pick appropriate columns */
from mytable m where exists (
select * from Tuples t
where m.group_id = t.group_id and m.group_type = t.group_type)
이 솔루션을 사용하면 다음과 같은 이점이 있습니다.
SELECT *
FROM mytable m
WHERE EXISTS (
SELECT * FROM (
SELECT "1234-567" group_id, 2 group_type UNION ALL
SELECT "4321-765", 3 UNION ALL
SELECT "1111-222", 5) [t]
WHERE m.group_id = t.group_id AND m.group_type = t.group_type)
참고로, CTE를 사용하여 내부 테이블을 만들어야 합니다.
아직 본 적은 없지만, 이런 것이 효과가 있을 겁니다.
SELECT * FROM AgeGroup ag JOIN
(VALUES
('18-24', 18, 24),
('25-34 ', 25, 39),
('35-44 ', 35, 49),
('45-54 ', 45, 59),
('55-64 ', 55, 69),
('65+ ', 65, 299)
) AS x (agegroup, minage, maxage)
ON ag.age_group = x.agegroup
AND ag.min_age=x.minage
AND ag.max_age=x.maxage
조인을 사용하는 다른 튜플 솔루션은 다음과 같습니다.
SELECT
*
FROM mytable m
JOIN
(
SELECT "1234-567" group_id, 2 group_type
UNION ALL SELECT "4321-765", 3
UNION ALL SELECT "1111-222", 5
) [t]
ON m.group_id = t.group_id
AND m.group_type = t.group_type
비슷한 문제가 있었지만 튜플 수집이 동적이었습니다. 쿼리 매개 변수를 통해 SQL Server로 전송되었습니다.저는 다음과 같은 해결책을 생각해냈습니다.
XML로 튜플 전달:
DECLARE @tuplesXml xml = '<tuples><tuple group-id="1234-567" group-type="2"/><tuple group-id="4321-765" group-type="3"/></tuples>';
XML 노드로 필터링할 테이블에 내부 조인:
SELECT t.* FROM mytable t INNER JOIN @tuplesXml.nodes('/tuples/tuple') AS tuple(col) ON tuple.col.value('./@group-id', 'varchar(255)') = t.group_id AND tuple.col.value('./@group-type', 'integer') = t.group_type
질문에 설명된 것보다 조금 더 복잡한 제 상황에서는 잘 작동하는 것 같습니다.
사용할 필요가 있음을 명심하십시오.t.*
에 *
그리고 테이블이 돌아왔습니다.nodes
tuple(col)
이 경우).
select * from table_name where 1=1 and (column_a, column_b) in ((28,1),(25,1))
언급URL : https://stackoverflow.com/questions/8006901/using-tuples-in-sql-in-clause
'itsource' 카테고리의 다른 글
FastAPI + SQLAlchemy - datetime 필드가 있는 테이블에 항목을 게시할 때 잘못된 RequestError가 발생함 (0) | 2023.06.26 |
---|---|
리포지토리 패턴을 올바르게 사용하는 방법 (0) | 2023.06.26 |
LEA EAX, [EAX]의 의미는 무엇입니까? (0) | 2023.06.21 |
SELECT max(x)가 null을 반환합니다. 0을 반환하려면 어떻게 해야 합니까? (0) | 2023.06.21 |
Android - Firebase - TaskSnapshot - Method는 개인 범위 내에서만 액세스해야 합니까? (0) | 2023.06.21 |