2016-05-27 1 views
0

GPSスポットの複数のソースからのテストデータを表示するビューがあります。 このビューには、「GPSポイントID」と、このGPSポイントに関連するいくつかの地質試験結果が表示されます。SQL Server:IDレコードを変更するためのテーブルデザイン

GPS-POINT-IDは次のようである:XYZ-0XX-CCCCC

  • XYZ:エリア
  • 00XX:ID
  • CCCCは:

GPSポイント名を座標(XYZ-0XX)の最初の部分は同じで変更されませんが、座標部分(CCCC)は新しいGPSポイントの場所に応じて変化します。

私は、前に述べたビューをデータソースとして持つテーブルを設計したかったのです。

  • 主キー::私はフルGPS-POINT-IDを使用している場合、それは時間をかけて頻繁に変化するので、私は変更を追跡することはできません私は、次について決定する必要があります。私はポイントを追跡することはできません。私はそれを歴史的記録にリンクすることはできません。

  • GPS-Point-ID(XYZ-00XX)の固定部分を計算カラムとして使用すると、同じポイントには同じ履歴レコードが多数あるため、プライマリキーとして使用できません(XYZ-00XX)部分では、これは主キー重複制約に違反します。

  • 新しいレコードごとに増加するID列を作成すると、各ポイント名の変更を追跡し、最新のテストデータと各ポイント(XYZ-00XX)の履歴データを取得する方法を教えてください。

ビューのサンプル行がスナップショットに添付されています。

Sample Query from against the view

おかげ

+0

2つの列で構成されるプライマリキーを使用しないでください。GPS-Point-IDとCoordinateの部分が固定されていませんか? –

+0

私はそれを試みましたが、同じGPS-POINT-ID + Coordinateの部分では複数のテストが行​​われ、2つの列が重複しています。 –

+0

'Update-Date'をキーに追加します。 –

答えて

1

ノービジネス価値を持つ主キーのIDを使用することをお勧めします。私は静的なデータと変化するデータの2つの列にデータを格納します。次に、必要な場合は、それらを1つのフィールドとしてまとめた計算列を作成できます。履歴に従うことができるように日付フィールドを追加することもできます。静的データ列は、レコードを結びつける識別子です。

何らかの理由で履歴レコードを追跡するために監査を使用しないと仮定しています。それが私が通常取るアプローチです。

http://weblogs.asp.net/jongalloway/adding-simple-trigger-based-auditing-to-your-sql-server-database

EDIT:唯一の更新が与えられた日に発生する可能性があれば サンプルクエリが動作します。複数の更新が発生する可能性がある場合は、group byの代わりにrow_number関数を使用できます。

Select * 
     From Table T1 
     Join (Select Max(MatchDate) MatchDate, GpsStaticData 
       From Table Group By GpsStaticData) T2 
      On T1.GpsStaticData = T2.GpsStaticData And T1.UpdateDate = T2.MatchDate 

EDIT:あなたが選択されたレコードを決定するためにROW_NUMBER関数にUpdateDate ORDER BYの後に複数のフィールドを追加することができます

With cteGetLatest As 
(
Select UpdateDate MatchDate, GpsStaticData, 
     Row_Number() Over (Partition By GpsStaticData, Order By UpdateDate Desc) SortOrder 
) 

Select * 
    From Table T1 
    Join (Select MMatchDate, GpsStaticData 
       From cteGetLatest Where SortOrder = 1) T2 
      On T1.GpsStaticData = T2.GpsStaticData And T1.UpdateDate = T2.MatchDate 

ROW_NUMBERを使用して ()。人工の列を避ける--to

+0

あなたの答えにお答えいただき、ありがとうございます。 "RF-0014"の最新のテスト結果をどのように問い合わせることができますか?私が最新の「Coordinate Suffix」を正確に知らないのであれば? –

+0

サンプルクエリを自分の答えに追加します。 –

+0

これは素晴らしいことです。これは、最新のテスト日付で各静的ポイントデータを結合します。それは100%そのままですが、同じ静的フィールドに2つのテストが同時にある場合は、積極的に働き、効果的な解決策を求めたいのですか?私はこれがPKとしてのフィールドではないとも仮定していますか? –

0

