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

このステートメントは、重複する B.val3 を含む 24 行を取得します。使用する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.

EDIT : 構造とデータ

テーブル 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

あなたが達成しようとしているものに応じて。それらがあなたが望んでいることをしない場合は、あなたが望んでいること/サンプルデータに関する詳細情報を提供してください。

問題は、個別の 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 に答える