简体   繁体   中英

SQL query returns multiple rows

I wrote a SQL query to return a values from column if product type of one contract more than 1.

When I use this query to my main query I get this error:

Single row subquery returns more than one row

When I use rownum = 1 , then no rows are returned.

I need to return the type of the contract

(SELECT
     MAX(TYPE) AS TYPE,
     CONT_NO
 FROM 
     (SELECT    
          MO.CONT_NO, 
          MO.TYPE, 
          COUNT (*) C1
      FROM 
          TABLE1.MORG MO 
      GROUP BY    
          MO.CONT_NO, MO.TYPE) DRT1  
 WHERE  
     DRT1.CONT_NO = CONT_NO 
 GROUP BY 
     CONT_NO
 HAVING 
     COUNT (*) = 1 AND SUM (C1) > 1
) 

There may be several methods to solve your problem, but you do not reveal much detail.

IF you are going to include that subquery in the select clause it most probably needs to be "correlated" to some value of the current result set. eg

SELECT 
...

      (SELECT
            MAX(TYPE) AS type
      FROM (
            SELECT
                  mo.TYPE
                , COUNT(*) c1
            FROM TABLE1.MORG mo
            WHERE mo.CONT_NO = XYZ.CONT_NO --<<<< a "correlation" to the outer query
            GROUP BY
                  mo.TYPE
            ) drt1
      WHERE drt1.CONT_NO = CONT_NO --<<<< is this a "correlation" to the outer query?
      HAVING SUM(C1) > 1)

FROM XYZ 
....

This is because you are NOT ALLOWED to return multiple rows in a "cell" of the selected rows, so you need to restrict the result to a SINGLE VALUE.

In SQL Server a very useful technique for substituting "correlated subqueries" is to use a OUTER APPLY (or CROSS APPLY) instead, but it appears that this subquery could (should?) be used as a joined derived table.

SELECT
       ...
     , x.type
FROM XYZ t
LEFT JOIN (
      SELECT
            MAX(TYPE) AS type
          , CONT_NO
      FROM (
            SELECT
                  mo.CONT_NO
                , mo.TYPE
                , COUNT(*) c1
            FROM TABLE1.MORG mo
            GROUP BY
                  mo.CONT_NO
                , mo.TYPE
      ) drt1
      WHERE drt1.CONT_NO = CONT_NO
      GROUP BY
            CONT_NO
      HAVING COUNT(*) = 1
      AND SUM(C1) > 1
) x ON t.cont_no = x.cont_no

If this is SQL Server, you might want:

(SELECT TOP 1 MAX(TYPE) AS TYPE,
 FROM (SELECT MO.CONT_NO, MO.TYPE, COUNT(*) C1
       FROM TABLE1.MORG MO 
       GROUP BY MO.CONT_NO, MO.TYPE
      ) DRT1  
 WHERE DRT1.CONT_NO = <external reference>.CONT_NO 
 GROUP BY CONT_NO
 HAVING COUNT (*) = 1 ANDSUM (C1) > 1
) 

Perhaps the biggest issue is WHERE DRT1.CONT_NO = CONT_NO . The CONT_NO refers to DRTS.CONT_NO . It should probably be a correlation to the outer query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM