2017-12-08 11 views
1

私は古いAccessデータベースをSQL Serverに変換しようとしています。データベースを正規化するのに、すべてがかなり簡単でしたが、私は交差することができないような障害に遭遇しました。SQLは、悪い表の設計を良い表の設計に移行しますか?

古いデータベースはテーブルを使用して、ボックス間でオブジェクトの移動を保持します。問題は、古いテーブルが、オブジェクトが移動された新しいボックスを保持していないことです。すべての古いボックスのログだけです。現在のボックスはObjテーブルに保持されます。このフィドルを確認してください。http://sqlfiddle.com/#!6/382bb/7/0

これには優雅な解決策がありますか?

TL:DR;

古いテーブルには、このようなデータを返して、

MoveID ObjectID OldBoxID DTMoved 
1  27   22  2009-09-11 
2  27   16  2008-01-19 
3  27   29  2004-10-31 

私はそれを返すようにしたい、

MoveID ObjectID OldBoxID NewBoxID DTMoved 
1  27   22  24**  2009-09-11 
2  27   16  22  2008-01-19 
3  27   29  16  2004-10-31 

**This value will be from the Obj table that shows the current BoxID for the object. 

フィドルがなくなっている場合は、ここに私のスキーマは、

CREATE TABLE Box (
[BoxID] int IDENTITY(1,1) NOT NULL, 
[BoxName] varchar(20) NULL, 
CONSTRAINT [PK_Box] PRIMARY KEY CLUSTERED 
(
    [BoxID] ASC 
)) 
GO 

INSERT INTO Box (BoxName) VALUES ('Box1') 
INSERT INTO Box (BoxName) VALUES ('Box2') 
INSERT INTO Box (BoxName) VALUES ('Box3') 
INSERT INTO Box (BoxName) VALUES ('Box4') 
INSERT INTO Box (BoxName) VALUES ('Box5') 
INSERT INTO Box (BoxName) VALUES ('Box6') 
INSERT INTO Box (BoxName) VALUES ('Box7') 
INSERT INTO Box (BoxName) VALUES ('Box8') 
INSERT INTO Box (BoxName) VALUES ('Box9') 
INSERT INTO Box (BoxName) VALUES ('Box10') 

CREATE TABLE Obj (
    [ObjectID] int IDENTITY(1,1) NOT NULL, 
    [ObjectName] varchar(20) NULL, 
    [CurrentBoxID] int NULL 
CONSTRAINT [PK_Obj] PRIMARY KEY CLUSTERED 
(
[ObjectID] ASC 
)) 
GO 

INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('tiger',3) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('file',8) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('press',9) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('heap',4) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('careful',6) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('fairies',5) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('uneven',7) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('fertile',5) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('brass',9) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('hospitable',8) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('stem',1) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('pastoral',9) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('strip',10) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('spiteful',9) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('scribble',6) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('vest',1) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('soothe',5) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('sin',4) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('fanatical',10) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('scissors',7) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('rat',3) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('plastic',5) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('store',6) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('mighty',1) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('juice',6) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('angry',8) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('zephyr',2) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('decorous',1) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('stretch',4) 
INSERT INTO Obj (ObjectName,CurrentBoxID) VALUES ('complete',9) 

CREATE TABLE Move (
    [MoveID] int IDENTITY(1,1) NOT NULL, 
    [ObjectID] int NULL, 
    [OldBoxID] int NULL, 
    [DTMoved] datetime NULL 
CONSTRAINT [PK_Move] PRIMARY KEY CLUSTERED 
(
    [MoveID] ASC 
)) 
GO 

INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (5,10,'01/15/2006') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (30,6,'05/21/2008') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (27,10,'06/12/2010') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (25,6,'10/30/2006') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (19,10,'08/30/2008') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (19,2,'05/01/2006') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (29,4,'01/24/2013') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (16,10,'04/08/2008') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (17,3,'03/11/2014') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (3,4,'02/25/2006') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (17,9,'06/05/2008') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (27,5,'12/31/2008') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (11,8,'01/08/2012') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (27,1,'09/21/2012') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (21,7,'07/22/2017') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (16,1,'02/19/2005') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (12,3,'09/12/2012') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (3,3,'05/08/2016') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (6,1,'09/12/2006') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (20,1,'12/13/2015') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (13,4,'10/20/2017') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (2,5,'06/21/2015') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (6,5,'11/21/2008') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (15,5,'09/10/2005') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (15,10,'10/20/2006') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (10,10,'06/07/2008') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (9,2,'10/19/2012') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (3,1,'10/27/2011') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (27,1,'03/03/2010') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (2,8,'12/06/2013') 
INSERT INTO Move (ObjectID,OldBoxID,DTMoved) VALUES (2,4,'03/29/2017') 
です

次の構造を返すクエリを探しています。

MoveID,ObjectID,DTMoved,OldBox,NewBox 
12,27,'2008-12-31',Box5,Box1 
29,27,'2010-03-03',Box1,Box10 
3,27,'2010-06-12',Box10,Box1 
14,27,'2012-09-21',Box1,Box2 

ここで私はフィドルの例を表示するために使用したクエリ、

--Move joins 
SELECT MoveID, M.ObjectID, DTMoved, BB.BoxName AS OldBox, B.BoxName AS CurrentBox 
FROM Move M 
    INNER JOIN Obj O ON M.ObjectID = O.ObjectID 
    INNER JOIN Box B ON O.CurrentBoxID = B.BoxID 
    INNER JOIN Box BB ON M.OldBoxID = BB.BoxID 
ORDER BY O.ObjectID, DTMoved 

--How many moves per box 
SELECT ObjectID, COUNT(ObjectID) 
FROM Move 
GROUP BY ObjectID 
ORDER BY COUNT(ObjectID) DESC 

--Look at Object ID 27 
SELECT MoveID, M.ObjectID, DTMoved, BB.BoxName AS OldBox, '' AS NewBox, B.BoxName AS CurrentBox 
FROM Move M 
    INNER JOIN Obj O ON M.ObjectID = O.ObjectID 
    INNER JOIN Box B ON O.CurrentBoxID = B.BoxID 
    INNER JOIN Box BB ON M.OldBoxID = BB.BoxID 
WHERE M.ObjectID = 27 
ORDER BY DTMoved DESC 
+0

は、私は、データ/コードの量を削減することをお勧めしたいあなたあなたが問題を説明するのに必要な最低限の額をここに加えて、それをすべて調べる必要はありません。あなたはその方法を助ける可能性が高いですが、現在のところ、データとコードの大きな壁のように見えます。 – Tanner

+1

sqlのフィドルリンクを表示できましたか?私は、フィドルがなくなった場合にのみ質問のすべてのコードを貼り付けました(将来の研究者のことを考えています)。あなたがスキーマを生成し、次にSQLクエリを使用してデータを表示できるので、フィドルが簡単になります。 –

答えて

1

これを試してみてください、次のとおりです。 -

SELECT MoveID, M.ObjectID, DTMoved, BB.BoxName AS OldBox 
,isnull(lead(oldboxid) OVER (ORDER BY DTMoved), O.CurrentBoxID) As newBoxId 
FROM Move M 
    INNER JOIN Obj O ON M.ObjectID = O.ObjectID 
    INNER JOIN Box BB ON M.OldBoxId = BB.BoxID 
WHERE M.ObjectID = 27 
ORDER BY DTMoved 
+1

これはまさに私の道を踏み出すために必要なものです。 [LEAD機能](https://docs.microsoft.com/en-us/sql/t-sql/functions/lead-transact-sql)がチケットのようです。以前はこの関数について聞いたことがありませんでしたが、これは便利です(特にROW_NUMBERの場合)。 –

関連する問題