我有以下信息
|----------------------|
| Table1 |
|----------------------|
| Id | Info1 | Info2 |
|----------------------|
| 101 | foo | bar |
| 102 | bar | fubar |
| 103 | tot | bar |
| 104 | fubar | foo |
| 105 | foo | fubar |
| 106 | spur | tot |
| 107 | sar | nat |
我需要创建一个查询,以便只获取Info1列中Info1中的数据至少一次的行,Info2中的数据至少在Info1中一次,这意味着行中包含“tot”,“ Info1中的“and”和“sar”不应出现在结果中,因为“spur”和“sar”仅在Info1中出现,在“tot”的情况下,它出现在两列上,但由于行“spur”应该没有t出现然后Info1中带有“tot”的行不符合要显示的标准。
我尝试了以下几乎让我得到了我想要的东西
SELECT a.*
FROM Table1 a
WHERE EXISTS
(
SELECT 1
FROM Table1 b
WHERE a.Info2 = b.Info1
) and
EXISTS
(
SELECT 1
FROM Table1 c
WHERE a.Info1 = c.Info2
)
但它让我回答:
| Id | Info1 | Info2 |
|----------------------|
| 101 | foo | bar |
| 102 | bar | fubar |
| 103 | tot | bar |
| 104 | fubar | foo |
| 105 | foo | fubar |
我做错了吗?或者我应该寻找不同的方法?
这些是预期结果:
| Id | Info1 | Info2 |
|----------------------|
| 101 | foo | bar |
| 102 | bar | fubar |
| 104 | fubar | foo |
| 105 | foo | fubar |
答案 0 :(得分:1)
<强> SQL Fiddle Demo 强>
SELECT DISTINCT a.*
FROM table1 a
inner join table1 b
on ( a.Info1 = b.Info2
or a.Info2 = a.Info1
)
inner join table1 c
on ( b.Info2 = c.Info1
or b.Info1 = c.Info2
)
and a.Id <> c.Id
<强>输出强>
| Id | Info1 | Info2 |
|-----|-------|-------|
| 101 | foo | bar |
| 102 | bar | fubar |
| 104 | fubar | foo |
| 105 | foo | fubar |
大警告
如果需要3个以上的步骤,可能会破坏我的代码
CREATE TABLE table2
([Id] int, [Info1] varchar(5), [Info2] varchar(5))
;
INSERT INTO table2
([Id], [Info1], [Info2])
VALUES
(101, 'tar', 'foo'),
(102, 'foo', 'bar'),
(103, 'bar', 'car'),
(104, 'car', 'fish');
答案 1 :(得分:0)
怎么样:
SELECT *
FROM Table1
WHERE Info1 in (SELECT Info2 FROM Table1)
AND Info2 in (SELECT Info1 FROM Table1)
AND Id NOT IN (SELECT Id FROM Table1
WHERE (Info1 in (SELECT Info2 FROM Table1)
AND Info2 not in (SELECT Info1 FROM Table1))
OR (Info2 in (SELECT Info1 FROM Table1)
AND Info1 not in (SELECT Info2 FROM Table1))
)
所有嵌套选择都有点混乱,但这应该有效。
答案 2 :(得分:0)
尝试#1
select t.*
from
T as t
inner join (
select distinct Info1 as value from T t1 inner join T t2 on t2.Info2 = t1.Info1
) as v
on v.value in (Info1, Info2)
尝试#2
看到两个列也必须出现在另一个列表中的要求,我提供了这个建议。第一个查询解决了另一个问题。
select t.Id, t.Info1, t.Info2
from
T as t
inner join T as t2
on t2.Info2 = t.Info1 and t2.Id <> t.Id
inner join T as t3
on t3.Info1 = t.Info2 and t3.Id <> t.Id
group by t.Id, t.Info1, t.Info2
我看到这仍然没有删除第103行,所以我意识到要求仍然有点复杂。我稍后会再回来......
尝试#3
...不确定this是否优雅,但确实有效:
with
pass1(Info) as (
select distinct t1.Info1 from T t1 inner join T t2 on t2.Info2 = t1.Info1
),
pass2(Info) as (
select distinct case n when 1 then Info1 when 2 then Info2 end
from T, (select 1 union all select 2) as split(n)
where Info1 not in (select Info from pass1)
or Info2 not in (select Info from pass1)
)
select * from T
where Info1 not in (select Info from pass2)
and Info2 not in (select Info from pass2)
我使用 T 作为您的表格真实姓名的替身。在我看来,“Table1”使查询看起来更复杂。
答案 3 :(得分:0)
您只需要self join
和exists
条款并不困难:
select distinct t.*
from table1 t
join table1 t1 on t.info1=t1.info2
where exists(
select * from table1 t2
where t2.info2=t1.info1
)