我得到的完整错误是:
Msg 512,Level 16,State 1,Line 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
答案 0 :(得分:2)
我建议你分别执行每个子查询以找出哪一个返回多个记录
答案 1 :(得分: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 )
答案 2 :(得分:1)
在您的查询中,您有五个子查询用于ObyVar1,ObyVar2,ObyVar3,ExtendedDefaultValue和TotalValue。
两个值子查询使用的聚合没有group by
,所以它们应该返回一个值。
你的问题出在三个ObyVars中。
有两种方法可以解决这个问题:
max(varfld_value)
。top 1
(在其他数据库中,它可能是rownum = 1
或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
)
在大多数情况下,这应该比三个子查询更高效。
答案 3 :(得分:0)
我们似乎没有办法在没有访问你的数据库的情况下识别它们,不建议写任何这样的where语句,不仅仅是谈论性能,还要讨论你现在面临的问题。
要解决此问题,您需要完成整个逻辑并在没有子查询的情况下重写它,或者查看是否可以在子查询中通过DISTINCT / TOP 1过滤掉一些数据,而不会破坏逻辑本身。我建议你改写它,有时听起来很复杂,但事情会变得简单。
答案 4 :(得分: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
根据条款,在选择和组中放置您希望唯一的列。