2013-01-17 3 views
1

하나의 테이블과 두 개의 열을 포함하는 검색 쿼리가 있습니다.SQL 쿼리 여러 열을 편집해야합니다.

Select * 
from Gecoserv _a 
where _a.typeOfEcosystem IN (:typeNameList) 
    AND _a.service IN (:serviceNameList) 

그것은 작동하지만

이의 말을하자 내가

를 원하는 결과를 포기하지 않을 것 :

typeNameList = { Freshwater, Saltwater, Dunes } 
serviceNameList = {Habitat, Food, Recreation } 

나는 단지 하나의 조합 (민물-서식지, 해양 - 식품 표시하도록 그리드를 원하는 모래 언덕 - 레크리에이션 등)하지만 다른 조합 (예 : 민물 - 휴양)도 보여줍니다. 즉

는 : 쿼리 결과는

[0,0],[0,1],[0,2], 
[1,0],[1,1],[1,2], 
[2,0],[2,1],[2,2]. 

을 보여하지만 만보고 싶어 : [0,0],[1,1],[2,2].

나는 쿼리의 끝 부분에 뭔가를 추가해야한다는 것을 알고있다. 나는 많은 것을 시도했지만 완벽한 해결책을 찾지 못했습니다.

저를 도와 줄 수있는 사람이 있습니까?

감사합니다,

Melih

+0

이 테이블이 고유 키 (또는 다른 식별 열)이 있습니까 : 또한 기술 (그냥 평범한 오래된 신 읽기)에서 찾을 수 있습니까? – wildplasser

답변

0

나는 이것이 당신이 가지고있는 유일한 정보 인 경우이, 할 수 없다고 생각한다. 매개 변수 값 사이의 관계는 목록에서의 위치입니다. SQL에서 이러한 위치를 연관 시키거나 보존하는 옵션은 없습니다.

SQL 문을 만들 때 어떤 영향이 있습니까? 이 매개 변수화하는 방법의 예를 들어

SELECT * FROM Gecoserv 
    WHERE typeOfEcosystem = 'Freshwater' AND service = 'Habitat' 
UNION 
SELECT * FROM Gecoserv 
    WHERE typeOfEcosystem = 'Freshwater' AND service = 'Food' 
UNION 
... 

this answer를 보라 : 당신은 코드의 목록을 반복하고 동적 SQL을 만들 수 있다면

,이 같은 솔루션에 올 수 있습니다.

대안 : 분할 문자열

당신의 가장 큰 문제는 자신의 목록에있는 매개 변수의 "계급"/ "위치"를 유지하는 것입니다. 목록을 문자열로 바꾸고 나누면됩니다.

나는 example of a splitting a string in sql을 사용했습니다.

DECLARE 
    @ecoSystems varchar(100) = 'Freshwater,Saltwater,Dunes', 
    @services varchar(100) = 'Habitat,Food,Recreation', 
    @separator char(1) = ',' 

SELECT 
    [g].[id], 
    [g].[typeOfEcoSystem], 
    [g].[service] 
FROM [dbo].[Split](@separator, @ecoSystems) [e] 
INNER JOIN [dbo].[Split](@separator, @services) [s] 
    ON [e].[position] = [s].[position] 
INNER JOIN [Gecoserv] [g] 
    ON [e].[part] = [g].[typeOfEcoSystem] 
    AND [s].[part] = [g].[service] 
ORDER BY [id] ASC 

윌 시나리오에 대해이 작업 : (this Fiddle로 만든)

결과 쿼리는 다음과 같습니다?은 (답 : 예, 거의 ...)

그리고 마지막으로 모든 백업 스키마 또는 데이터베이스 제조업체없이 함수

DECLARE 
    @ecoSystems varchar(100) = 'Freshwater,Saltwater,Dunes', 
    @services varchar(100) = 'Habitat,Food,Recreation', 
    @separator char(1) = ','; 

WITH [EcoSystemsAndServices]([posE], [startE], [endE], [posS], [startS], [endS]) 
AS 
(
    SELECT 
    1, 
    1, 
    CHARINDEX(@separator, @ecoSystems), 
    1, 
    1, 
    CHARINDEX(@separator, @services) 
    UNION ALL 
    SELECT 
    [posE] + 1, 
    [endE] + 1, 
    CHARINDEX(@separator, @ecoSystems, [endE] + 1), 
    [posS] + 1, 
    [endS] + 1, 
    CHARINDEX(@separator, @services, [endS] + 1) 
    FROM [EcoSystemsAndServices] 
    WHERE [endE] > 0 
) 


SELECT 
    [g].[id], 
    [g].[typeOfEcoSystem], 
    [g].[service] 
FROM [Gecoserv] [g] 
INNER JOIN [EcoSystemsAndServices] [ess] 
    ON [g].[typeOfEcoSystem] = SUBSTRING(@ecoSystems, 
             [startE], 
             CASE WHEN [endE] > 0 THEN [endE] - [startE] ELSE 100 END) 
    AND [g].[service] = SUBSTRING(@services, 
            [startS], 
            CASE WHEN [endS] > 0 THEN [endS] - [startS] ELSE 100 END) 
