【问题标题】:Subquery related issue in SQL ServerSQL Server 中的子查询相关问题
【发布时间】:2020-10-29 14:14:10
【问题描述】:

the problem is shown in this screenshot

showing the view

SELECT DISTINCT
    w.sourcekeyid1,
    i.instrumentdesc,
    i.serialnum,
    i.instrumentmodelid,
    i.instrumenttype,
    i.workareadepartmentid,
    i.testingdepartmentid,
    spi.scheduleplanid,
    spi.scheduleplanitemdesc,
    spi.schedulerule,
    v.testmethod,
    v1.specid,
    v2.certificationinterval,
    v3.grcperiod,
    (SELECT keyid1 + '|' + keyid2 
     FROM workitemitem 
     WHERE workitemid + '|' + workitemversionid = v.testmethod 
       AND sdcid = 'ParamList') parameterlist,
    p.displayunits,
    (SELECT s.limittypesequence 
     FROM specparamlimits s 
     WHERE s.paramlistid = ((SELECT keyid1 FROM workitemitem 
                             WHERE workitemid + '|' + workitemversionid = v.testmethod 
                               AND sdcid = 'ParamList'))) limitlevel
FROM
    workorder w 
LEFT JOIN  
    instrument i ON w.sourcekeyid1 = i.instrumentid 
LEFT JOIN
    sysuser u ON w.completedby = u.sysuserid
LEFT JOIN
    scheduleplanitem spi ON spi.linksdcid = 'Instrument'
                         AND spi.linkkeyid1 = i.instrumentid
LEFT OUTER JOIN 
    vw_testmethod v ON v.scheduleplanitemid = spi.scheduleplanitemid
LEFT OUTER JOIN
    vw_specid v1 ON v1.scheduleplanitemid = spi.scheduleplanitemid
LEFT OUTER JOIN
    vw_certificationinterval v2 ON v2.scheduleplanitemid = spi.scheduleplanitemid
LEFT OUTER JOIN
    vw_grcperiod v3 ON v3.scheduleplanitemid = spi.scheduleplanitemid,
paramlistitem p 
INNER JOIN 
    workitemitem w1 ON p.paramlistid = w1.keyid1
ORDER BY
    w.sourcekeyid1

我在这里使用视图。我想使用视图的这一列在表中查找其他可能,但出现错误

子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

如何修改?

【问题讨论】:

  • 是否可以在这部分查询where s.paramlistid= ((select keyid1 中使用IN 而不是=

标签: sql sql-server view


【解决方案1】:

这里有几个问题,您需要解决所有问题,即使不是所有问题现在都导致错误。

首先,在下面的子查询中:

(
    SELECT keyid1 + '|' + keyid2 
    FROM workitemitem 
    WHERE workitemid + '|' + workitemversionid = v.testmethod 
         AND sdcid = 'ParamList'
) parameterlist

您在此处生成一个列值,而 SQL 引擎只期望返回一个值。如果上面的查询返回一个以上的值,你会得到错误。

这里有几种方法,具体取决于您的业务逻辑:

  • 确保查询只返回一个值(保持查询不变)

  • 只选择第一个值(您需要以唯一的方式对值进行排序,以确保每次生成一致的结果):

     (
         SELECT TOP 1 keyid1 + '|' + keyid2 
         FROM workitemitem 
         WHERE workitemid + '|' + workitemversionid = v.testmethod 
              AND sdcid = 'ParamList'
         ORDER BY keyid1 + '|' + keyid2 
     ) parameterlist  
    
  • 使用聚合来确保只返回一个值 - 再次取决于您的业务逻辑,您可能决定获取 MAXMIN 值:

    (
        SELECT MAX(keyid1 + '|' + keyid2)
        FROM workitemitem 
        WHERE workitemid + '|' + workitemversionid = v.testmethod 
             AND sdcid = 'ParamList'
    ) parameterlist  
    

    如果您使用的是 SQL Server 2017 或更高版本,您可以使用 STRING_AGG 获取 包含值的 CSV 列表:

    (
        SELECT STRING_AGG (keyid1 + '|' + keyid2, ',')
        FROM workitemitem 
        WHERE workitemid + '|' + workitemversionid = v.testmethod 
             AND sdcid = 'ParamList'
    ) parameterlist 
    

    对于早期版本,您可以创建自己的 SQL CLR aggregation 函数。

对于下一个查询:

(
    SELECT s.limittypesequence 
    FROM specparamlimits s 
    WHERE s.paramlistid = 
    (
        (
            SELECT keyid1 
            FROM workitemitem 
            WHERE workitemid + '|' + workitemversionid = v.testmethod 
                AND sdcid = 'ParamList'
        )
    )
) limitlevel

同样的东西适用于第一个外部部分。在WHERE 部分,您可以对其语句使用相同的选项,并使用IN 子句:

WHERE s.paramlistid IN 
(
        (
            SELECT keyid1 
            FROM workitemitem 
            WHERE workitemid + '|' + workitemversionid = v.testmethod 
                AND sdcid = 'ParamList'
        )
)

再次使用IN 子句可能会导致外部查询返回更多值,因此您也需要它们。

【讨论】:

    猜你喜欢
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多