【问题标题】:Joining multiple tables in SQL - Best practise在 SQL 中连接多个表 - 最佳实践
【发布时间】:2023-03-17 19:27:01
【问题描述】:

我有 3 张桌子。

表 1:ContractMain

ContractNo      SDValue Value   CityId     AreaCode
C0001           840888  18482   CY00004    AR0001
C0002           133500  35000   CY00004    AR0001
C0003           NULL    4200    CY00004    AR0001
C0004           73440   7400    CY00004    AR0001
C0005           73440   7400    CY00005    AR0002

表 2:合同详情

ContractNo  Code    TxPr Amt
C0001       1       25   2102220.50
C0001       2       25   2102220.50
C0001       3       25   2102220.50
C0002       1       25   333750.00
C0002       2       25   333750.00
C0003       1       25   333750.00
C0003       2       25   333750.00

表 3:城市

CityID  CName
CY00004 AMR
CY00005 EEE
CY00006 TRE
CY00008 WSE

Table4:区域

AreaCode AName
AR0001   COK
AR0002   TCR
AR0003   EKM
AR0004   RTT

我的预期结果是

 ContractNo     SDValue  Value  CityId     AreaCode   Amt  CName  AName

我写的脚本

select  A.*,B.Amt,C.CName,D.AName 
from ContractMain A  INNER JOIN ContractDetails B on  A.ContractNo=B.ContractNo 
Inner join City C on C.CityId=A.CityId
Inner join Area D on D.AreaCode=A.AreaCode

在这里,我得到了针对 ContractNo 的重复值,因为在表 B 中,我们为列 Code 获得了不同的值

我需要为 ContractNo 获取不同的值。实现这一目标的最佳方法是什么

【问题讨论】:

    标签: sql sql-server join inner-join


    【解决方案1】:
    select  A.*,SUM(B.Amt) TotalAmt,C.CName,D.AName 
    from ContractMain A  INNER JOIN ContractDetails B on  A.ContractNo=B.ContractNo 
    Inner join City C on C.CityId=A.CityId
    Inner join Area D on D.AreaCode=A.AreaCode
    GORUP BY A.*, C.Name, D.AName
    

    分组将删除重复,并将为您提供所需字段的总和

    【讨论】:

      【解决方案2】:

      这是您的查询。如果没有为新创建的合同输入合同详细信息,则使用左连接到 ContractDetails。

      select   ContractNo
          ,SDValue
          ,[Value]
          ,CityId
          ,AreaCode
          ,B.Amt
          ,(Select top 1 CName from City C where C.CityId=A.CityId) as CName
          ,(Select top 1 AName from Area D where D.AreaCode=A.AreaCode) as AName
      from ContractMain A  
      left join
          (select ContractNo, sum(Amt) as Amt ContractDetails group by ContractNo) B on  A.ContractNo=B.ContractNo 
      

      【讨论】:

      • 感谢您的回答。与@Zeina的回答相比,您能否评论一下哪个更好
      • 如果您添加更多列,则不需要在 group by 上添加其他字段。当然这更快
      【解决方案3】:

      假设 Tabl2.Code 维护版本并且始终 1 是有效版本(您可以根据您的要求更改),在这种情况下您可以尝试以下查询,这将消除来自 TableB 的重复条目,这可能导致错误 @ 987654323@进行聚合时

      select  A.*,B.Amt,C.CName,D.AName 
      from ContractMain A  
      INNER JOIN ContractDetails B on  A.ContractNo=B.ContractNo  and B.Code = 1
      Inner join City C on C.CityId=A.CityId
      Inner join Area D on D.AreaCode=A.AreaCode
      

      如果Tabl2.Code 不符合逻辑,您可以使用ROW_NUMBER() 生成自己的版本号,在这种情况下查询如下:

      注意:您可以更改PARTITION BYORDER BY 子句中的列,以生成满足您要求的有效版本号

      select  A.*, B.Amt, C.CName, D.AName 
      from ContractMain A  
              INNER JOIN 
                      (select *, row_number() over (partition by ContractNo order by Amt) as VersionNum 
                       From ContractDetails
                       ) as B on  A.ContractNo=B.ContractNo  and B.VersionNum = 1
              Inner join City C on C.CityId=A.CityId
              Inner join Area D on D.AreaCode=A.AreaCode
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-19
        • 2015-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多