在没有公用密钥的情况下联接多个表

时间:2020-01-27 05:20:21

标签: sql-server tsql common-table-expression

我正在从事一个有关创建ETL流程的项目,但遇到了1个问题:我需要使用3个不同的表将数据插入到Dimension表中,而没有可以连接表的通用密钥。我试图通过CTE解决此问题,但没有用。

带数据的地震表

enter image description here Table Earthquake

带有数据的城市表

enter image description here Table City

具有数据的国家/地区表

enter image description here Country Table

**我正在尝试做的** 我需要找到发生地震的城市,国家和世界地区,并将结果值存储在不同的表格中。 因此,通过使用计算提供的位置之间距离的公式。我从地震台获得的第一位置,从城市纬度和经度获得的第二位置。

( 6371 * acos( cos( radians(E.Latitude) ) * cos( radians( C.Latitude ) ) *  cos( radians( C.Longitude) - radians(E.Longitude) ) + sin( radians(E.Latitude) ) * sin( radians( C.Latitude ) ) ) )   < 100 

这里C.Latitude是城市的纬度,而E.Latitude是城市的纬度。

这是我无效的CTE方法。

WITH Test_CTE (
    Latitude
    ,Longitude
    ,City
    ,Country
    ,Region
    ,Place
    )
AS (
    SELECT E.Latitude
        ,E.Longitude
        ,C.City
        ,C.Country
        ,Cntry.Region
        ,Cast(E.place AS VARCHAR(50))
    FROM Earthquake AS E
        ,(
            SELECT Latitude
                ,Longitude
                ,Country
                ,City
            FROM City
            ) AS C
        ,(
            SELECT Country
                ,Region
            FROM Country
            ) AS Cntry
    WHERE (6371 * acos(cos(radians(E.Latitude)) * cos(radians(C.Latitude)) * cos(radians(C.Longitude) - radians(E.Longitude)) + sin(radians(E.Latitude)) * sin(radians(C.Latitude)))) < 100
        AND Cntry.Country = C.Country
    )
SELECT *
FROM Test_CTE

产生此结果的

enter image description here Result

注意:“城市”以外的其他列重复太多次。

我的期望:“地震表”中的每一行都只有1个最接近的对应城市,“城市”中的“国家”,“国家”表中的“地区”和“地震表”中的“地点”。

在没有公用密钥的情况下,我无法使用表,因此我不知道为什么以及导致此问题的原因。 有人能帮我吗?在此先感谢

2 个答案:

答案 0 :(得分:0)

那呢?

SELECT  E.Latitude
        ,E.Longitude
        ,C.City
        ,C.Country
        ,Cntry.Region
        ,Cast(E.place AS VARCHAR(50))
FROM Earthquake E
CROSS APPLY
(
    SELECT TOP 1 City
    FROM City
    WHERE (6371 * acos(cos(radians(E.Latitude)) * cos(radians(C.Latitude)) * cos(radians(C.Longitude) - radians(E.Longitude)) + sin(radians(E.Latitude)) * sin(radians(C.Latitude)))) < 100
    ORDER BY (6371 * acos(cos(radians(E.Latitude)) * cos(radians(C.Latitude)) * cos(radians(C.Longitude) - radians(E.Longitude)) + sin(radians(E.Latitude)) * sin(radians(C.Latitude)))) ASC
) City
INNER JOIN City C
    ON City.City = C.City
INNER JOIN Country Cntry
    ON C.Country = Cntry.Country

想法是使用CROSS APPLY来获取最接近特定地震的城市。使用INNER JOIN时获取数据。

您可以使用OUTER APPLY列出距离100个城市最近的记录。

答案 1 :(得分:0)

或者,

使用Split String UDF拆分EarthQuake表的“位置”列。

;with CTE as
(
select EQ.*,SScol from EarthQuake EQ
cross apply(select col split_string(Place,' ')SS )SS
)
,CTE1 as
(
select Ct.*,c.country,c.city from CTE ct
left join City C on ct.col=c.country
)
,CTE2 as
(
select Ct.*,c.country,c.city from CTE1 ct
left join City C on ct.col=c.city
)

这会给您带来增强CityCountry表的想法。

我不知道是否需要Country表。

或者您可以运行以查看缺少了多少个citycountry的数据, 和为什么?

这样您就可以创建一个算法。