【问题标题】:SQL : Needs help in joins in Sql ServerSQL:在 Sql Server 中的连接中需要帮助
【发布时间】:2012-09-07 10:48:26
【问题描述】:

我有以下表格,架构是


表:成员

Id        // PK Int Auto Increment
MemberID
MembershipType        // Holds MemberShipMaster types 1/2/3 for Prem, Corp or Free
RegisteredCountry     // FK of CountryMaster table
RegisteredState       // FK of States Table
RegisteredCity        // FK of Districts table
PostalCountry         // FK of CountryMaster table
PostalState           // FK of States Table
PostalCity            // FK of Districts table

请注意:邮政地址和注册地址可能不同(其逻辑...)


表:CountryMaster

Id        // PK , int auto increment
Country   // Name of Country

表:MemberShipMaster

Id               // PK int auto increment
Type             // Type Id int   , 1,2,3 respectively for Prem, Corp and Free
TypeName          // Membership Type Name e.g. Premium, Corporate, Free

Tbale : 城市

Id,         // PK int auto increment
Name       
StateId     // FK, PK of states table

表格:状态

Id   // PK int auto increment
Name           
CountryId // FK , PK of COuntry

以下是我的查询

SELECT Id , MemberID, MembershipType, Districts.Name as RegisteredCity,
States.Name as RegisteredState,CountryMaster.Country as RegisteredCountry,
Districts.Name as PostalCity,States.Name as PostalState, CountryMaster.Country as PostalCountry 
FROM   dbo.JFPMembers RIGHT  JOIN MemberShipMaster ON MemberShipMaster.Id= dbo.JFPMembers.MembershipType  
LEFT  JOIN  Districts ON dbo.JFPMembers.PostalCity = Districts.Id OR  Districts.Id =JFPMembers.RegisteredCity
LEFT  JOIN  States ON States.Id = dbo.JFPMembers.RegisteredState OR States.Id = dbo.JFPMembers.PostalState
LEFT  JOIN CountryMaster ON CountryMaster.Id = dbo.JFPMembers.RegisteredCountry and CountryMaster.Id = dbo.JFPMembers.postalCountry
Where Id= @id

我的预期输出:

根据列中保存的 id,在下面的字段中填写适当的城市、州或国家/地区名称。但相反,我在所需的列中得到空值。我已经确认这两个值存在于数据库中以用于连接。

Districts.Name 作为 RegisteredCity,States.Name 作为 RegisteredState,CountryMaster.Country 作为 RegisteredCountry,Districts.Name 作为 PostalCity,States.Name 作为 PostalState,CountryMaster.Country 作为 PostalCountry

【问题讨论】:

    标签: .net sql sql-server sql-server-2008 sql-server-2008-r2


    【解决方案1】:

    你的问题是你试图加入两个不同的条件。而是加入您的查找表两次。像这样:

    SELECT Id , MemberID, MembershipType, RegDistricts.Name as RegisteredCity,
        RegStates.Name as RegisteredState, RegCountryMaster.Country as RegisteredCountry,
        PostalDistricts.Name as PostalCity, PostalStates.Name as PostalState, 
        PostalCountryMaster.Country as PostalCountry 
    FROM dbo.JFPMembers 
    LEFT JOIN MemberShipMaster 
        ON MemberShipMaster.Id = dbo.JFPMembers.MembershipType  
    LEFT JOIN Districts RegDistricts
        ON RegDistricts.Id = JFPMembers.RegisteredCity
    LEFT JOIN Districts  PostalDistricts
        ON dbo.JFPMembers.PostalCity = PostalDistricts.Id 
    LEFT JOIN States RegStates
        ON RegStates.Id = dbo.JFPMembers.RegisteredState 
    LEFT JOIN States PostalStates
        ON PostalStates.Id = dbo.JFPMembers.PostalState
    LEFT JOIN CountryMaster RegCountryMaster
        ON RegCountryMaster.Id = dbo.JFPMembers.RegisteredCountry 
    LEFT JOIN CountryMaster PostalCountryMaster
        ON PostalCountryMaster.Id = dbo.JFPMembers.postalCountry
    Where Id= @id
    

    【讨论】:

      【解决方案2】:

      邮政需要通过单独的别名自行连接到各自的国家、州和城市表...与已注册...相同...

      SELECT 
            M.Id, 
            M.MemberID, 
            M.MembershipType, 
            MM.TypeName as MembershipTypeName,
            RegCountryAlias.Country as RegisteredCountry,
            RegStatesAlias.Name as RegisteredState,
            RegCitiesAlias.Name as RegisteredCity,
            PostalCountryAlias.Country as PostalCountry,
            PostalStatesAlias.Name as PostalState,
            PostalCitiesAlias.Name as PostalCity
         FROM   
            JFPMembers M
               JOIN MemberShipMaster MM
                  ON M.MembershipType = MemberShipMaster.Id
      
               JOIN CountryMaster as RegCountryAlias
                  ON M.RegisteredCountry = RegCountryAlias.ID
               JOIN States as RegStatesAlias
                  ON M.RegisteredState = RegStatesAlias.ID
               JOIN Cities as RegCitiesAlias
                  ON M.RegisteredCity = RegCitiesAlias.ID
      
               JOIN CountryMaster as PostalCountryAlias
                  ON M.PostalCountry = PostalCountryAlias.ID
               JOIN States as PostalStatesAlias
                  ON M.PostalState = PostalStatesAlias.ID
               JOIN Cities as PostalCitiesAlias
                  ON M.PostalCity = PostalCitiesAlias.ID
         WHERE
            M.ID = @id
      

      正如 Kenneth 指出的那样,如果任何列在相应的连接表中没有专门找到匹配项,则可能会出现 NULL,它不会返回记录。因此,您可能会将 JOIN 更改为 LEFT JOIN。此外,您提到了“Districts”表,但没有提供,但 DID 提供了您的“Cities”表,这是我用作连接的基础。

      【讨论】:

      • 除非 id 列不为 NULL,否则您应该将 JOIN 保留为 LEFT OUTER JOIN。
      • @KennethFisher,对于空值,我同意你的看法......但是看起来发帖人并不期望空值,并且记录条目将包含所有元素以正确加入 Registered AND Postal 列。
      • 我总是喜欢 LEFT OUTER JOIN,除非列明确地不是 NULL 以防万一。调试结果集中的空值比调试缺失的行要容易得多。当然,这个特殊的问题是从去年年底开始的。我真的希望他们已经找到了答案:)
      • @KennethFisher,在大多数情况下我也是这样做的,但开发人员也需要帮助确保良好的数据。
      【解决方案3】:

      在 CountryMaster.Id = dbo.JFPMembers.RegisteredCountry 和 CountryMaster.Id = dbo.JFPMembers.postalCountry 上左加入 CountryMaster

      您是指and 还是or

      【讨论】:

      • 好吧,and 看起来行不通,除非您希望 RegisteredCountry 等于 postalCountry
      • 顺便说一句,我不确定您是否需要在 Member 表中存储 Country、State 和 City。 City 对 State 有一个 FK,State 对 Country 有一个 FK。
      猜你喜欢
      • 2023-03-20
      • 1970-01-01
      • 2017-09-28
      • 2012-03-05
      • 2011-07-10
      • 2016-05-29
      • 1970-01-01
      • 2015-10-01
      • 2012-03-21
      相关资源
      最近更新 更多