举个例子:
字段1,字段2,字段3
A A A
A B A
B B A
B E A
C D A
C D B这样的数据我想查出字段1和字段2之间一对一的数据
字段1,字段2
C D 怎么来组织SQL语句啊?
我自己写了个,但感觉效率不高
怎么能优化一下,或者更好的方法select distinct t1,t2
from table1
where t1 in (select t1
from (select distinct t1,t2 from table1) a
group by t1
having count(1)=1)
and t2 in (select t2
from (select distinct t1,t2 from table1) a
group by t2
having count(1)=1)
字段1,字段2,字段3
A A A
A B A
B B A
B E A
C D A
C D B这样的数据我想查出字段1和字段2之间一对一的数据
字段1,字段2
C D 怎么来组织SQL语句啊?
我自己写了个,但感觉效率不高
怎么能优化一下,或者更好的方法select distinct t1,t2
from table1
where t1 in (select t1
from (select distinct t1,t2 from table1) a
group by t1
having count(1)=1)
and t2 in (select t2
from (select distinct t1,t2 from table1) a
group by t2
having count(1)=1)
select distinct t1, t2
from (select t.*, count(1) over(partition by t1, t2) v_count from test t)
where v_count > 1
SQL> SELECT FIELD1, MAX(FIELD2) NEW_FIELD2
2 FROM TABLE_NAME TT
14 GROUP BY FIELD1
15 HAVING COUNT(DISTINCT FIELD2) = 1;FIELD1 NEW_FIELD2
------ ----------
C D
如果想都查出来 再套一层
-- 下面是我加了一个E,F,C记录的结果
SQL> SELECT * FROM TEST_NUM2;FIELD1 FIELD2 FIELD3
------ ------ ------
A A A
A B A
B B A
B E A
C D A
C D B
E F C7 rows selectedSQL> SELECT DISTINCT FIELD1, FIELD2
2 FROM (SELECT T.*, COUNT(1) OVER(PARTITION BY FIELD1, FIELD2) V_COUNT
3 FROM TEST_NUM2 T)
4 WHERE V_COUNT > 1;FIELD1 FIELD2
------ ------
C D-- 所以改成下面的就好了:
SQL> SELECT DISTINCT FIELD1, FIELD2
2 FROM (SELECT T.*, COUNT(DISTINCT FIELD2) OVER(PARTITION BY FIELD1) V_COUNT
3 FROM TEST_NUM2 T)
4 WHERE V_COUNT = 1;FIELD1 FIELD2
------ ------
C D
E F
字段1,字段2,字段3
A A A
A C B ------- 字段1中的值A 与字段2中的值A,B 各组成一条记录,这样就相当于一对二
B B C
E B D ------- 字段2中的值B 与字段2中的值B,E 各组成一条记录,这样就相当于一对二
C D E
C D F ------- 字段1中的值C 与且只与字段2中的值D 组成记录,虽然两条,但也算一对一
D F G ------- 很明显算一对一
这样的数据我想查出字段1和字段2之间一对一的数据
字段1,字段2
C D
D F
SQL> SELECT * FROM TEST_NUM2;FIELD1 FIELD2 FIELD3
------ ------ ------
A A A
A B A
B B A
B E A
C D A
C D B
E F C7 rows selectedSQL> SELECT FIELD1, MAX(FIELD2) NEW_FIELD2
2 FROM TEST_NUM2 TT
3 GROUP BY FIELD1
4 HAVING COUNT(DISTINCT FIELD2) = 1;FIELD1 NEW_FIELD2
------ ----------
C D
E FSQL> SELECT DISTINCT FIELD1, FIELD2
2 FROM (SELECT T.*, COUNT(DISTINCT FIELD2) OVER(PARTITION BY FIELD1) V_COUNT
3 FROM TEST_NUM2 T)
4 WHERE V_COUNT = 1;FIELD1 FIELD2
------ ------
C D
E F
这种语句是Oracle独有的么?我在DB2和MSSQL上执行不支持
我需要的运行环境是DB2,不过那边板块人少,就再也便也发了一个,呵呵
其实我需要的是三个主键之间的1:1:1的关系的数据,因为比较复杂,所以先考虑一下两个字段
2 FROM (SELECT C1,
3 C2,
4 COUNT(C2) OVER(PARTITION BY C1) R1,
5 COUNT(C1) OVER(PARTITION BY C2) R2
6 FROM (SELECT DISTINCT C1, C2 FROM T))
7 WHERE R1 = 1
8 AND R2 = 1;C1 C2
-- --
C D
D F
字段1,字段2,字段3,字段4
A A A A
A C B B
B B C C
E B D D
C D E E
C D F F
D F G G
三个字段的1:1:1关系,并且主要的我还想把字段4也查出来
现在看合格的数据只有
D F G G
SQL> SELECT * FROM TEST_NUM3;FIELD1 FIELD2 FIELD3 FIELD4
------ ------ ------ ------
A A A A
A C B B
B B C C
E B D D
C D E E
C D F F
D F G G
D F G H
D F G Z
H I J M10 rows selectedSQL> SELECT FIELD1, FIELD2, FIELD3, FIELD4
2 FROM (SELECT TT.*,
3 COUNT(1) OVER(PARTITION BY FIELD1) NEW_FIELD1,
4 COUNT(1) OVER(PARTITION BY FIELD2) NEW_FIELD2,
5 COUNT(1) OVER(PARTITION BY FIELD3) NEW_FIELD3,
6 COUNT(1) OVER(PARTITION BY FIELD1, FIELD2, FIELD3) COUNTS
7 FROM TEST_NUM3 TT) ZZ
8 WHERE NEW_FIELD1 = NEW_FIELD2
9 AND NEW_FIELD2 = NEW_FIELD3
10 AND NEW_FIELD3 = COUNTS;FIELD1 FIELD2 FIELD3 FIELD4
------ ------ ------ ------
D F G G
D F G H
D F G Z
H I J M
from t1 a,
(select ia.seg1 from t1 ia group by ia.seg1 having count(*)=1) b,
(select ib.seg1 from t1 ib group by ib.seg1,ib.seg2 having count(*)>1) c
where a.seg1=b.seg1 or a.seg1=c.seg1;
这个也可以实现,只是不知效率如何,楼主试后可否给个评价?
写成in(列表)的格式
select a.*
from t1 a
where a.seg1 in (select ia.seg1 from t1 ia group by ia.seg1 having count(*)=1) or
a.seg1 in (select ib.seg1 from t1 ib group by ib.seg1,ib.seg2 having count(*)>1)
我感觉这两个SQL的效率差不多。支持一下!
2 FROM T
3 WHERE (C1, C2, C3) IN (SELECT C1, C2, C3
4 FROM (SELECT C1,
5 C2,
6 C3,
7 COUNT(C1) OVER(PARTITION BY C1) R1,
8 COUNT(C2) OVER(PARTITION BY C2) R2,
9 COUNT(C3) OVER(PARTITION BY C3) R3
10 FROM (SELECT DISTINCT C1, C2, C3 FROM T))
11 WHERE R1 = 1
12 AND R2 = 1
13 AND R3 = 1);C1 C2 C3 C4
-- -- -- --
D F G G