这是一个简单的问题,当我有(A,B)作为我的查询的结果时,我想只有(A,B),而不是(B,A)。
例如,我的查询返回:
161, 52
161, 53
53, 161
53, 161
这是我的问题:
SELECT S1.SURVEY_ID, S2.SURVEY_ID
FROM SURVEYS S1, SURVEYS S2
WHERE (S2.START_DATE BETWEEN S1.START_DATE and S1.END_DATE
OR S2.END_DATE BETWEEN S1.START_DATE and S1.END_DATE)
AND S1.SURVEY_ID != S2.SURVEY_ID
ORDER BY S1.SURVEY_ID, S2.SURVEY_ID
答案 0 :(得分:4)
您可以使用条件排序将每个集(A,B) , (B,A)
组合为一个组。
SELECT MAX(S1.SURVEY_ID) as survey_id_1, MIN(S2.SURVEY_ID) as survey_id_2
FROM SURVEYS S1
INNER JOIN SURVEYS S2
ON (S2.START_DATE BETWEEN S1.START_DATE and S1.END_DATE
OR S2.END_DATE BETWEEN S1.START_DATE and S1.END_DATE)
WHERE S1.SURVEY_ID != S2.SURVEY_ID
GROUP BY CASE WHEN S1.SURVEY_ID > S2.SURVEY_ID
THEN S1.SURVEY_ID
ELSE S2.SURVEY_ID
END
ORDER BY survey_id_1, survey_id_2
这将导致(更大的调查,更小的调查) - 每组1个。
我还将您的连接语法更改为正确的连接语法,请尽量避免使用隐式连接语法(以逗号分隔)。
答案 1 :(得分:2)
这是一种方法:
WITH SS as (
SELECT S1.SURVEY_ID as SURVEY_ID1, S2.SURVEY_ID as SURVEY_ID2
FROM SURVEYS S1 JOIN
SURVEYS S2
ON (S2.START_DATE BETWEEN S1.START_DATE and S1.END_DATE OR
S2.END_DATE BETWEEN S1.START_DATE and S1.END_DATE
) AND
S1.SURVEY_ID <> S2.SURVEY_ID
)
SELECT ss.*
FROM ss
WHERE SURVEY_ID1 < SURVEY_ID2
UNION ALL
SELECT ss.*
FROM ss
WHERE SURVEY_ID1 > SURVEY_ID2 AND
NOT EXISTS (SELECT 1 FROM ss ss2 WHERE ss2.SURVEY_ID1 = ss.SURVEY_ID2 AND ss2.SURVEY_ID2 = ss.SURVEY_ID1);
但是,如果您只是想要重叠调查,那么这将是适当的查询:
SELECT S1.SURVEY_ID as SURVEY_ID1, S2.SURVEY_ID as SURVEY_ID2
FROM SURVEYS S1 JOIN
SURVEYS S2
ON S2.START_DATE <= S1.END_DATE AND
S2.END_DATE >= S1.START_DATE
S1.SURVEY_ID < S2.SURVEY_ID;
答案 2 :(得分:2)
不确定我是否真的理解这个问题。猜猜:你希望(A,B)被视为(B,A)的副本,其中一个被删除。
将值放入一个订单(在降低之前更高),然后您可以使用distinct:
SELECT distinct
(CASE WHEN S1.SURVEY_ID > S2.SURVEY_ID THEN S1.SURVEY_ID ELSE S2.SURVEY_ID END) as "higher id",
(CASE WHEN S1.SURVEY_ID > S2.SURVEY_ID THEN S2.SURVEY_ID ELSE S1.SURVEY_ID END) as "lower id"
...