简体   繁体   English

如何实现具有多个联接条件的SQL Server查询

[英]How to implement a SQL Server query which has several join conditions

I am trying to implement this query but I can't figure out why I am not getting the result. 我正在尝试实现此查询,但是我不知道为什么我没有得到结果。

Here are the descriptions: 以下是说明:

Lets say I have a table call: TableAct 可以说我有一个表调用: TableAct

Acct#   Date                    WithdrawAmt         DepositAmt
!24455  2012-11-19-00.00.00 1245.77                 200.50
125577  2011-02-12-00.00.00 100.98                  578.00

Another table TableCustomerOrd : 另一个表TableCustomerOrd

ID# COrder# CustID  Ord_Description  VendorType
124455  7712AS  123 1AAA             Permanent
125577  9914DL  346 1BBB             Partial 
...     UK1234  111 2HJ5             Permanent'
,,,     FR0912  567 5LGY             Partial

Then TableCustomerDtls : 然后TableCustomerDtls

CustID  Descriptions    Delivery    Address        ZipCode
123     1AAA_BLUESHARE  SUCCESSFUL  222 Main St 97002
346     1BBB_CHASE          DECLINE         40 West Side    97122
111     2HJ5_CITIBANK   SUCCESSFUL  …….         …….
567     5LGY_VANGURD    DECLINED        ----            -----

And table DelivaryFlight : 和表DelivaryFlight

   FlightOrder#   FlightCustID      FlightDt
   7712AS           123    2011-9-29-00.00.00
   9914DL           346    2010-11-2-00.00.00
   UK1234           111    2012-4-1-00.00.00
   FR0912           567    2012-9-11-00.00.00

I want to update TableAct on the following conditions: 我想在以下情况下更新TableAct

  1. TableAct. Acct# = TableCustomerOrd.ID# TableAct. Acct# = TableCustomerOrd.ID# , AND : TableAct. Acct# = TableCustomerOrd.ID# AND
  2. TableCustomerOrd. CustID = TableCustomerDtls.CustID TableCustomerOrd. CustID = TableCustomerDtls.CustID and at the same time, TableCustomerOrd.Ord_Descriptions field should match with TableCustomerDtls. Descriptions TableCustomerOrd. CustID = TableCustomerDtls.CustID ,同时, TableCustomerOrd.Ord_Descriptions字段应与TableCustomerDtls. Descriptions匹配TableCustomerDtls. Descriptions TableCustomerDtls. Descriptions field anything before “_” . TableCustomerDtls. Descriptions字段中的“_”之前的任何内容。 Therefore '1AAA', '2HJ5' etc. AND : 因此, '1AAA', '2HJ5'AND
  3. DelivaryFlight.FlightOrder# = TableCustomerOrd.COrder# , AND : DelivaryFlight.FlightCustID = TableCustomerOrd. CustID DelivaryFlight.FlightOrder# = TableCustomerOrd.COrder#ANDDelivaryFlight.FlightCustID = TableCustomerOrd. CustID DelivaryFlight.FlightCustID = TableCustomerOrd. CustID . DelivaryFlight.FlightCustID = TableCustomerOrd. CustID Also TableCustomerDtls. Delivery = 'SUCCESSFUL' 还有TableCustomerDtls. Delivery = 'SUCCESSFUL' TableCustomerDtls. Delivery = 'SUCCESSFUL' AND: TableCustomerDtls. Delivery = 'SUCCESSFUL'并且:

      DelivaryFlight.FlightOrder# = TableCustomerOrd. COrder# AND DelivaryFlight.FlightCustID = TableCustomerOrd. CustID Also TableCustomerDtls. Delivery = 'DECLINED 

Then I want to compare: elivaryFlight.FlightDt > DelivaryFlight.FlightDt . 然后,我想比较一下: elivaryFlight.FlightDt > DelivaryFlight.FlightDt

Basically I need to match table DelivaryFlight columns FlightOrder#, FlightCustID with TableCustomerOrd . 基本上,我需要将表DelivaryFlightFlightOrder#, FlightCustIDTableCustomerOrd

Moreover TableCustomerDtls column Delivery to ck for delivary status such as 'DECLINED' . 此外, TableCustomerDtls列的Delivery状态为ck ,例如'DECLINED' delivary 'DECLINED'

And 'SUCCESSFUL' condition and compare 'SUCCESSFUL' FlightDt with 'DECLINED' FlightDt . 然后,将'SUCCESSFUL'条件与'SUCCESSFUL' FlightDt'DECLINED' FlightDt

Here's my query but please help me to understand, I am sure this could be done in a better way. 这是我的查询,但请帮助我理解,我相信可以用更好的方法来完成。

The query is not working: 查询不起作用:

     Update
     Set …
    FROM TableAct AC
    Join TableCustomerOrd CustOd
    ON AC.Acct# = CustOd.ID#
    Join TableCustomerDtls CDtls
    ON CDtls. CustID = CustOd. CustID
   AND (CustOd.Ord_Descriptions =
       Left(CDtls.Descriptions, LEN(rtrim(CDtls.Descriptions))))
   JOIN DelivaryFlight DF
   ON DF.FlightOrder# = CustOd.COrder#
   AND DF.FlightCustID = CustOd.CustID
   AND CDtls.Delivery = ‘SUCCESSFUL’
   JOIN DelivaryFlight DF2
   ON DF2.FlightOrder# = DF.COrder#
   AND DF2.FlightCustID = DF.CustID
   AND CDtls.Delivery = ‘DECLINED’
   WHERE DelivaryFlight. FlightDt >  DelivaryFlight. FlightDt
   AND DepositAmt > 100


