【问题标题】:Join multiple tables without having common key在没有公共键的情况下加入多个表
【发布时间】:2020-05-12 11:51:30
【问题描述】:

我正在开展一个关于创建 ETL 流程的项目,但遇到了 1 个问题,我需要使用 3 个不同的表将数据插入到维度表中,而没有可以用来连接表的公共键。我试图用 CTE 解决这个问题,但没有用。

地震数据表

Table Earthquake

城市数据表

Table City

国家数据表

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

产生这个结果

Result

注意:除 City 以外的列重复次数过多。

我的期望:Earthquake Table 中的每一行只有 1 个最接近的对应城市,City 中的 Country,Country 表中的 Region 和 Earthquake 表中的 Place。

我没有使用没有公共键的表,所以我不知道为什么以及是什么导致了这个问题。 有人能帮我吗?提前致谢

【问题讨论】:

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


    【解决方案1】:

    这个呢?

    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 来获取离特定地震最近的城市。 Тhen 使用INNER JOIN 获取数据。

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

    【讨论】:

    • 非常感谢,Gotqn,经过一些调整后,它并没有很好地工作。再次感谢。
    【解决方案2】:

    或者,

    使用Split String UDF 拆分EarthQuake 表的Place 列。

    ;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 table 是否需要。

    或者你可以运行看看有多少没有citycountry的数据丢失, 为什么?

    这样你就可以创建算法了。

    【讨论】:

    • 非常感谢,Harsh Kumar。
    猜你喜欢
    • 2020-10-12
    • 1970-01-01
    • 2018-09-19
    • 2020-04-25
    • 1970-01-01
    • 2021-12-07
    • 2018-04-11
    • 1970-01-01
    相关资源
    最近更新 更多