【问题标题】:How to implement a SQL Server query which has several join conditions如何实现具有多个连接条件的 SQL Server 查询
【发布时间】:2012-12-11 08:55:00
【问题描述】:

我正在尝试实现这个查询,但我不知道为什么我没有得到结果。

这里是描述:

假设我有一个餐桌电话: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

另一张桌子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

然后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        ----            -----

还有表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

我想在以下情况下更新TableAct

  1. TableAct. Acct# = TableCustomerOrd.ID#AND
  2. TableCustomerOrd. CustID = TableCustomerDtls.CustID 同时,TableCustomerOrd.Ord_Descriptions 字段应与 TableCustomerDtls. Descriptions 字段匹配 “_” 之前的任何内容。因此‘1AAA’, ‘2HJ5’AND
  3. DelivaryFlight.FlightOrder# = TableCustomerOrd.COrder#ANDDelivaryFlight.FlightCustID = TableCustomerOrd. CustID。还有TableCustomerDtls. Delivery = ‘SUCCESSFUL’ AND:

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

那我要比较一下:elivaryFlight.FlightDt > DelivaryFlight.FlightDt

基本上我需要将表DelivaryFlightFlightOrder#, FlightCustIDTableCustomerOrd 匹配。

此外TableCustomerDtlsDeliveryck 用于delivary 状态,例如‘DECLINED’

‘SUCCESSFUL’ 条件并比较‘SUCCESSFUL’ FlightDt‘DECLINED’ FlightDt

这是我的查询,但请帮助我理解,我相信这可以以更好的方式完成。

查询不工作:

     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


你的帮助将是巨大的,因为我的项目将于本周末结束。 谢谢

【问题讨论】:

  • 我真的不明白这个:WHERE DelivaryFlight. FlightDt > DelivaryFlight. FlightDt
  • 不要在字段名中使用#,最好避免在字段名中使用符号。在 # 的情况下,如果您碰巧将它用作第一个字符,SQl 服务器会认为您有一个临时表而不是字段名。并请正确拼写交货。这种事情会让维护程序员发疯,所以最好从一开始就养成更好的习惯。
  • Beth 谢谢,是的,那些是错字

标签: sql sql-server-2008 tsql


【解决方案1】:

如果我有这样一个复杂的查询,我首先创建一个“简单”选择,它只生成要更新的行。

它还应该返回更新值和更新表的 pk

然后(相对)直接(内部)将它与要更新的表连接起来,并通过包含更新记住仅更新匹配的行

WHERE tblTobeUpdated.pk = SimpleSelect.pk

希望对你有帮助

【讨论】:

  • 嗨,谢谢大家,但这是我的问题,那些是错字
  • 我认为您需要分解查询并一一测试您的联接和条件。你看起来好像在使用子查询,我见过的最清晰的例子是allenbrowne.com/subquery-01.html我们没有你的数据。这里的所有其他指导都很好,但它是学习解决问题的一部分,您可以开发技术来解决问题。我倾向于用 go 编写我的查询参数化查询,然后将 exec myquery 参数作为“在线”测试,然后在 SSMS 中按 f5 键运行和测试全部合二为一。
  • Ian,谢谢 请查看上面的所有表格,此查询需要匹配 DF.FlightOrder# = CustOd.COrder# AND DF.FlightCustID = CustOd.CustID AND TableCustomerDtls.Delivery = 'SUCCESSFUL'不仅如此,还需要匹配 DF2.FlightOrder# = DF.COrder# AND DF.FlightCustID = DF.CustID AND TableCustomerDtls.Delivery = 'DECLINED' 所以我在 DeliveryFlight 表上分离 JOIN 条件。还有其他方法可以实现吗?这是一个不错的选择吗?此外,请协助我完成此查询。
  • 大家好,请帮我解决这个问题...非常感谢
  • 你可以嵌套你的查询:我会把它作为一个响应,因为它很难在评论中写代码
【解决方案2】:

我没有时间深入研究这个问题,但我怀疑你至少想要修复:

  WHERE DelivaryFlight. FlightDt >  DelivaryFlight. FlightDt

这是永远无法满足的条件。

你可能想要:

  WHERE DF. FlightDt > DF2. FlightDt

对于这些复杂的查询也很有用,因为更新能够看到将要更新的记录,所以我通常会这样做:

Update
     Set …
--Select *
    FROM TableAct AC

然后,我不运行更新,而是运行突出显示并运行以 select 开头的部分以查看结果,并且在我确定我选择了我想要选择的记录并且值之前不测试更新我将替换是正确的。

【讨论】:

  • 谢谢,但请您详细解释一下。
【解决方案3】:

尝试分解你的查询,这是我今天写的一个查询,分别测试每个部分

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

【讨论】:

    猜你喜欢
    • 2014-03-11
    • 1970-01-01
    • 2013-08-17
    • 1970-01-01
    • 2017-02-24
    • 2018-09-10
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    相关资源
    最近更新 更多