我有以下表格
Table 1
ID VAL ID2
1 a x
1 b x
1 b z
2 a x
3 a y
Table 2
ID VAL ID2
1 a x
1 b y
1 b x
1 b k
我想从表1中找到ID和VAL等于表2的Id和VAL的行,而表1的ID2不等于表2中的ID2。
我尝试的sql是
SELECT
t1.ID,t1.VAL,t1.ID2
FROM Table1 t1 LEFT JOIN Table2 t2 ON t1.ID=t2.ID
AND t1.Val=t2.Val AND t1.id2!=t2.ID2
WHERE
t2.ID IS NOT NULL
GROUP BY t1.ID,t1.VAL,t1.ID2 ;
,结果是
ID VAL ID2
1 b x
1 b z
但我想要的结果是
ID VAL ID2
1 b z
请咨询
谢谢
答案 0 :(得分:1)
只需翻译您的规则 - ID和Val匹配的所有项目除了ID,Val和ID2匹配的项目
SELECT DISTINCT t1.ID,t1.VAL,t1.ID2
FROM Table1 t1
JOIN Table2 t2 ON t1.ID=t2.ID AND t1.Val=t2.Val
EXCEPT
SELECT DISTINCT t1.ID,t1.VAL,t1.ID2
FROM Table1 t1
JOIN Table2 t2 ON t1.ID=t2.ID AND t1.Val=t2.Val AND t1.ID2=t2.ID2
您也可以使用左连接和其他逻辑来实现,但我认为简单总是更好,除非您发现需要优化。此外,这个简单版本(我们可以很容易地看到逻辑上正确)将允许您验证更复杂的查询。
答案 1 :(得分:1)
我喜欢Hogan的推理:简单可以是最好的。但是,它可以进一步简化;加上Oracle的关系减号运算符是MINUS
:
SELECT ID, VAL, ID2
FROM Table1 JOIN Table2 USING ( ID, Val )
MINUS
SELECT ID, VAL, ID2
FROM Table1 NATURAL JOIN Table2;
如果您觉得需要针对其他人在这些表格中添加更多列进行防御性编码,那么请随意将这些列明确表示(我个人从未在野外看到这样的情况),例如。
WITH T1 AS ( SELECT ID, VAL, ID2 FROM Table1 ),
T2 AS ( SELECT ID, VAL, ID2 FROM Table2 )
SELECT ID, VAL, ID2
FROM Table1 JOIN Table2 USING ( ID, Val )
MINUS
SELECT ID, VAL, ID2
FROM Table1 NATURAL JOIN Table2;
答案 2 :(得分:0)
如果我理解你的问题是正确的,请根据你的结果找到相同的代码。
DECLARE @Table1 AS TABLE (ID INT, VAL VARCHAR(10), ID2 VARCHAR(10))
INSERT INTO @Table1(Id,Val,ID2)
VALUES (1,'a','x'),
(1,'b','x') ,
(1,'b','z') ,
(2,'a','x') ,
(3,'a','y ')
DECLARE @Table2 AS TABLE (ID INT, VAL VARCHAR(10), ID2 VARCHAR(10))
INSERT INTO @Table2(Id,Val,ID2)
VALUES (1, 'a', 'x'),
(1, 'b', 'y'),
(1, 'b', 'x'),
(1, 'b', 'k')
--I want to find rows from table 1 where ID and VAL are equal to Id and VAL of table 2,--and table's 1 ID2 is not equal to ID2 from table 2.
SELECT DISTINCT t1.*
FROM @Table1 t1
INNER JOIN @Table2 t2 ON t2.ID = t1.Id AND T2.VAL = t1.VAL
AND t2.ID2 != t1.ID2
EXCEPT
SELECT *
FROM @Table2
答案 3 :(得分:0)
如果我正确地插入规则,你希望table1中的所有记录都不在table2中,基于ID,val和ID2,除了那些在table2中没有记录的记录。
with table1(ID, val, ID2) as
(Select 1, 'a','x' from dual UNION ALL
Select 1, 'b','x' from dual UNION ALL
Select 1, 'b','z' from dual UNION ALL
Select 2, 'a','x' from dual UNION ALL
Select 3, 'a','y' from dual),
table2(ID, val,ID2) as (
Select 1, 'a', 'x' from dual UNION ALL
Select 1, 'b', 'y' from dual UNION ALL
Select 1, 'b' , 'x' from dual UNION ALL
Select 1, 'b', 'k' from dual)
SELECT
t1.ID,t1.VAL,t1.ID2
FROM Table1 t1
LEFT JOIN Table2 t2
ON t1.ID=t2.ID
AND t1.Val=t2.Val
and t1.Id2=t2.ID2
WHERE t2.ID2 IS NULL
and exists (Select t2a.ID
from table2 t2a
where t2a.id = t1.id
--and t2a.val = t1.val;
);
- 但也许你也需要注释掉的内容,但我并没有很好地遵循这些要求。