Your Help will be monumental 'cause my project due end of this week. 您的帮助非常重要,因为我的项目将于本周结束。 Thank you 谢谢

If I have a complex query like this, I start by creating a "simple" select which produces only the rows to be updated. 如果我有一个像这样的复杂查询,我将从创建一个“简单”选择开始,该选择仅产生要更新的行。

It should also return both the update values and the pk for the updated table 它还应该返回更新值和更新表的pk

It is then (relatively) straight forward to (inner) join this with the table to be updated and do the update remebering to only update matching rows by including 然后(相对)直接(内部)将此表与要更新的表进行连接,并进行更新修正以仅通过包含以下内容来更新匹配的行

WHERE tblTobeUpdated.pk = SimpleSelect.pk

Hope this helps 希望这可以帮助

I don't have the time to look at this in depth but I suspect you at least want to fix: 我没有时间深入研究这个问题,但我怀疑您至少想解决此问题:

  WHERE DelivaryFlight. FlightDt >  DelivaryFlight. FlightDt

This is a condition that can never be met. 这是永远无法满足的条件。

You probably want: 您可能想要:

  WHERE DF. FlightDt > DF2. FlightDt

it is also useful with these complex queires for an update to be able to see the records that would be updated, so I usually do something like this: 对于这些复杂的查询,通过更新来查看将要更新的记录也很有用,因此我通常这样做:

Update
     Set …
--Select *
    FROM TableAct AC

Then instead of running the update, I run just highlight and run the part that starts with select to see the results and don't test the update until I am sure I am selecting the records I want to select and that the values I will be replacing are correct. 然后,不运行更新,而是运行并突出显示并运行以select开头的部分以查看结果,直到确定我要选择的记录以及将要使用的值之前,才对更新进行测试。更换是正确的。

Try breaking your query down, heres a query I wrote today, test each part separately 尝试分解查询,以下是我今天写的查询,分别测试每个部分

SELECT
    Employee
    , Reference
    , Payroll
    , [Hours] / 60 
    [Hours]
    , [Days]
FROM
    (
    SELECT
        Employee
        , Reference
        , Payroll
        , SUM( Duration ) AS [Hours]
        , AvailableID
    FROM
        (
        SELECT
            RequirerID
            , Duration
            , RTRIM( COALESCE(MA.MemberLastName, '') 
                + ' ' + COALESCE(MA.MemberFirstName, '')  
                + ' ' + COALESCE(MA.MemberInitial, '')) Employee
            , COALESCE(MA.Detailref1, '') Reference
            , COALESCE(MA.PayrollRef, '') Payroll
            , Available.AvailableId 
        FROM
            (
            SELECT DISTINCT
                RequirerID
                , ShiftDate
                , CAST(ShiftStart - ShiftEnd - ShiftBreak AS DECIMAL(19,2)) ShiftDuration
                , Id RequirementRecordID
            FROM
                Requirements
            WHERE
                Requirements.ShiftDate BETWEEN @ParamStartDate
                AND @ParamEndDate
                AND RequirerID IN (SELECT ID FROM MemberDetails WHERE CompanyID = @ParamCompanyID)
            )
            R
            INNER JOIN
            ShiftConfirmed
            INNER JOIN
            Available
            INNER JOIN
            MemberDetails MA
            ON Available.AvailableID = MA.ID
            ON ShiftConfirmed.AvailableRecordID = Available.ID
            ON R.RequirementRecordID = ShiftConfirmed.RequirementRecordID
        WHERE
            R.ShiftDate BETWEEN @ParamStartDate
            AND @ParamEndDate
            AND COALESCE(ShiftChecked, 0) BETWEEN 0 AND 1
        )
        ShiftDay
    Group By
        Employee
        , Reference
        , Payroll
        , AvailableId
    ) Shifts
    INNER JOIN
    (
    SELECT
        COUNT( * ) AS [Days]
        , AvailableID
    FROM
        (
        SELECT DISTINCT
            R.ShiftDate
            , Available.AvailableId 
        FROM
            (
            SELECT DISTINCT
                ShiftDate
                , Id RequirementRecordID
            FROM
                Requirements
            WHERE
                Requirements.ShiftDate BETWEEN @ParamStartDate
                AND @ParamEndDate
                AND RequirerID IN (SELECT ID FROM MemberDetails WHERE CompanyID = @ParamCompanyID)
            )
            R
            INNER JOIN
            ShiftConfirmed
            INNER JOIN
            Available
            INNER JOIN
            MemberDetails MA
            ON Available.AvailableID = MA.ID
            ON ShiftConfirmed.AvailableRecordID = Available.ID
            ON R.RequirementRecordID = ShiftConfirmed.RequirementRecordID
        WHERE
            R.ShiftDate BETWEEN @ParamStartDate
            AND @ParamEndDate
            AND COALESCE(ShiftChecked, 0) BETWEEN 0 AND 1
        )
        ShiftDay
    Group By
        AvailableId
    ) D
    ON Shifts.AvailableID = D.AvailableID

WHERE [Hours] > 0
ORDER BY
    Employee

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM