Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL将坏表设计迁移到好表设计?_Sql_Sql Server_Database Normalization - Fatal编程技术网

SQL将坏表设计迁移到好表设计?

SQL将坏表设计迁移到好表设计?,sql,sql-server,database-normalization,Sql,Sql Server,Database Normalization,我正在将旧的Access数据库转换为SQL Server。规范化数据库的过程非常简单,但我遇到了一个似乎无法跨越的障碍 旧数据库使用一个表来保存框之间对象的移动。问题是,旧表不包含对象移动到的新框,而是所有旧框的日志。当前框保存在Obj表中。看看这把小提琴 有一个优雅的解决方案吗 TL:DR 旧表返回的数据如下所示 MoveID ObjectID OldBoxID DTMoved 1 27 22 2009-09-11 2 27

我正在将旧的Access数据库转换为SQL Server。规范化数据库的过程非常简单,但我遇到了一个似乎无法跨越的障碍

旧数据库使用一个表来保存框之间对象的移动。问题是,旧表不包含对象移动到的新框,而是所有旧框的日志。当前框保存在Obj表中。看看这把小提琴

有一个优雅的解决方案吗

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
试试这个:-

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 

我建议将您在此处添加的数据/代码的数量减少到说明问题所需的最小数量,这样我们就不必对所有数据/代码进行筛选。你更可能通过这种方式获得帮助,它目前看起来就像一堵巨大的数据和代码墙。你能查看sql fiddle链接吗?我只是粘贴了问题中的所有代码,以防小提琴不见了(为未来的研究人员着想)。fiddle使它变得更容易,因为您可以生成模式,然后使用我的sql查询查看数据。这正是我所需要的。这似乎是一张票。我以前从未听说过这个函数,但它会派上用场的(尤其是对于ROW_NUMBER)。