は、オーバーヘッド主キーを使用することができる化合物をコスト:

-- Simulate the Source View 
CREATE TABLE ybSourceView (
    [GPS-POINT-ID] VARCHAR(20), 
    [Status] NVARCHAR(MAX), 
    UpdateDate [datetime2], 
    Reason NVARCHAR(MAX), 
    OpId VARCHAR(15) 
); 

-- Source View sample data 
INSERT INTO ybSourceView ([GPS-POINT-ID], [Status], UpdateDate, Reason, OpId) 
VALUES ('RF-0014-9876', 'Reachable' , '2015-01-27 13:36', 'New Updated Coordinate'     , 'AFERNANDO'), 
     ('RF-0014-9876', 'Reachable' , '2014-02-27 09:37', 'New Updated Coordinate'     , 'AFERNANDO'), 
     ('RF-0014-3465', 'Reachable' , '2015-04-27 09:42', 'New Updated Coordinate'     , 'HRONAULD'), 
     ('RF-0014-2432', 'Reachable' , '2013-06-27 12:00', 'New Updated Coordinate'     , 'AFERNANDO'), 
     ('RF-0015-9876', 'OUT_OF_Range', '2014-04-14 12:00', 'Point Abandoned, getting new coordinate', 'AFERNANDO'); 

-- Historic Data Table 
CREATE TABLE ybGPSPointHistory (
    Area VARCHAR(5) NOT NULL DEFAULT '', 
    ID VARCHAR(10) NOT NULL DEFAULT '', 
    Coordinates VARCHAR(20) NOT NULL DEFAULT '', 
    [GPS-POINT-ID] VARCHAR(20), 
    [Status] NVARCHAR(MAX), 
    UpdateDate [datetime2] NOT NULL DEFAULT SYSUTCDATETIME(), 
    Reason NVARCHAR(MAX), 
    OpId VARCHAR(15), 
    CONSTRAINT ybGPSPointHistoryPK PRIMARY KEY (Area, ID, UpdateDate) --< Compound Primary Key 
); 
GO 

-- Update Historic Data Table from the Source View 
INSERT INTO ybGPSPointHistory (Area, ID, Coordinates, [GPS-POINT-ID], [Status], UpdateDate, Reason, OpId) 
SELECT LEFT(Src.[GPS-POINT-ID], LEN(Src.[GPS-POINT-ID]) - 10), RIGHT(LEFT(Src.[GPS-POINT-ID], LEN(Src.[GPS-POINT-ID]) - 5), 4), RIGHT(Src.[GPS-POINT-ID], 4), Src.[GPS-POINT-ID], Src.[Status], Src.UpdateDate, Src.Reason, Src.OpId 
FROM ybSourceView Src 
LEFT JOIN ybGPSPointHistory Tgt ON Tgt.[GPS-POINT-ID] = Src.[GPS-POINT-ID] AND Tgt.UpdateDate = Src.UpdateDate 
WHERE Tgt.[GPS-POINT-ID] Is NULL; 

--Tests(PKの使用を確認するために実際の実行計画を確認してください):

-- Full history 
SELECT * FROM ybGPSPointHistory; 

-- Up-to-date only 
SELECT * 
FROM (
    SELECT *, RANK() OVER (PARTITION BY Area, ID ORDER BY UpdateDate DESC) As HistoricOrder 
    FROM ybGPSPointHistory 
) a 
WHERE HistoricOrder = 1; 

-- Latest record for a particular ID 
SELECT TOP 1 * 
FROM ybGPSPointHistory a 
WHERE [GPS-POINT-ID] = 'RF-0014-9876' 
ORDER BY UpdateDate DESC; 

-- Latest record for a particular ID in details (more efficient) 
SELECT TOP 1 * 
FROM ybGPSPointHistory a 
WHERE Area = 'RF' AND ID = '0014' AND Coordinates = '9876' 
ORDER BY UpdateDate DESC; 

-- Latest record for a particular point 
SELECT TOP 1 * 
FROM ybGPSPointHistory a 
WHERE Area = 'RF' AND ID = '0014' 
ORDER BY UpdateDate DESC; 

- クリーンアップ:

DROP TABLE ybGPSPointHistory; 
DROP TABLE ybSourceView; 
関連する問題