0

我得到的完整错误是:

消息 512,级别 16,状态 1,第 1 行
子查询返回超过 1 个值。当子查询跟随 =、!=、<、<=、>、>= 或子查询用作表达式时,这是不允许的。

我通过了这个过去可以工作的 SQL 代码,我需要修复它,但我得到了上面的错误,但即使我注释掉某些部分,错误仍然保持不变

这是sql代码:

SELECT  
    OrderId = OrdNameAdd.ORDERS_ID,
    LTRIM(ISNULL(OrdNameAdd.OBY_FirstName, '') + ' ' + ISNULL(OrdNameAdd.OBY_LASTNAME, '')) AS OrderedByName,
    ObyVar1 = (SELECT varfld_value FROM MAILERVBL WHERE OBYMAILER = MAILERVBL.MAILER_SEQID AND VARDEF_SEQUENCE = 1),
    ObyVar2 = (SELECT varfld_value FROM MAILERVBL WHERE OBYMAILER = MAILERVBL.MAILER_SEQID AND VARDEF_SEQUENCE = 2),
    ObyVar3 = (SELECT varfld_value FROM MAILERVBL WHERE OBYMAILER = MAILERVBL.MAILER_SEQID AND VARDEF_SEQUENCE = 3),
    ExtendedDefaultValue = (SELECT sum(isnull(p.prduct_value,0) *  (isnull(pickdt.prdord_toshipqty,1))) 
                            FROM PICKDT 
                            LEFT OUTER JOIN 
                               locVerBals ON PICKDT.PRVERS_SEQID = locVerBals.PRVERS_Seqid 
                            LEFT OUTER JOIN 
                               LOCPRDSUM p ON locVerBals.PRDUCT_Seqid = p.PRDUCT_SEQID 
                                           AND p.system_id = PICPAK.SYSTEM_ID 
                            WHERE
                               PICKDT.PICPAK_Seqid = PICPAK.PICPAK_Seqid 
                               AND p.PRDUCT_INACTIVEDATE IS NULL), 
    FulfCharges = (rpt_BD.Linesshipped * ACCDEF_ChargePerLine) + ACCDEF_ChargePerShipment, 
    PubFreight = (rpt_BD.PubFreight), 
    TotalValue = 
        (SELECT 
            sum(isnull(p.prduct_value, 0) * (isnull(pickdt.prdord_toshipqty, 1))) 
         from PICKDT 
         LEFT OUTER JOIN locVerBals ON PICKDT.PRVERS_SEQID = locVerBals.PRVERS_Seqid 
         LEFT OUTER JOIN LOCPRDSUM p ON locVerBals.PRDUCT_Seqid = p.PRDUCT_SEQID 
                                     AND p.system_id = PICPAK.SYSTEM_ID 
         WHERE 
             PICKDT.PICPAK_Seqid = PICPAK.PICPAK_Seqid AND p.PRDUCT_INACTIVEDATE IS NULL) 
         + isnull((rpt_BD.Linesshipped * ACCDEF_ChargePerLine), 0) 
         + isnull(ACCDEF_ChargePerShipment,0) + isnull((rpt_BD.PubFreight), 0)
FROM 
    PICPAK 
LEFT OUTER JOIN 
    ORDSTO ON PICPAK.ORDSTO_Seqid = ORDSTO.ORDSTO_Seqid 
LEFT OUTER JOIN 
    OrdNameAdd ON ORDSTO.ORDERS_Seqid = OrdNameAdd.ORDERS_SEQID 
LEFT OUTER JOIN 
    Rpt_BillingDetail rpt_BD ON PICPAK.PICPAK_Seqid = rpt_BD.PICPAK_Seqid 

---------------hERE
WHERE 
    (convert(datetime, DateShipped, 1) >= '4/17/2012' 
     AND convert(datetime, DateShipped, 1) <= '12/17/2012')
---------------HERE

    AND (PICPAK.PICPAK_Status = 'Complete' OR PICPAK.PICPAK_Status = 'Shipped' 
         OR picpak_Status = 'Voided') 
    /*AND (p.PRDUCT_INACTIVEDATE IS NULL)*/
    AND ISNULL(PICPAK.SUPPLR_SEQID,0) = 0
GROUP BY
    OrdNameAdd.ORDERS_ID,
    OrdNameAdd.OBY_FirstName,
    OrdNameAdd.OBY_LASTNAME,
    OrdNameAdd.obymailer,
    PICPAK.PICPAK_Seqid,
    PICPAK.System_Id,
    rpt_BD.PubFreight,
    ACCDEF_ChargePerLine,
    ACCDEF_ChargePerShipment,
    rpt_BD.Linesshipped,
    rpt_BD.Numpackages,
    ordsto.orders_seqid
ORDER BY
    ordsto.orders_seqid ASC
4

5 回答 5

2

我建议您分别执行每个子查询,以找出哪个返回多条记录

于 2012-12-17T15:54:55.403 回答
2

在您的查询中,ObyVar1、ObyVar2、ObyVar3、ExtendedDefaultValue 和 TotalValue 有五个子查询。

两个值子查询使用不带 no 的聚合group by,因此它们应该返回一个值。

您的问题出在三个 ObyVar 中。

有两种简单的方法可以摆脱这种情况:

  1. 聚合值。就这样吧max(varfld_value)
  2. 选择一个值。在 SQL Server 中,这将是 a top 1(在其他数据库中,它可能是rownum = 1or limit 1)。

然而,总的来说,我发现select语句中的select语句是不可取的。from我会在子句中用子查询替换这三个变量:

(select mailer_seqid,
        max(case when vardef_sequence = 1 then varfld_value end) as vv_1, 
        max(case when vardef_sequence = 2 then varfld_value end) as vv_2,
        max(case when vardef_sequence = 3 then varfld_value end) as vv_3
 from mailervbl
 group by mailer_seqid
)

在大多数情况下,这应该与三个子查询一样或更有效。

于 2012-12-17T16:51:06.497 回答
1

如果您有子查询SELECT columns Ex: (1)或有子查询,WHERE col = cluses Ex:(2)您应该确保只返回一个值。

--Ex:(1) make sure only one row returned by the sub query, 
--this case can be voided using TOP 1 from the sub query
SELECT col1, (SELECT colX from Table2 ) 
FROM Table1

--Ex:(2) this case can be avoided using IN instead =
SELECT col1, col2
FROM Table1
WHERE col3 = (SELECT colX from Table2 ) 
于 2012-12-17T15:58:20.497 回答
0

如果不访问您的数据库,我们似乎无法识别它们,不建议编写任何这样的 where 语句,不仅要谈论性能,还要谈论您现在面临的问题。

要解决此问题,您需要通过完整的逻辑并在没有子查询的情况下重写它,或者查看是否可以通过子查询中的 DISTINCT/TOP 1 过滤掉一些数据而不会破坏逻辑本身。我建议你重写它,有时听起来很复杂,但会让事情变得更简单。

于 2012-12-17T15:57:55.727 回答
0

您无法从正在执行单个 SUM 语句的子查询中获取重复项,因此问题出在 MAILERVBL 表上。

如果您一直在寻找重复项,请运行以下类型的代码来识别您的重复项:

select MAILER_SEQID, VARDEF_SEQUENCE, count(*) as numentries
from MAILERVBL 
group by MAILER_SEQID, VARDEF_SEQUENCE
having count(*) > 1
order by numentries desc -- not really needed but useful to see where most of your duplicates are

在您的selectgroup by子句中放置您希望唯一的列。

于 2012-12-18T00:56:13.633 回答