2016-12-07 18 views
1

これはSQL Server 2016データベース用です。このケース(SQL Server)の代わりにSQLを作成する方法の提案が必要です

Iは以下のように、2つのテーブルを有する:

  • GlobalIdのUNIQUEIDENTIFIER、
  • 日付DATETIME2、
  • 説明

表B

  • GlobalId UNIQUEIDENTIFIER、
  • Rel_GlobalId UNIQUEIDENTIFIER、
  • ファイル名はnvarchar(250)、
  • 日付DATETIME2

は、テーブルAとテーブルBとの関係は1対多であり、または '表AのA行に表Bの1つ以上の行が含まれています。

Bには、常に1つ以上の行が含まれていますA.しかし、最初の行と最後の行だけが必要です(表Bの日付でソートされています)。したがって、表Aの行にも表Bの行が10行あります。

GlobalId (from A), First_File (GlobalId from B), Last_File (GlobalID from B), First_File_Num*, Last_File_Num* 

First_File_NumLast_File_Num 1から無限大まで開始、シーケンシャル番号であるが、これ:私は次の形式で値を返さなければならない最初のB.

のみ1 B必要ました単一の連続番号です。 Aが2つのB、first_file_num = 1、およびlast_file_num = 2を有する場合、連続した行では、その連続番号は最後の行から継続しなければならないので、3と4、さらに5と6などでなければならない。この行の増分は1だけです。

物事をより明確にする(と英語は私の第一言語ではないので)、一例として、これを取る:

表A

+----------+------------+----------------+ 
| GlobalId | Date  | Description | 
+----------+------------+----------------+ 
| aa  | 2016-12-06 | Description 01 | 
| ab  | 2016-12-07 | Description 02 | 
| ac  | 2016-12-07 | Description 03 | 
+----------+------------+----------------+ 

表B

+----------+--------------+------------+---------------------+ 
| GlobalId | Rel_GlobalId | Filename | Date    | 
+----------+--------------+------------+---------------------+ 
| ba  | aa   | file02.jpg | 2016-12-06 05:13:25 | 
| bb  | aa   | file01.jpg | 2016-12-06 03:45:12 | 
| bc  | ab   | file03.jpg | 2016-12-07 08:54:31 | 
| bd  | ac   | file05.jpg | 2016-12-07 11:39:19 | 
| be  | ac   | file04.jpg | 2016-12-07 10:48:13 | 
| bf  | ac   | file06.jpg | 2016-12-07 15:08:17 | 
+----------+--------------+------------+---------------------+ 

表Aと表Bとの関係は、A.GlobalId = B.Rel_GlobalId

だから、今、私は次のようなデータを持つテーブルを返す必要があります。この問題を解決するには

+----------+------------+-----------+----------------+---------------+ 
| GlobalId | First_File | Last_File | First_File_Num | Last_File_Num | 
+----------+------------+-----------+----------------+---------------+ 
| aa  | bb   | ba  | 01    | 02   | 
| ab  | bc   | NULL  | 03    | NULL   | 
| ac  | be   | bf  | 04    | 05   | 
+----------+------------+-----------+----------------+---------------+ 

、私は、関数(テーブル値関数)を作成しましたが、私はこれが可能であるかどうかを知りたいですD

+0

row_numbers()、日付が1のもの、日付descのもの。サブクエリ/ CTEに入れて、両方のrow_numbersが1である場所を選択します。 – HoneyBadger

+0

そして、「First_File_Num」と「Last_File_Num」の連続番号はどこで取得できますか?彼らは既に表Bに入っていますか?またはFileNameにはありますか? – DVT

+0

@DVT彼らはどこにもいません。それはオンザフライで '計算'されなければならない連続番号です。単なるシーケンスです。 –

答えて

1

/*このケース(SQL Server)の代わりにSQLを作成する方法の提案が必要です。*/ I need a suggestion for how to create a SQL instead a function for this case (SQL Server)(このビューでは、複数のビューを作成する必要があります)

これは可能ですcteを送信し、複数のrow_number()を使用する(HoneyBadgerのコメントのように)。

rextester:でhttp://rextester.com/FHQIL42952

create table a (
    globalid varchar(36) not null primary key 
    , date  datetime2(2) not null 
    , description varchar(128) not null 
); 
create table b (
    rel_globalid varchar(36) not null 
    , globalid  varchar(36) not null 
    , filename  varchar(128) not null 
    , date   datetime2(2) not null 
); 
insert into a (globalid, date, description) values 
    ('aa','2016-12-06','Description 01') 
, ('ab','2016-12-07','Description 02') 
, ('ac','2016-12-07','Description 03'); 

insert into b (globalid, rel_globalid, filename, date) values 
('ba','aa','file02.jpg','2016-12-06T05:13:25') 
,('bb','aa','file01.jpg','2016-12-06T03:45:12') 
,('bc','ab','file03.jpg','2016-12-07T08:54:31') 
,('bd','ac','file05.jpg','2016-12-07T11:39:19') 
,('be','ac','file04.jpg','2016-12-07T10:48:13') 
,('bf','ac','file06.jpg','2016-12-07T15:08:17'); 

with cte as (
    select 
     globalid 
    , rel_globalid 
    , filename 
    , date 
    , rn_a = row_number() over (partition by rel_globalid order by date asc) 
    , rn_d = row_number() over (partition by rel_globalid order by date desc) 
    from b 
) 
, x as (
    select 
     globalid 
    , rel_globalid 
    , filename 
    , date 
    , rn_a 
    , rn_d 
    , seq = row_number() over (order by globalid, date asc) 
    from cte 
    where rn_a = 1 
    or rn_d = 1 
) 

    select 
     a.globalid 
    , first_file  = ba.globalid 
    , last_file  = bd.globalid 
    , first_file_num = ba.seq 
    , last_file_num = bd.seq 
    from a 
     left join x as ba on a.globalid = ba.rel_globalid and ba.rn_a = 1 
     left join x as bd on a.globalid = bd.rel_globalid and bd.rn_d = 1 and bd.rn_a !=1 
    order by a.globalid; 

結果:

globalid first_file last_file first_file_num last_file_num 
aa   bb   ba   1   2 
ab   bc   NULL   3   NULL 
ac   be   bf   4   5 
+0

Tks。私は「cte」を知らない。しかし最後の行(globalid = ac)では、first_file_numは4、last_file_numは6です。last_file_numは5でなければなりません。 –

+0

@ Roberto-Correia別の 'cte'を使ってファイル番号を修正しました。 s:https://msdn.microsoft.com/en-us/library/ms175972.aspx – SqlZim

0

私はむしろレコードの最後の行を返す関数を作成し、最初の行を返すストアドプロシージャを作成してしまうと関数にクロスを適用すると、apply演算子は非常に便利で、内部結合としての作業がないため、選択クエリの影響は非常に小さい

関連する問題