1

我有 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    
4

2 回答 2

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

取决于您要达到的目标。如果那些不做你所追求的,请你能提供更多关于你希望做什么/示例数据的信息吗?

您所拥有的问题是选择Distinct B.Val3时,可能有多个记录关联:

  • 表 B 中 V3 列中的值是否唯一?
  • 表 A 和/或 C 的 V1 列中的值是否唯一?

如果上述任何一个问题的答案是否定的,您需要为 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 
于 2012-08-14T08:15:18.117 回答
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
于 2012-08-14T13:20:56.067 回答