【问题标题】:Subquery in view returning more than 1 value视图中的子查询返回超过 1 个值
【发布时间】:2014-10-02 04:43:03
【问题描述】:

我正在尝试创建一个视图,该视图具有执行计算的部分,以便决定要显示哪个字段。但是,我遇到了子查询的问题。

每当我尝试执行视图时,我都会收到错误消息:Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

我明白它在说什么,通常我会使用WHERE 子句和子查询中的参数来解决这个问题。但是,由于我需要将其作为一个观点,我该如何缓解这个问题?我已经为多个案例独立运行了子查询,并验证了它们确实为每个订单返回一行。是否可以让子查询仅从它在视图中的当前行中选择单个结果?

这里是视图特定部分的代码 sn-p。你们能提供的任何建议将不胜感激。

SELECT
    CASE
        WHEN ORC.SimultaneousCalculation = 1
            THEN CASE
                    WHEN -- Select the Owner's Simultaneous Report Code when Sales Price >= Loan Amount.
                        (SELECT
                            CASE 
                                WHEN (ISNULL(O.OwnerPolicyLiability, 0) = 0)
                                    THEN O.SalesPrice
                                WHEN (ISNULL(O.OwnerPolicyLiability, 0) > 0)
                                    THEN (O.OwnerPolicyLiability)
                                ELSE 0 END AS 'SalesPrice'
                                FROM
                                    Orders O) >=
                        (SELECT
                            CASE 
                                WHEN (ISNULL(L.LoanPolicyLiability, 0) = 0)
                                    THEN L.Amount
                                WHEN (ISNULL(L.LoanPolicyLiability, 0) > 0)
                                    THEN (L.Amount)
                                ELSE 0 END AS 'LoanAmount'
                                FROM
                                    Orders O
                                    INNER JOIN Loan L
                                        ON O.OrdersID = L.OrdersID
                                        AND L.LoanOrder = 1)
                        THEN CONVERT(VARCHAR(MAX),RES.SalesPolicyCode)
                    WHEN -- Select the Owner's Simultaneous Report Code when Sales Price < Loan Amount.
                        (SELECT
                            CASE 
                                WHEN (ISNULL(O.OwnerPolicyLiability, 0) = 0)
                                    THEN O.SalesPrice
                                WHEN (ISNULL(O.OwnerPolicyLiability, 0) > 0)
                                    THEN (O.OwnerPolicyLiability)
                                ELSE 0 END AS 'SalesPrice'
                                FROM
                                    Orders O) <
                        (SELECT
                            CASE 
                                WHEN (ISNULL(L.LoanPolicyLiability, 0) = 0)
                                    THEN L.Amount
                                WHEN (ISNULL(L.LoanPolicyLiability, 0) > 0)
                                    THEN (L.Amount)
                                ELSE 0 END AS 'LoanAmount'
                                FROM
                                    Orders O
                                    INNER JOIN Loan L
                                        ON O.OrdersID = L.OrdersID
                                        AND L.LoanOrder = 1)
                        THEN CONVERT(VARCHAR(MAX),RES.LoanPolicyCode)
                    ELSE CONVERT(VARCHAR(MAX),0) END
        -- If not Simultaneous, select the primary rate's Report Code.
        ELSE CONVERT(VARCHAR(MAX),R.ReportCode)
        END AS 'PremCode'
    ,O.Col1
    ,O.Col2
    ,O.Col3
FROM
    Orders O
    INNER JOIN OrderRateCalculation ORC
        ON O.OrdersID = ORC.OrdersID
    LEFT JOIN Rate R
        ON ORC.RateID = R.RateID
    LEFT JOIN RateEffectiveDate RED
        ON R.RateID = RED.RateID
    LEFT JOIN RateEngineSimultaneous RES
        ON RED.RateEffectiveDateID = RES.RateEffectiveDateID
WHERE
    (ORC.LoanHolder = 1)

【问题讨论】:

  • 这只是视图的一部分?为什么有这么多嵌套的 case 表达式?这真的让人很难跟上。我怀疑大部分问题是因为您的子查询不相关。它们应该有一个 where 子句来限制与外部查询相关的结果。
  • 问题是您的一些子查询返回多于一行,因此 SQL Server 不知道要与哪一行进行比较。您可以使用 MAX 或 MIN 将子查询过滤到一行。

标签: sql sql-server tsql


【解决方案1】:

如果不了解表的关系,这很难回答,但如果是我,我会尝试找到一种方法将 JOIN 移动到 'Loan' 到主连接列表,并完全删除子选择。像这样的:

SELECT
CASE
    WHEN ORC.SimultaneousCalculation = 1
        THEN CASE
                WHEN -- Select the Owner's Simultaneous Report Code when Sales Price >= Loan Amount.
                        CASE 
                            WHEN (ISNULL(O.OwnerPolicyLiability, 0) = 0)
                                THEN O.SalesPrice
                            WHEN (ISNULL(O.OwnerPolicyLiability, 0) > 0)
                                THEN (O.OwnerPolicyLiability)
                            ELSE 0 END AS 'SalesPrice'
                         >=
                        CASE 
                            WHEN (ISNULL(L.LoanPolicyLiability, 0) = 0)
                                THEN L.Amount
                            WHEN (ISNULL(L.LoanPolicyLiability, 0) > 0)
                                THEN (L.Amount)
                            ELSE 0 END AS 'LoanAmount'
                    THEN CONVERT(VARCHAR(MAX),RES.SalesPolicyCode)
                WHEN -- Select the Owner's Simultaneous Report Code when Sales Price < Loan Amount.
                        CASE 
                            WHEN (ISNULL(O.OwnerPolicyLiability, 0) = 0)
                                THEN O.SalesPrice
                            WHEN (ISNULL(O.OwnerPolicyLiability, 0) > 0)
                                THEN (O.OwnerPolicyLiability)
                            ELSE 0 END AS 'SalesPrice'
                         <
                        CASE 
                            WHEN (ISNULL(L.LoanPolicyLiability, 0) = 0)
                                THEN L.Amount
                            WHEN (ISNULL(L.LoanPolicyLiability, 0) > 0)
                                THEN (L.Amount)
                            ELSE 0 END AS 'LoanAmount'
                    THEN CONVERT(VARCHAR(MAX),RES.LoanPolicyCode)
                ELSE CONVERT(VARCHAR(MAX),0) END
    -- If not Simultaneous, select the primary rate's Report Code.
    ELSE CONVERT(VARCHAR(MAX),R.ReportCode)
    END AS 'PremCode'
,O.Col1
,O.Col2
,O.Col3
FROM
Orders O
INNER JOIN OrderRateCalculation ORC
    ON O.OrdersID = ORC.OrdersID
LEFT JOIN Rate R
    ON ORC.RateID = R.RateID
LEFT JOIN RateEffectiveDate RED
    ON R.RateID = RED.RateID
LEFT JOIN RateEngineSimultaneous RES
    ON RED.RateEffectiveDateID = RES.RateEffectiveDateID
LEFT JOIN Loan L
    ON O.OrdersID = L.OrdersID
    AND L.LoanOrder = 1
WHERE
(ORC.LoanHolder = 1)

祝你好运!

【讨论】:

  • 宾果游戏!我不知道为什么我没有想到这一点。我想我错误地认为我无法将两个 CASE 语句相互比较,但这只是一个简单的失误。谢谢你,先生!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
  • 2016-04-10
  • 1970-01-01
相关资源
最近更新 更多