我有3个表连接在一起,我希望在B.val3上选择不同的行。我使用这样的东西:
SELECT A.val1,A.val2, B.val1, B.val2, B.val3, C.val1, C.val2
FROM A INNER JOIN
B ON A.val1 = B.val1 INNER JOIN
C ON A.val1 = C.val1
这句话给了我24行,重复了B.val3
现在,当我使用SELECT DISTINCT A.val1,A.val2, B.val1,...
时,检索到所有24条记录,但我只想要检索到的B.val3上的不同行(8行)
当我使用类似的东西时:
SELECT DISTINCT A.val1,A.val2, B.val1,
...
C ON A.val1 = C.val1 GROUP BY B.val3
我收到了一个错误:
Msg 8120, Level 16, State 1, Line 13
Column 'A.val1' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
编辑:结构和数据
表A如下:val2是B的外键,val3是外键C
val1 val2 val3
----- ----- -----
1 100 200
2 100 201
3 101 200
4 102 200
5 102 201
表B:
val1 val2 val3
----- ----- -----
100 a2 aaa
101 b2 bbb
102 c2 ccc
表C:
val1 val2
----- -----
200 a3
201 b3
我希望得到类似的东西:
A.val1 A.val2 A.val3 B.val1 B.val2 B.val3 C.val1 C.val2
----- ----- ----- ----- ----- ----- ----- -----
1 100 200 100 a2 aaa 200 a3
3 101 200 101 b2 bbb 200 a3
4 102 201 102 c2 ccc 201 b3
答案 0 :(得分:6)
您可以尝试这样的事情:
select *
from
(
SELECT A.val1,A.val2, B.val1, B.val2, B.val3, C.val1, C.val2
, row_number() over
(
partition by b.val3
order by A.val1, A.val2, B.val1, B.val2, C.val1, C.val2
) r
FROM A
INNER JOIN B ON A.val1 = B.val1
INNER JOIN C ON A.val1 = C.val1
) x
where x.r = 1
或
SELECT max(A.val1)
,max(A.val2)
, max(B.val1)
, max(B.val2)
, B.val3
, max(C.val1)
, max(C.val2)
FROM A
INNER JOIN B ON A.val1 = B.val1
INNER JOIN C ON A.val1 = C.val1
group by b.val3
取决于您要实现的目标。如果那些不能完成您所追求的目标,那么您能否提供更多关于您希望做什么/示例数据的信息?
您遇到的问题是,在选择不同的b.val3时,可能会有多个相关记录:
如果上述任何一个问题的答案都是肯定的,那么在选择要为其他列显示的数据时,需要给SQL一种方法来决定选择多个可能的记录/结果中的哪一个。
修改强>
根据上面给出的示例数据,请找到一个脚本来复制样本信息&显示解决方案:
if object_id('a') is not null drop table a
if object_id('b') is not null drop table b
if object_id('c') is not null drop table c
go
create table b
(
val1 int not null identity(100,1) primary key clustered
, val2 nvarchar(2) not null
, val3 nvarchar(3) not null
)
go
create table c
(
val1 int not null identity(200,1) primary key clustered
, val2 nvarchar(2) not null
)
go
create table a
(
val1 int not null identity(1,1) primary key clustered
, val2 int not null constraint fk_a_b foreign key references b(val1)
, val3 int not null constraint fk_a_c foreign key references c(val1)
)
go
--ids 100 - 105
insert b
select 'a2', 'aaa'
union all select 'b2', 'bbb'
union all select 'c2', 'ccc'
union all select 'c3', 'ccc' --val3 is not unique
union all select 'c4', 'ccc' --
union all select 'b3', 'bbb' --
--ids 200 - 204
insert c
select 'a3'
union all select 'b3'
union all select 'c3'
union all select 'd3'
union all select 'e3'
insert a
select 100, 200
union all select 100, 200
union all select 100, 201
union all select 101, 200
union all select 102, 200
union all select 102, 201
union all select 103, 201
union all select 104, 201
union all select 105, 201
union all select 105, 202
union all select 105, 203
union all select 105, 204
--what does the full result set look like?
SELECT A.val1 aval1
, A.val2 aval2
, B.val1 bval1
, B.val2 bval2
, B.val3 bval3
, C.val1 cval1
, C.val2 cval2
FROM A
INNER JOIN B
ON A.val2 = B.val1
INNER JOIN C
ON A.val3 = C.val1
--now show unique B's
select Aval1, Aval2, Bval1, Bval2, Bval3, Cval1, Cval2
from
(
SELECT A.val1 aval1
, A.val2 aval2
, B.val1 bval1
, B.val2 bval2
, B.val3 bval3
, C.val1 cval1
, C.val2 cval2
, row_number() over
(
partition by b.val3
order by b.val1, c.val1 --try playing with this to see how the results change / see what fits your requirements
) r
FROM A
INNER JOIN B
ON A.val2 = B.val1
INNER JOIN C
ON A.val3 = C.val1
) x
where x.r = 1
--what wasn't included in the unique B result set, but was in the full set?
select Aval1, Aval2, Bval1, Bval2, Bval3, Cval1, Cval2
from
(
SELECT A.val1 aval1
, A.val2 aval2
, B.val1 bval1
, B.val2 bval2
, B.val3 bval3
, C.val1 cval1
, C.val2 cval2
, row_number() over
(
partition by b.val3
order by b.val1, c.val1 --try playing with this to see how the results change / see what fits your requirements
) r
FROM A
INNER JOIN B
ON A.val2 = B.val1
INNER JOIN C
ON A.val3 = C.val1
) x
where x.r > 1
答案 1 :(得分:0)
看起来你正在从B获取行,第一个匹配在A中,然后是C中的任何匹配。
您可以这样做:
select *
from B join
(select A.*, row_number() over (partition by A.val2 order by A.val1) as seqnum
from A
) A
on B.val1 = A.val2 and
A.seqnum = 1 join
C
on A.val3 = C.val1