ORDER BY [id] ASC 
+0

답해 주셔서 감사합니다. 그러나, 내가하고 싶은 것은 하나씩 요소를 쓰는 것이 아닙니다. 작성한 첫 번째 쿼리는 훌륭하게 작동하지만 동일한 순위를 가진 요소를 가져올 수있는 방법이 있어야합니다. (예 : typeNameList [4] and serviceList [4] 또는 typeNameList [28] and serviceList [28]) 그래서 내가 찾고있는 것은 질의가 배열 변수에서 항목을 선택할 수있게 해준다는 것입니다. typeNameList 및 serviceNameList입니다. 하지만 속임수는 요소가 같은 순위를 가져야합니다. –

+0

내 답변에 대한 대안을 추가했습니다. 그리고 당신은 당신의 대답을 제거 할 수 있습니까? – Jacco

+0

대단히 고마워요. 예, 내 시나리오에서 작동합니다. 그러나 우리에게는 문제가 있습니다. 것은 내가 Wavemaker에서 코딩하고 있으며 SQL 대신 HQL을 사용하고 있습니다. HQL에서 SQL 쿼리를 수정하여 적용 할 수 있다고 생각했습니다. 그러나 HQL에서 함수를 생성 할 수 있는지 여부는 알 수 없습니다. 나는 이것을 찾았으나 유용한 정보를 찾을 수 없었다. 그 상황에서 어떤 제안이 있습니까? –

0

없이, 내 대답은 설정에 대한 몇 가지 가정을해야합니다 .

이론

이것은 데카르트 제품처럼 엄청 많이 들린다. 문제의 핵심은 IN 절이 서로 독립적이라는 것입니다. 따라서 하나의 레코드가 두 조건을 모두 만족시킬 수 있지만 결과 세트에서보고자하는 레코드가 아닙니다. 예를 들어 다음과 같이 우리가 기록을 가지고 말 :

id name   typeOfEcosystem service 
-- ------------ --------------- ---------- 
1 myEcoService Freshwater  Recreation 

쿼리를, 그것을 지금 기록 된대로, 먼저 typeOfEcosystem (민물)를 타고 그것은 당신의 목록에 있는지 확인합니다. 결과 : TRUE

그런 다음 쿼리는 (Recreation) 서비스를 사용하고 두 번째 목록에 있는지 확인합니다. 다시 값이 발견됩니다. 결과 : TRUE

모든 조건이 true로 평가되므로 행이 최종 결과 집합에 포함됩니다. 당신이 절에 여러 열을 원하는처럼

솔루션

그것은 나에게 소리. 이는 최종 솔루션이 단일 IN 키워드 만 포함해야하므로 이는 귀하의 시도와 구별됩니다. 이제 쿼리의 정확한 형식은 데이터베이스에 많이 의존하며 제공되는 내용에 달려 있습니다. SQL 호환 데이터베이스에서 작동해야하는 솔루션은 문자열 조작을 사용하는 것입니다. 대략적인 예는 다음과 같습니다.

Select * 
    from Gecoserv _a 
where _a.typeOfEcosystem || '-' || _a.service IN ('Freshwater-Habitat', 'Saltwater-Food', 'Dunes-Recreation') 

이 예제에서 '||' 연결이라고 가정합니다. 이것은 매우 휴대 가능하지만 느립니다. 문제는 훨씬 더 우아하게 다루어 질 수 있지만 정확한 해결책은 특정 데이터베이스와 요구 사항에 훨씬 더 의존 할 것입니다. 당신은 그들이 당신의 DBMS와 잘 플레이를 할 수 이러한 솔루션 중 하나를 마사지 할 수 있습니다

Select * 
    from Gecoserv _a 
where (_a.typeOfEcosystem, _a.service) IN (('Freshwater', 'Habitat'), ('Saltwater', 'Food'), ('Dunes', 'Recreation')); 

: 예를 들어, 오라클 절에 여러 열은 간단 할 수 있습니다.

  1. SQL multiple columns in IN clause

  2. Select records where a combinations of columns are repeated using SQLite

+0

답변 해 주셔서 감사합니다. 그러나, 내가하고 싶은 것은 하나씩 요소를 쓰는 것이 아닙니다. 작성한 첫 번째 쿼리는 훌륭하게 작동하지만 동일한 순위를 가진 요소를 가져올 수있는 방법이 있어야합니다. (예 : typeNameList [4] 및 serviceList [4] 또는 typeNameList [28] 및 serviceList [28]) 그래서 내가 찾고있는 것은 쿼리를 통해 배열 변수에서 항목을 선택할 수있게 해줍니다. typeNameList 및 serviceNameList입니다. 하지만 속임수는 요소가 같은 순위를 가져야합니다. –

관련 문제