2017-12-15 5 views
2

私は、分類で有効な年の範囲内にある分類IDを取得するためにのみ探しています。 NULLsを許可する必要があるので、私は左の結合を使用しています。集計が機能しない場合、どのようにして最大値で一連の結合を実行できますか?


私はテーブル持っている:私は取引から途切れを挿入するために、クエリに取り組んでいます、そして途切れが持つべき

CREATE TABLE comm (
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [comm_code] [varchar](20) NULL, /*should be unique*/ 
    [fk_classification_id_a] [bigint] NULL, 
    [fk_classification_id_b] [bigint] NULL 
--Rest of constraints... 
) 

CREATE TABLE classifications (
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [classification_code] [varchar](20) NOT NULL, 
    [description] [varchar](255) NULL, 
    [valid_from] [int] NULL, 
    [valid_to] [int] NULL 
--Rest of constraints... 
) 

insert into classifications (classification_code, description, valid_from, valid_to) 
values ('05012','Classification Number 1',2007,2012), 
('05012','Classification Number 1',2013,2016), 
('05012','Classification Number 1',2017,2020). 
('12043','Classification Number 2',2007,2010), 
('12043','Classification Number 2',2011,2020), 
('12345','Classification Number 3',2013,2015), 
('12345','Classification Number 3',2016,2020), 
('54321','Classification Number 4',2007,2009), 
('54321','Classification Number 4',2010,2013), 
('54321','Classification Number 4',2014,2020) 


CREATE TABLE comm_info_a (
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [comm_code] [nchar](10) NOT NULL, /*should be unique*/ 
    [classification_code] [nchar](6) NULL, 
    [thing] [nchar](6) NULL 
--Rest of constraints... 
) 

insert into comm_info_a (comm_code, classification_code) 
values ('0100100000','54321'), 
('8090010000','05012'), 
('5002310010','12043'), 
('0987654321','54321') 


CREATE TABLE comm_info_b (
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [comm_code] [nchar](10) NOT NULL, /*should be unique*/ 
    [classification_code] [nchar](6) NULL 
--Rest of constraints... 
) 

insert into comm_info_b (comm_code, classification_code) 
values ('0100100000','12043'), 
('8090010000','00000'), 
('5002310010','05012'), 
('1234567890','12345') 


CREATE TABLE transactions (
    [comm_code] [varchar](50) NULL, 
    [year] [varchar](255) NULL 
--Rest of constraints... 
) 

insert into transactions (comm_code, year) values 
('0100100000', 2013), 
('0100100000', 2015), 
('0100100000', 2017), 
('8090010000', 2009), 
('8090010000', 2010), 
('8090010000', 2011), 
('8090010000', 2015), 
('8090010000', 2017), 
('8090010000', 2018), 
('5002310010', 2008), 
('5002310010', 2014), 

そして最後にユニークcomm_code

次のようにクエリは次のとおりです。

INSERT INTO comm 
(comm_code, 
fk_classification_id_a, 
fk_classification_id_b) 
SELECT comm_code, 
ca.id, 
cb.id, 
MAX(year) 
FROM transactions t 
LEFT JOIN comm_info_a mia ON mia.comm_code=t.comm_code 
LEFT JOIN comm_info_b mib ON mib.comm_code=t.comm_code 
--these next two joins obviously do not work so I'm looking for something like it. Treat them as 'pseudo-code' 
LEFT JOIN classifications ca ON ca.classification_code=mia.classification_code AND 
MAX(t.year) BETWEEN ca.valid_from AND ca.valid_to 
LEFT JOIN classifications cb ON cb.classification_code=mib.classification_code AND 
MAX(t.year) BETWEEN cb.valid_from AND cb.valid_to 
-- end of the two joins 
WHERE NOT EXISTS 
(SELECT DISTINCT comm_code FROM comm) 
GROUP BY 
t.comm_code 
t.classification_code 

だから最後に私は、結果として、このような何かを得るために探しています:

comm_code | fk_classification_id_a | fk_classification_id_b 
-----------|------------------------|----------------------- 
0100100000 | 5      | 10 
8090010000 | 3      | NULL 
5002310010 | 5      | 2 

はcomm_codeが一意であることに注意してくださいこの表で!したがって、私は最新のトランザクション(したがって最大の年を集約する)にコミットしたい、そしてトランザクションの年が属する分類のIDを持つ必要があります。

本当のクエリははるかに複雑で長いですが、このかなり多くはすべての基盤をカバーします。コメントされているものを見てみましょう。私はそれが何らかのサブクエリで実行可能でなければならないことを理解していますが、私は試みましたが、今のところ、サブクエリに集計を渡す方法が見つかりませんでした。

私はこの問題にどのように対処できますか?

+0

テーブルが多すぎます...あなたは、あなたの問題の最小限のサンプルを投稿することができますか? –

