简体   繁体   中英

How to include all results of a subquery into a SELECT statement?

I want to include the results of a sub-query into my SELECT statement BUT I am stuck on how to do that with my SQL statement. When the sub-query returns one result my statement seem to work fine but when more it returns more than one row it becomes a problem. Below is how my SQL statement is structured:

function get_client ($client_ec_no){
    include 'connection.php';

    $sql = 'SELECT cs.*, 
            (SELECT ss.s_name 
                    FROM ss, mcs 
                    WHERE mcs.mcs_s_id = ss.s_id 
                    AND mcs.mcs_client_ec_no = ?)

    FROM cs, ss, mcs
    WHERE cs.client_ec_no = ?';

    try {
        $results = $db->prepare($sql);
        $results->bindValue(1, $client_ec_no, PDO::PARAM_STR);
        $results->bindValue(2, $client_ec_no, PDO::PARAM_STR);
        $results->execute();
    } catch (Exception $e) {
        echo "Error!: " . $e->getMessage() . "<br />";
        return false;
    }
    return $results->fetch();
}

I am getting the error:

Error!: SQLSTATE[21000]: Cardinality violation: 1242 Subquery returns more than 1 row

You can JOIN it, instead of using it in the SELECT :

SELECT cs.*, t.*
  FROM cs, ss, mcs
INNER JOIN
(
    SELECT ss.s_name, ss.s_id
    FROM ss, mcs 
    WHERE mcs.mcs_s_id = ss.s_id 
      AND mcs.mcs_client_ec_no = ?
) AS t ON ss.s_id = t.s_id AND mcs.mcs_s_id = t.mcs_s_id
  WHERE cs.client_ec_no = ?

Note that, the tables FROM cs, ss, mcs will be CROSS JOIN as you didn't supply a join condition. You should add a join condition, and I recommend using the following syntax:

SELECT cs.*, t.*
FROM cs
INNER JOIN ss  ON ...
INNER JOIN mcs ON ...
INNER JOIN
(
    SELECT ss.s_name, ss.s_id
    FROM ss, mcs 
    WHERE mcs.mcs_s_id = ss.s_id 
      AND mcs.mcs_client_ec_no = ?
) AS t ON ss.s_id = t.s_id AND mcs.mcs_s_id = t.mcs_s_id
  WHERE cs.client_ec_no = ?

您可以使用JOIN解决此错误。以下查询可用于u。

  SELECT cs.*, ss.s_name  FROM ss JOIN mcs ON ss.s_id =  mcs.mcs_s_id  JOIN cs ON cs.client_ec_no = mcs.mcs_client_ec_no WHERE  cs.client_ec_no =? 

I understood your query like this, You need all contents from cs table, s_name from ss table. And s_id is common in mcs and ss . client_ec_no provided which is present in mcs and cs. Now all three tables are joined. I restructured your query and added a distinct to that so that there is no duplicates. And also there will be cross join because you did not specify any join conditions in the outer query.

  'SELECT distinct cs.*, ss.s_name 
       FROM cs, ss, mcs
      WHERE mcs.mcs_s_id = ss.s_id 
        AND mcs.mcs_client_ec_no = ?
        AND cs.client_ec_no = ?'

I am unsure what your query is meant to do, but if exactly one result in the sub-query is fine, then this will get rid of the error:

$sql = 'SELECT cs.*, 
        (SELECT TOP 1 ss.s_name 
         FROM ss LEFT JOIN mcs ON 
             ss.s_id = mcs.mcs_s_id 
         WHERE
             mcs.mcs_client_ec_no = ?
        )
        FROM cs
        WHERE cs.client_ec_no = ?';

Use alias and join. Coreect syntax:

 $sql = 'SELECT cs.*, 
        (SELECT ss.s_name 
                FROM ss INNER JOIN mcs ON mcs.mcs_s_id = ss.s_id 
                WHERE 
                mcs.mcs_client_ec_no = ? LIMIT 1) AS some_value

FROM cs
WHERE cs.client_ec_no = ?';

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