了解3个或更多表的连接顺序

时间:2014-09-26 06:13:01

标签: sql sql-server sql-server-2014

我有一个使用*=运算符的旧查询。现在,查询的where子句如下所示

Table1.Column1 *= Table2.Column1
AND Table1.Column2 *= Table3.Column1
if (some conditions in C# script)  //this whole clause is generated by C# function based on different conditions
AND Table1.Column3 *= Table4.Column1

我必须重写它才能使用左连接,因为我们不再是恐龙了,而且正在转向SQL Server 2014(来自sql server 2000)。无论如何,我已经重写了像

这样的查询
From Table1
Left Join Table2 On Table1.Column1 = Table2.Column1
Left Join Table3 On Table1.Column2 = Table3.Column1
Left Join Table4 On Table1.Column3 = Table4.Column1

我相信这应该为我提供相同的结果集,但事实并非如此。显然,SQL Server在两种情况下都不遵循相同的连接顺序。所以,我必须弄清楚旧查询遵循的确切顺序,以及如何重新创建相同的顺序。

P.S。我对代码了解不多。但是,我可以在这里发布完整的功能,万一它可以帮助别人更好地了解情况。

编辑:

我正在使用的确切查询构建器功能。

public virtual FANUC.Common.BaseClasses.Row[] GetCustomersForPopup( FANUC.Common.BaseClasses.Row objListCustomerFilter, FANUC.Common.BaseClasses.PagingEventArgs e )    {

        string strConnector = " WHERE ";
        string strANDClause = "";

        string strSQLQuery  = " SELECT "
                            + " TBL_Company_Master.CMPM_Company_ID,"
                            + " TBL_Company_Master.CMPM_Company_Name,"
                            + " " + ( ( FANUCUser )Thread.CurrentPrincipal.Identity ).DBUser + ".fnGetRefCodeValue( CMPM_Company_Type_ID ) AS CMPM_CompanyTypeID,"
                            + " TBL_Company_Master.CMPM_Company_NickName,"
                            + " TBL_Company_Master.CMPM_Service_Center_ID,"
                            + " TBL_Company_Master.CMPM_Company_BranchName,"
                            + " TBL_Company_Master.CMPM_Black_Listed_Flag,"
                            + " TBL_Company_Master.CMPM_Prohibited_Company_Flag,"   
                            + " " + ( ( FANUCUser )Thread.CurrentPrincipal.Identity ).DBUser + ".fnGetRefCodeValue( TBL_Company_Master.CMPM_Status ) AS CMPM_Status,"
                            + " TBL_Company_Master.CMPM_City_Location_ID AS CMPM_City_Location_ID,"
                            + " TBL_City_Location_Master.CLIM_City_Name AS CLIM_City_Name, "
                            + " TBL_Company_Master.CMPM_Country_ID AS CMPM_Country_ID,"
                            + " TBL_Country_Master.CRIM_CountryName, "
                            + " TBL_Company_Master.CMPM_Night_Call_Applicable_flag,"
                            + " TBL_Company_Master.CMPM_Default_currency_for_transaction,"
                            + " TBL_Company_Master.CMPM_Telephone_No, "
                            + " TBL_Customer_Contact_Master.CNTM_ContactPersonName, "
                            + " TBL_Customer_Contact_Master.CNTM_Section_Name, "
                            + " TBL_Company_Master.Use_Count, "
                            + " TBL_Company_Master.CMPM_Self_Company_Indicator, "
                            + " TBL_Company_Master.CMPM_Transport_Time ";


        string strFromClause    = " FROM TBL_Company_Master, "
                                + " TBL_Service_Center_Master, "
                                + " TBL_City_Location_Master, "
                                + " TBL_Country_Master, "
                                + " TBL_Customer_Contact_Master";

        strANDClause    += " AND TBL_Company_Master.CMPM_Service_Center_ID *= TBL_Service_Center_Master.SCRM_Service_Center_ID  "
                        +  " AND TBL_Company_Master.CMPM_City_Location_ID *= TBL_City_Location_Master.CLIM_City_ID "
                        +  " AND TBL_Company_Master.CMPM_Country_ID *= TBL_Country_Master.CRIM_CountryID ";

            if ( objListCustomerFilter[ Constants.IS_CALLING_CUSTOMER ] != null || objListCustomerFilter[ Constants.IS_PAYEE_CUSTOMER ] != null || Convert.ToInt32( objListCustomerFilter[ "CUTM_Customer_Type_ID" ] ) == 120 ) 
                strANDClause += " AND TBL_Company_Master.CMPM_Company_ID *= TBL_Customer_Contact_Master.CNTM_Customer_ID ";
            else
                strANDClause += " AND TBL_Company_Master.CMPM_Company_ID = TBL_Customer_Contact_Master.CNTM_Customer_ID " ;

            strANDClause    += " AND TBL_Customer_Contact_Master.CNTM_Default_Flag = 'Y' "; 
            strANDClause    += " AND CMPM_Active_Flag != 'N'";


        if ( objListCustomerFilter["CUTM_Customer_Type_ID"] != null && Convert.ToString(objListCustomerFilter["CUTM_Customer_Type_ID"]) != "" ) {
            strFromClause   += " ,TBL_Customer_Type_Mapping ";
            strANDClause    += " AND CUTM_Customer_ID = CMPM_Company_ID " + " AND CUTM_Customer_Type_ID = "+Convert.ToString(objListCustomerFilter["CUTM_Customer_Type_ID"]);
        }

        if ( objListCustomerFilter["CMPM_Company_Type_ID"] != null && Convert.ToString(objListCustomerFilter["CMPM_Company_Type_ID"]) != "" && Convert.ToString(objListCustomerFilter["CMPM_Company_Type_ID"]) != Constants.ALL )   {
            strANDClause += " AND CMPM_Company_Type_ID IN ("+Convert.ToString(objListCustomerFilter["CMPM_Company_Type_ID"])+","+Constants.COMPANY_TYPE_BOTH+") ";
        }

        if ( !Convert.ToString( objListCustomerFilter[ Constants.PAYMENT_REQD ] ).Equals(Constants.CONST_NO ) ) {

            strSQLQuery += ", TBL_Company_Payment_Terms.CMPT_Payment_Term_Description "
                        + ", TBL_Company_Payment_Terms.CMPT_Payment_Term_ID ";

            strFromClause += " ,TBL_Company_Payment_Terms ";

            if((objListCustomerFilter[Constants.IS_CALLING_CUSTOMER] != null) ||(objListCustomerFilter[Constants.IS_END_USER] != null) ) 
                strANDClause    += " AND TBL_Company_Master.CMPM_Company_ID *= TBL_Company_Payment_Terms.CMPT_Company_ID "
                                + " AND TBL_Company_Payment_Terms.CMPT_Default = 'Y' ";
            else
                strANDClause    += " AND TBL_Company_Master.CMPM_Company_ID = TBL_Company_Payment_Terms.CMPT_Company_ID "
                                + " AND TBL_Company_Payment_Terms.CMPT_Default = 'Y' ";


            if ( objListCustomerFilter[ "CMPM_Company_Type_ID" ] != null && Convert.ToString( objListCustomerFilter[ "CMPM_Company_Type_ID" ] ) != Constants.COMPANY_TYPE_BOTH && Convert.ToString( objListCustomerFilter[ "CMPM_Company_Type_ID" ] ) != Constants.ALL )
                strANDClause += " AND CMPT_Company_Type_ID = " + Convert.ToString( objListCustomerFilter[ "CMPM_Company_Type_ID" ] );   

        }

        strANDClause += " AND CMPM_Subsidiary_Code = '"+((FANUCUser)Thread.CurrentPrincipal.Identity).SubsidiaryCode+"'";

        Row objFilter = new Row();

        objFilter["CMPM_Company_ID"]                            = objListCustomerFilter["CMPM_Company_ID"];
        objFilter["CMPM_Black_Listed_Flag"]                     = objListCustomerFilter["CMPM_Black_Listed_Flag"];
        objFilter["CMPM_Prohibited_Company_Flag"]               = objListCustomerFilter["CMPM_Prohibited_Company_Flag"];
        objFilter["CMPM_Status"]                                = objListCustomerFilter["CMPM_Status"];
        objFilter["CMPM_Company_Name~like"]                     = objListCustomerFilter["CMPM_Company_Name"];
        objFilter["CMPM_Company_NickName~like"]                 = objListCustomerFilter["CMPM_Company_NickName"];
        objFilter["CMPM_Telephone_No~like"]                     = objListCustomerFilter["CMPM_Telephone_No"];
        objFilter["CMPM_FAX_No"]                                = objListCustomerFilter["CMPM_FAX_No"];
        objFilter["CMPM_Service_Center_ID"]                     = objListCustomerFilter["CMPM_Service_Center_ID"];
        objFilter["CMPM_Billing_Company_ID"]                    = objListCustomerFilter["CMPM_Billing_Company_ID"];
        objFilter["CMPM_Shipping_Company_ID"]                   = objListCustomerFilter["CMPM_Shipping_Company_ID"];
        objFilter["CMPM_City_Location_ID"]                      = objListCustomerFilter["CMPM_City_Location_ID"];
        objFilter["CMPM_State_ID"]                              = objListCustomerFilter["CMPM_State_ID"];
        objFilter["CMPM_Country_ID"]                            = objListCustomerFilter["CMPM_Country_ID"];
        objFilter["CMPM_Grp_Parent_Company_ID"]                 = objListCustomerFilter["CMPM_Grp_Parent_Company_ID"];
        objFilter["CMPM_Night_Call_Applicable_Flag"]            = objListCustomerFilter["CMPM_Night_Call_Applicable_Flag"];
        objFilter["CMPM_Default_currency_for_transaction"]      = objListCustomerFilter["CMPM_Default_currency_for_transaction"];
        objFilter["CMPM_Company_local_registration_No~like"]    = objListCustomerFilter["CMPM_Company_local_registration_No"];
        objFilter["CMPM_Company_central_registration_No~like"]  = objListCustomerFilter["CMPM_Company_central_registration_No"];
        objFilter["CMPM_Insurance_Policy_No~like"]              = objListCustomerFilter["CMPM_Insurance_Policy_No"];
        objFilter["CMPM_Active_Flag"]                           = objListCustomerFilter["CMPM_Active_Flag"];
        objFilter["CMPM_Company_BranchName~like"]               = objListCustomerFilter["CMPM_Company_BranchName"];
        objFilter["CMPM_Company_BranchName_LocalLanguage~like"] = objListCustomerFilter["CMPM_Company_BranchName_LocalLanguage"];
        objFilter["CMPM_Postal_Code"]                           = objListCustomerFilter["CMPM_Postal_Code"];
        objFilter["CMPM_Web_Site~like"]                         = objListCustomerFilter["CMPM_Web_Site"];
        objFilter["CMPM_Distance"]                              = objListCustomerFilter["CMPM_Distance"];

        if ( objListCustomerFilter["CMPM_Self_Company_Indicator"] != null && Convert.ToString(objListCustomerFilter["CMPM_Self_Company_Indicator"]) != Constants.ALL )
            objFilter[ "CMPM_Self_Company_Indicator" ]  = objListCustomerFilter["CMPM_Self_Company_Indicator"];



        CommonBQ    objCommonBQ     = new CommonBQ();
        string      strSearchClause = objCommonBQ.CreateFilter( objFilter );
        string      strFinalString  = "";

        if ( !strSearchClause.Equals( "" ) )    strFinalString  = strSQLQuery + strFromClause + strConnector + strSearchClause + strANDClause;
        else    {

            strSQLQuery += strFromClause + strConnector + strANDClause;

            int     iFirstPos       = strSQLQuery.IndexOf( "AND", 0 );
            string  strFirstPart    = strSQLQuery.Substring( 0, iFirstPos );
            string  strSecondPart   = strSQLQuery.Substring( iFirstPos + 3, strSQLQuery.Length - iFirstPos - 3 );

            strFinalString  = strFirstPart + strSecondPart;
        }

        return  GetRows( strFinalString, CreateParameterArray( objListCustomerFilter ), CommandType.Text, null, e );
    }

3 个答案:

答案 0 :(得分:1)

您应该在此查询中更新一些内容:

  1. 在select子句中使用Table Alias而不是完整的表名。

  2. TBL_Customer_Contact_Master根据条件加入:
    objListCustomerFilter [Constants.IS_CALLING_CUSTOMER]!= null || objListCustomerFilter [Constants.IS_PAYEE_CUSTOMER]!= null || Convert.ToInt32(objListCustomerFilter [" CUTM_Customer_Type_ID"]) == 120)如果这是真的那么Left Join其他Inner join

  3. 因此请将语句更新为:

    string strFromClause = "来自TBL_Company_Master TCM" + "左加入TBL_Service_Center_Master TSC     TCM.CMPM_Service_Center_ID = TSC.SCRM_Service_Center_ID" + "左加入TBL_City_Location_Master TCL     TCM.CMPM_City_Location_ID = TCL.CLIM_City_ID" + "左加入TBL_Country_Master TC on     TCM.CMPM_Country_ID = TC.CRIM_CountryID&#34 ;;

  4. 将条件1更新为:

    if(objListCustomerFilter [Constants.IS_CALLING_CUSTOMER]!= null ||  objListCustomerFilter [Constants.IS_PAYEE_CUSTOMER]!= null || Convert.ToInt32(  objListCustomerFilter [" CUTM_Customer_Type_ID" ])== 120)

    strFromClause + ="在TCM.CMPM_Company_ID上左连接TBL_Customer_Contact_Master TCCM = TCCM.CNTM_Customer_ID&#34 ;; 其他 strFromClause + =" TCM.CMPM_Company_ID上的内连接TBL_Customer_Contact_Master TCCM = TCCM.CNTM_Customer_ID&#34 ;;

  5. 然后将条件2更新为: if(objListCustomerFilter [" CUTM_Customer_Type_ID"]!= null&& Convert.ToString (objListCustomerFilter [" CUTM_Customer_Type_ID"])!="" ){

    strFromClause + ="左连接TBL_Customer_Type_Mapping on CUTM_Customer_ID = CMPM_Company_ID AND CUTM_Customer_Type_ID =" + Convert.ToString(objListCustomerFilter [" CUTM_Customer_Type_ID"];}

  6. 条件3为:

    if((objListCustomerFilter [Constants.IS_CALLING_CUSTOMER]!= null)||(objListCustomerFilter [Constants.IS_END_USER]!= null)) strFromClause + ="左加入TBL_Company_Payment_Terms TCPT 在TCM.CMPM_Company_ID = TCPT.CMPT_Company_ID AND TCPT.CMPT_Default =' Y' &#34 ;; 其他 strFromClause + ="内部加入TBL_Company_Payment_Terms TCPT 在TCM.CMPM_Company_ID = TCPT.CMPT_Company_ID AND TCPT.CMPT_Default =' Y' &#34 ;;

  7. 我可能在这里和那里错过了一些逗号和分号,但它应该让你知道可能缺少的东西。希望这会有所帮助!!!

答案 1 :(得分:0)

订单在左外连接中无关紧要,所以请保证,它不会导致它。我的猜测是if语句可能导致结果的差异。 如果您可以共享表格数据或输出,则可以计算出来。

答案 2 :(得分:0)

不同之处在于如何为外连接表中的列应用额外的where子句过滤器。

有了这个:

select *
from a
    left outer join b on a.id = b.id
where
    b.other_col = 'test'

结果将仅包含找到b中的行的行,other_col中的b列的值为test

与此相比:

select *
from a, b
where
    a.id *= b.id
    and b.other_col = 'test'

这将找到a中的所有行。它还会包含bb.other_col = 'test'

行的列

因此,采用第二个查询并将其转换为具有左连接的查询,以下之一将提供相同的输出:

-- 1.

select *
from a
    left outer join b on a.id = b.id and b.other_col = 'test'

-- 2.

select *
from a
    left outer join 
    (
        select *
        from b
        where other_col = 'test'
    ) as b on a.id = b.id