+0

私はちょっと試してみますが、今のところこれは私がそれを提示できるほど簡単です。全体にはもっと多くのテーブルと結合があるので、結果として欲しいものと関連があると思ったものだけを含めました。私はできるだけsqlのフィドルに親しみやすいようにしようとしました。 – Nimchip

+0

定義を削除するか、少なくともinsert文を削除し、デモリンクを追加します。 –

答えて

1

改訂版の回答では、共通テーブル式を使用してcomm_codeあたりの最大年を計算し、最終結果では不要なcomm_codesを除外します。その後、ジョインで使用する各行にという値があるので、分類テーブルへのジョインは簡単です。dbfiddle here

CREATE TABLE transactions (
    [comm_code] [varchar](50) NULL, 
    [year] [varchar](255) NULL 
--Rest of constraints... 
) 

insert into transactions (comm_code, year) values 
('0100100000', 2013), 
('0100100000', 2015), 
('0100100000', 2017), 
('8090010000', 2009), 
('8090010000', 2010), 
('8090010000', 2011), 
('8090010000', 2015), 
('8090010000', 2017), 
('8090010000', 2018), 
('5002310010', 2008), 
('5002310010', 2014) 
; 
GO 
 
11 rows affected 

with transCTE as (
     select 
      t.* 
      , max(t.year) over(partition by comm_code) comm_max_year 
     from transactions t 
     left join comm on t.comm_code = comm.comm_code -- this table not in sample given 
     where comm.comm_code IS NULL -- use instead of NOT EXISTS 
    ) 
SELECT DISTINCT 
     t.comm_code 
    , ca.id as fk_classification_id_a 
    , cb.id as fk_classification_id_b 
    , t.comm_max_year 
FROM transCTE t 
LEFT JOIN comm_info_a mia ON mia.comm_code = t.comm_code 
LEFT JOIN classifications ca ON mia.classification_code = ca.classification_code 
     AND t.comm_max_year BETWEEN ca.valid_from AND ca.valid_to 
LEFT JOIN comm_info_b mib ON mib.comm_code = t.comm_code 
LEFT JOIN classifications cb ON mib.classification_code = cb.classification_code 
     AND t.comm_max_year BETWEEN cb.valid_from AND cb.valid_to 
ORDER BY 
     t.comm_code 
; 
GO 
 
comm_code | fk_classification_id_a | fk_classification_id_b | comm_max_year 
:--------- | :--------------------- | :--------------------- | :------------ 
0100100000 | 10      | 5      | 2017   
5002310010 | 5      | 2      | 2014   
8090010000 | 3      | null     | 2018   

デモ

CREATE TABLE classifications (
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [classification_code] [varchar](20) NOT NULL, 
    [description] [varchar](255) NULL, 
    [valid_from] [int] NULL, 
    [valid_to] [int] NULL 
--Rest of constraints... 
) 

insert into classifications (classification_code, description, valid_from, valid_to) 
values ('05012','Classification Number 1',2007,2012), 
('05012','Classification Number 1',2013,2016), 
('05012','Classification Number 1',2017,2020), 
('12043','Classification Number 2',2007,2010), 
('12043','Classification Number 2',2011,2020), 
('12345','Classification Number 3',2013,2015), 
('12345','Classification Number 3',2016,2020), 
('54321','Classification Number 4',2007,2009), 
('54321','Classification Number 4',2010,2013), 
('54321','Classification Number 4',2014,2020) 
; 
GO 
 
10 rows affected 
CREATE TABLE comm_info_a (
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [comm_code] [nchar](10) NOT NULL, /*should be unique*/ 
    [classification_code] [nchar](6) NULL, 
    [thing] [nchar](6) NULL 
--Rest of constraints... 
); 
GO 
insert into comm_info_a (comm_code, classification_code) 
values ('0100100000','54321'), 
('8090010000','05012'), 
('5002310010','12043'), 
('0987654321','54321') 
; 

GO 
 
4 rows affected 
CREATE TABLE comm_info_b (
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [comm_code] [nchar](10) NOT NULL, /*should be unique*/ 
    [classification_code] [nchar](6) NULL 
--Rest of constraints... 
); 
GO 
insert into comm_info_b (comm_code, classification_code) 
values ('0100100000','12043'), 
('8090010000','00000'), 
('5002310010','05012'), 
('1234567890','12345'); 
GO 
 
4 rows affected 
+0

悲しいことに、これは私が探しているものではありません。 commテーブルにはユニークなcomm_codeが必要です。なぜなら私は最初にグループバイスを使用しているからです。コミットは '最新の'トランザクション、それゆえMAX()集合から取られるべきです。 – Nimchip

+0

私は私の答えを改訂しました。説明をありがとう。 –

関連する問題