【问题标题】:How to include all results of a subquery into a SELECT statement?如何将子查询的所有结果包含到 SELECT 语句中?
【发布时间】:2018-03-03 15:43:04
【问题描述】:

我想将子查询的结果包含在我的 SELECT 语句中,但我一直不知道如何使用我的 SQL 语句来做到这一点。当子查询返回一个结果时,我的语句似乎可以正常工作,但是当它返回多于一行时,它就会成为一个问题。下面是我的 SQL 语句的结构:

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();
}

我收到错误:

错误!:SQLSTATE[21000]:基数违规:1242 子查询返回 超过 1 行

【问题讨论】:

  • $client_cs_no的内容是什么?
  • 错误信息说明了一切。你想要什么?改为执行 LEFT JOIN。顺便说一句,您的查询似乎错过了一些连接条件。
  • 外部查询中cs, ss, mcs 的连接条件在哪里?你有一个笛卡尔积!
  • @OptimusCrime 这是一个单词字符串

标签: php mysql sql


【解决方案1】:

你可以JOIN它,而不是在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 = ?

请注意,表 FROM cs, ss, mcs 将是 CROSS JOIN,因为您没有提供连接条件。您应该添加一个连接条件,我建议使用以下语法:

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 = ?

【讨论】:

  • @Strawberry - 是的,我知道这是另一种方式,但是三个表的连接条件在哪里cs, ss, mcs 我只能看到WHERE cs.client_ec_no = ?,它只会在此列上过滤,但仍然会交叉加入。
【解决方案2】:

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

  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 =? 

【讨论】:

    【解决方案3】:

    我这样理解你的问题, 您需要 cs 表中的所有内容,ss 表中的 s_name。 s_id 在 mcs 和 ss 中很常见。提供了在 mcs 和 cs 中存在的 client_ec_no。现在所有三个表都已连接。 我重组了您的查询并添加了一个不同的查询,以便没有重复。而且还会有交叉连接,因为您没有在外部查询中指定任何连接条件。

      '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 = ?'
    

    【讨论】:

      【解决方案4】:

      我不确定您的查询是什么意思,但如果子查询中的一个结果很好,那么这将消除错误:

      $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 = ?';
      

      【讨论】:

        【解决方案5】:

        使用别名并加入。修正语法:

         $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 = ?';
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-10-18
          • 2012-08-28
          • 1970-01-01
          • 2013-02-22
          • 1970-01-01
          • 2012-01-15
          相关资源
          最近更新 更多