从连接数据创建SQL表

时间:2013-09-16 12:52:33

标签: sql database sql-server-2008

在我提出问题之前,这是关于我的数据的信息:

Table Name: dbo.DecodedCSVMessages_Staging
Columns: MMSI, Message_ID, Time, Vessel_Name, Ship_Type, IMO, Dimension_to_Bow, Dimension_to_stern, Dimension_to_port, Dimension_to_starboard, Draught, Longitude, Latitude

我需要创建一个新表。以下是表格中我需要的内容:

我对所有这些数据感兴趣,但我只需要1或3的Message_ID。**问题是,Message_ID的1和3 **缺少以下内容:(仅适用于Message_ID的5.)

Vessel_Name,  Ship_Type, IMO, 
Dimension_to_Bow, 
Dimension_to_stern,
Dimension_to_port, 
Dimension_to_starboard, 
Draught

对于Message_ID的1和3,这些列标记为NULL。他们只有

Longitude, 
Latitude, 
Time, 
MMSI

所有标记为空 Message_ID等于5

MMSI是此实例中的主键。 Message_ID的1,3和5都将具有代表给定船舶的MMSI号码。这些MMSI虽然在每艘船发出多个类型1,3和5的消息时重复出现。所以说我们的MMSI为210293000,这个数字将与几个Message_ID的不同类型并列。所以我需要做的就是获取1和3的所有Message_ID,并将Message_ID的信息附加到5和1和3。因此,列不再是NULL。

最后但并非最不重要的是,我必须选择仅属于以下内容的Message_ID 1和3:

Where Latitude > 55 and Latitude <85 and Longitude > 50 and Longitude < 141;

几列的示例:

MMSI/ Message_ID /Time/Ship_type/Vessel_Name/Latitude/Longitude

21029300, 3, 2012-06-01, NULL, NULL, 56.528003, 85.233443

21029300, 5, 2012-07-01, 70, RIO_CUBAL, NULL, NULL

2109300, 1, 2012-08-01, NULL, NULL, 57.432345, 131.123343

2109300, 1, 2012-09-01, NULL, NULL, 62.432345, 121.123343

2109300, 1, 2012-09-02, NULL, NULL, 65.432345, 140.123343

21029300, 5, 2012-08-01, 70, RIO_CUBAL, NULL, NULL

最终结果如下:

21029300, 3, 2012-06-01, 70, RIO_CUBAL, 56.528003, 85.233443

2109300, 1, 2012-08-01, 70, RIO_CUBAL, 57.432345, 131.123343

2109300, 1, 2012-09-01, 70, RIO_CUBAL, 62.432345, 121.123343

2109300, 1, 2012-09-02, 70, RIO_CUBAL, 65.432345, 140.123343

谢谢!

3 个答案:

答案 0 :(得分:0)

在单个事务中,创建新表,使用INSERT INTO ... SELECT ...将数据从DecodedCSVMessages_Staging传输到新表,然后DELETE FROM ...DecodedCSVMessages_Staging删除旧数据}。

答案 1 :(得分:0)

您可以选择类型1和类型3消息,并将联接中添加的信息添加到数据中第一个相应的类型5记录中。 (如果没有相应的Type 5记录,那么这些字段将获得空值。)试试这个:

SELECT DISTINCT M13.MMSI, M13.Message_ID, M13.Time, M13.Latitude, M13.Longitude,
M5.Vessel_Name, M5.Ship_Type, M5.IMO, M5.Dimension_to_Bow
M5.Dimension_to_stern, M5.Dimension_to_port, 
M5.Dimension_to_starboard, M5.Draught
FROM dbo.DecodedCSVMessages_Staging M13
JOIN (
SELECT MMSI, Time, Vessel_Name, Ship_Type, IMO, Dimension_to_Bow
Dimension_to_stern, Dimension_to_port, Dimension_to_starboard, 
Draught
FROM dbo.DecodedCSVMessages_Staging
WHERE Message_ID = 5
ORDER BY Time
) M5
ON M5.MMSI = M13.MMSI
WHERE M13.Message_ID IN (1, 3)
AND M13.Latitude > 55
AND M13.Latitude < 85
AND M13.Longitude > 50
AND M13.Longitude < 141
ORDER BY M13.Time

如果这返回了您想要的数据,则创建一个新表并使用INSERT INTO NewTable SELECT插入记录。

请注意,MMSI不是主表,无论是旧表还是新表。主键(PK)必须是唯一的,在这种情况下,每个MMSI都有多个条目。

创建新表时,应添加一个整数IDENTITY字段,以便它具有PK。此IDENTITY字段未包含在insert语句中,但会自动使用递增整数填充。这样每条记录都会得到一个独特的PK,这是非常需要的。

已编辑在外部查询中使用DISTINCT

答案 2 :(得分:0)

考虑到评论部分中的所有信息(特别是关于一次性事项说明),您可以尝试以下SQL语句。但是,只有在“类型5”消息的相关数据确实与您所说的一致时才会起作用!

SELECT Messages.MMSI
    ,Messages.Message_ID
    ,Messages.TIME
    ,Type5Messages.Vessel_Name
    ,Type5Messages.Ship_Type
    ,Type5Messages.IMO
    ,Type5Messages.Dimension_to_Bow
    ,Type5Messages.Dimension_to_stern
    ,Type5Messages.Dimension_to_port
    ,Type5Messages.Dimension_to_starboard
    ,Type5Messages.Draught
    ,Messages.Longitude
    ,Messages.Latitude
INTO [DataBaseName].[dbo].[YourNewTableName]
FROM dbo.DecodedCSVMessages_Staging Messages
LEFT OUTER JOIN (
    SELECT DISTINCT MMSI
        ,Vessel_Name
        ,Ship_Type
        ,IMO
        ,Dimension_to_Bow
        ,Dimension_to_stern
        ,Dimension_to_port
        ,Dimension_to_starboard
    FROM dbo.DecodedCSVMessages_Staging
    WHERE Messages.Message_ID = 5
    ) Type5Messages
    ON Messages.MMSI = Type5Messages.MMSI
WHERE Messages.Message_ID IN (1,3)
    AND Messages.Latitude > 55
    AND Messages.Latitude < 85
    AND Messages.Longitude > 50
    AND Messages.Longitude < 141;

在此语句中,您选择所有“类型1”和“类型3”行,并将它们与具有相同MMSI值的所有“类型5”行连接起来。如果关于所选列的“类型5”信息是一致的,则每个“类型5”行将只有一个条目,因此每个“类型1”和“类型3”行将仅出现一次。不过你应该做一些测试 INTO [DataBaseName].[dbo].[YourNewTableName]行(您必须以命名方式调整)创建一个新表(如果您选择尚未使用的名称)与原始表的数据类型并插入所选行。如果您需要indixes,keys,relationship或者任何其他内容,您可能希望稍后更改此表。