PDO로 행 수


192

주위에 많은 상충되는 진술이 있습니다. PHP에서 PDO를 사용하여 행을 계산하는 가장 좋은 방법은 무엇입니까? PDO를 사용하기 전에 그냥 사용했습니다 mysql_num_rows.

fetchAll 때로는 큰 데이터 세트를 처리 할 수 ​​있기 때문에 원하지 않는 것이므로 사용하기에 좋지 않습니다.

의견 있으십니까?

답변:


265
$sql = "SELECT count(*) FROM `table` WHERE foo = ?"; 
$result = $con->prepare($sql); 
$result->execute([$bar]); 
$number_of_rows = $result->fetchColumn(); 

가장 우아한 방법은 아니며 추가 쿼리가 필요합니다.

PDO는 MySql에서 작동 PDOStatement::rowCount()하지 않는 것으로 보입니다 . 얼마나 아파요?

PDO 문서에서 :

대부분의 데이터베이스에서 PDOStatement :: rowCount ()는 SELECT 문의 영향을받는 행 수를 리턴하지 않습니다. 대신 PDO :: query ()를 사용하여 원하는 SELECT 문과 동일한 술어를 사용하여 SELECT COUNT (*) 문을 발행 한 다음 PDOStatement :: fetchColumn ()을 사용하여 리턴 될 행 수를 검색하십시오. 그런 다음 응용 프로그램이 올바른 조치를 수행 할 수 있습니다.

편집 : 위의 코드 예제는 준비된 명령문을 사용하는데, 대부분의 경우 행 수를 계산하는 데 불필요합니다.

$nRows = $pdo->query('select count(*) from blah')->fetchColumn(); 
echo $nRows;

이것은 여분의 데이터베이스 쿼리를 수행하는 것을 의미합니다. 그가 이미 선택 쿼리를 수행했으며 이제 얼마나 많은 행이 반환되었는지 알고 싶습니다.
nickf

1
애칭이 맞습니다. PDO를 사용할 때 mysql_num_rows ()가 작동하지 않습니까?
James

사실 PDOStatement :: rowCount ()가 있지만 MySql에서는 작동하지 않습니다.
karim79

11
이 방법을 사용하면 fetchColumn()문자열 "1234"를 반환합니다 ... EDIT has echo count($nRows);- count()is a array function : P. 또한 결과를 fetchColumn()정수로 캐스트하는 것이 좋습니다 . $count = (int) $stmt->fetchColumn()
Cobby

1
@ karim79 준비되지 않은 명령문 접근 방식은 실제 행 수 대신 1 만 리턴합니다. 준비된 진술은 잘 작동합니다. 무엇이 문제가 될 수 있습니까?
SilentAssassin 2019

86

이전에 비슷한 질문대한 답변 에서 썼 듯이 , 유일한 이유 mysql_num_rows()는 내부적으로 모든 행을 가져 와서 정보가 보이지 않는 경우에도 해당 정보를 제공하기 때문입니다.

따라서 PDO에서 옵션은 다음과 같습니다.

  1. MySQL의 FOUND_ROWS()기능을 사용하십시오 .
  2. PDO의 fetchAll()함수를 사용 하여 모든 행을 배열로 가져온 다음 사용 count()하십시오.
  3. SELECT COUNT(*)karim79가 제안한대로에 추가 쿼리를 수행하십시오 .

8
mysql_num_rows ()에 대해 더 많이 교육 해 주셔서 감사합니다. 다시 감사합니다.
James

2
fetch_all은 실제로 fetchAll () :)입니다.
동적

2
결과가 큰 경우 옵션 2는 권장되지 않습니다.
에드 슨 호라시오 주니어

FOUND_ROWS ()는 MySQL에서 제거되므로 이미 익숙한 경우 사용하기 전에 FOUND_ROWS 링크를 확인하십시오.
anatak

29

종종 발생하는 것처럼,이 질문은 지옥과 혼동됩니다. 사람들은 두 가지 다른 작업 을 염두에두고 여기에옵니다 .

  1. 테이블에 몇 개의 행이 있는지 알아야합니다.
  2. 쿼리가 행을 반환했는지 여부를 알아야합니다.

그것은 공통점이 없으며 동일한 기능으로 해결할 수없는 완전히 다른 두 가지 작업입니다. 아이러니하게도 이들어느 것도 실제 PDOStatement::rowCount()기능을 사용 하지 않아야합니다 .

왜 보자

테이블에서 행 개수

PDO를 사용하기 전에 그냥 사용했습니다 mysql_num_rows().

이미 잘못 했음을 의미합니다 . 사용 mysql_num_rows()또는 rowCount()테이블의 행 수를 계산하는 것은입니다 실제 재해 서버 자원을 소모의 측면이다. 데이터베이스는 디스크에서 모든 행을 읽고 데이터베이스 서버의 메모리를 소비 한 다음이 힙을 모두 PHP로 전송하여 PHP 프로세스의 메모리를 소비하므로 서버는 아무 이유없이 서버에 부담을줍니다.
게다가, 행을 세는 행만 선택하는 것은 의미가 없습니다. count(*)쿼리 대신 실행해야합니다. 데이터베이스는 인덱스 중, 레코드를 계산합니다 실제 행을 읽지 않고 다음 만 하나 행이 돌아왔다.

이를 위해 허용 된 답변에 제안 된 코드 는 공정합니다.

리턴 된 행 수를 계산합니다.

두 번째 사용 사례는 무의미한 것이 아니라 비참한 것이 아닙니다. 쿼리가 데이터를 반환했는지 여부를 알아야 할 경우 항상 데이터 자체가 있습니다!

하나의 행만 선택한다면 말하십시오. 페치 된 행을 플래그로 사용할 수 있습니다.

$stmt->execute();
$row = $stmt->fetch();
if (!$row) { // here! as simple as that
    echo 'No data found';
}

많은 행을 가져와야 할 경우을 사용할 수 있습니다 fetchAll().

fetchAll() 때로는 큰 데이터 세트를 처리 할 수 ​​있기 때문에 원하지 않는 것입니다.

물론, 첫 번째 사용 사례의 경우 두 배나 나쁩니다. 그러나 우리가 이미 배운 바로 하지 않는 행을 선택에서만도, 그들을 계산하는 rowCount()fetchAll() .

그러나 실제로 선택한 행을 사용하려는 경우을 사용하는 데 아무런 문제가 없습니다 fetchAll(). 웹 응용 프로그램에서는 절대로 많은 행을 선택해서는 안됩니다. 실제로 웹 페이지에 사용됩니다 만 행을 따라서 당신이 사용에있어, 선택해야합니다 LIMIT, WHERE또는 SQL에서 비슷한 절. 그리고 적당한 양의 데이터에 대해서는 사용하는 것이 좋습니다 fetchAll(). 그리고이 조건 에서이 함수의 결과를 사용하십시오.

$stmt->execute();
$data = $stmt->fetchAll();
if (!$data) { // again, no rowCount() is needed!
    echo 'No data found';
}

물론 두 개의 상위 답변에서 제안한 것처럼 다른 쿼리가 행을 반환했는지 여부를 알려주기 위해 추가 쿼리 를 실행하는 것은 절대적으로 광기 입니다.

큰 결과 집합에서 행 수 계산

드문 경우이지만 실제 대량의 행을 선택해야하는 경우 (예 : 콘솔 응용 프로그램에서) 사용되는 메모리 양을 줄이려면 버퍼되지 않은 query 를 사용해야합니다 . 그러나 이것은 실제로 사용할 수없는 경우 rowCount() 입니다 없는 경우 이므로이 기능을 사용하지 않습니다.

따라서 선택한 행 수에 대한 가까운 추정치를 알아야 할 경우 추가 쿼리를 실행해야 할 경우에 유일하게 유스 케이스입니다.


API가 전체 검색 결과를 인쇄해야하는 경우 유용합니다. 10 또는 15 개의 행만 제공하지만 총 284 개의 결과가 있음을 알려줍니다.
Andres SK

4
@andufo 아닙니다. 기억하십시오 : 개발자는 절대 이런 식으로하지 않아야합니다 . 검색 쿼리는 284 개의 행을 모두 반환하지 않아야합니다. 표시하려면 15를 리턴 하고 284가 발견되었음을 알리기 위해 별도의 쿼리에서 하나의 행 을 표시해야합니다 .
당신의 상식

2
이것은 매우 좋은 점입니다. 처음에는 직관적이지 않지만 유효합니다. 대부분의 사람들은 두 가지 간단한 SQL 쿼리 것을 잊지 방법 빨리 약간 더 큰보다. 계산을 정당화하려면 최적화 할 수없고 결과가 거의없는 매우 느린 쿼리가 있어야합니다. 지적 해 주셔서 감사합니다!
PeerBr

@ 당신의 상식 : 그냥 뒤 : 결과 집합이 매우 큰 경우 fetchAll () 나쁜 생각하지 않습니까? fetch ()를 사용하여 데이터를 연속적으로 얻는 것이 낫지 않습니까?
timmornYE

@timmornYE 그것이 바로 내 대답의 마지막 단락에서 말한 것입니다
당신의 상식

21

이것은 매우 늦었지만 문제가 발생 하여이 작업을 수행합니다.

function countAll($table){
   $dbh = dbConnect();
   $sql = "select * from `$table`";

   $stmt = $dbh->prepare($sql);
    try { $stmt->execute();}
    catch(PDOException $e){echo $e->getMessage();}

return $stmt->rowCount();

정말 간단하고 쉽습니다. :)


19
계산하기 위해 모든 데이터를 선택하는 것은 데이터베이스 상호 작용의 가장 기본적인 규칙에 위배됩니다.
당신의 상식

모든 반환 값에 대한 진행률 표시 줄을 원할 수 있으므로 선행 행 수를 알아야합니다.
Jonny

18

나는 이것을 사용하여 끝났다.

$result = $db->query($query)->fetchAll();

if (count($result) > 0) {
    foreach ($result as $row) {
        echo $row['blah'] . '<br />';
    }
} else {
    echo "<p>Nothing matched your query.</p>";
}

12

이 게시물은 오래되었지만 PDO로 PHP에서 행 수를 얻는 것은 간단합니다.

$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();

3
karim79의 답변에 인용 된 설명서를 참조하십시오. 이것은 때때로 작동하지만 신뢰할 수 없습니다.
옥턴

5

이것은 오래된 게시물이지만 대안을 찾는 데 좌절하고 있습니다. PDO에이 기능이없는 것이 유감입니다. 특히 PHP와 MySQL이 서로 밀접한 관계가 있기 때문입니다.

fetchColumn ()이 바늘을 다음 행으로 이동함에 따라 더 이상 결과 집합을 효과적으로 사용할 수 없으므로 fetchColumn ()을 사용하면 불행한 결함이 있습니다. 예를 들어,

  1. 과일-> 바나나
  2. 과일-> 애플
  3. 과일-> 오렌지

fetchColumn ()을 사용하면 3 개의 과일이 반환된다는 것을 알 수 있지만 이제 결과를 반복하면 두 개의 열만 있습니다. fetchColumn ()의 가격은 찾을 첫 번째 결과 열의 손실 리턴 된 행 수 이로 인해 조잡한 코딩이 발생하고 구현되면 완전히 오류가 발생합니다.

이제 fetchColumn ()을 사용하면 새로운 작업 결과 세트를 얻기 위해 완전히 새로운 호출 및 MySQL 쿼리를 구현해야합니다. (마지막 쿼리 이후로 변경되지 않았기를 바랍니다), 가능성은 낮지 만 발생할 수 있습니다. 또한 모든 행 수에 대한 이중 쿼리의 오버 헤드가 확인됩니다. 이 예제는 작지만 결합 된 쿼리에서 2 백만 행을 구문 분석하는 것은 유쾌한 가격이 아닙니다.

저는 PHP를 좋아하고 개발에 관여하는 모든 사람과 커뮤니티를 매일 PHP를 사용하여 크게 지원하지만 앞으로 릴리스에서이 문제가 해결되기를 바랍니다. 이것은 PHP PDO에 대한 나의 유일한 불만이며, 그렇지 않으면 훌륭한 클래스입니다.


2

내가 이것을 알고 나 자신에 갇혀 있기 때문에 이것에 대답하면 아마도 유용 할 것입니다.

결과를 두 번 가져올 수 없습니다. 페치 결과를 배열에 저장하고로 행 개수를 가져오고로 결과를 count($array)출력해야합니다 foreach. 예를 들면 다음과 같습니다.

$query = "your_query_here";
$STH = $DBH->prepare($query);
$STH->execute();
$rows = $STH->fetchAll();
//all your results is in $rows array
$STH->setFetchMode(PDO::FETCH_ASSOC);           
if (count($rows) > 0) {             
    foreach ($rows as $row) {
        //output your rows
    }                       
}

1

데이터가 아닌 행 수를 얻으려는 경우 즉. 준비된 명령문에서 COUNT (*)를 사용하면 결과를 검색하고 값을 읽으면됩니다.

$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$statement = $con->prepare($sql); 
$statement->execute(); 
$count = $statement->fetch(PDO::FETCH_NUM); // Return array indexed by column number
return reset($count); // Resets array cursor and returns first value (the count)

실제로 간단한 수를 수행하기 위해 모든 행 (데이터)을 검색하는 것은 자원 낭비입니다. 결과 집합이 크면 서버가 질식 할 수 있습니다.



1

쿼리 내에서 변수를 사용하려면 bindValue()또는 을 사용해야 bindParam()합니다. 그리고 변수를 연결 하지 마십시오" . $variable . "

$statement = "SELECT count(account_id) FROM account
                  WHERE email = ? AND is_email_confirmed;";
$preparedStatement = $this->postgreSqlHandler->prepare($statement);
$preparedStatement->bindValue(1, $account->getEmail());
$preparedStatement->execute();
$numberRows= $preparedStatement->fetchColumn();

GL


0

PHP PDO를 사용 하여 테이블의 행 수 를 계산 하거나 얻는 방법mysql 과 관련 이 있습니다.

// count total number of rows
$query = "SELECT COUNT(*) as total_rows FROM sometable";
$stmt = $con->prepare($query);

// execute query
$stmt->execute();

// get total rows
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$total_rows = $row['total_rows'];

크레딧은 Mike @ codeofaninja.com으로갑니다


-1

첫 번째 항목을 반환하는 빠른 하나의 라이너. 이것은 매우 기본적인 쿼리에 좋습니다.

<?php
$count = current($db->query("select count(*) from table")->fetch());
?>

참고


-1

$count = $stmt->rowCount();Oracle 11.2로 시도했지만 작동하지 않았습니다. 아래에 표시된 것처럼 for 루프를 사용하기로 결정했습니다.

   $count =  "";
    $stmt =  $conn->prepare($sql);
    $stmt->execute();
   echo "<table border='1'>\n";
   while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
        $count++;
        echo "<tr>\n";
    foreach ($row as $item) {
    echo "<td class='td2'>".($item !== null ? htmlentities($item, ENT_QUOTES):"&nbsp;")."</td>\n";
        } //foreach ends
        }// while ends
        echo "</table>\n";
       //echo " no of rows : ". oci_num_rows($stmt);
       //equivalent in pdo::prepare statement
       echo "no.of rows :".$count;

-1

특정 행을 원하고 행이 있는지 알고 싶은 직선 쿼리의 경우 다음과 같은 것을 사용합니다.

function fetchSpecificRow(&$myRecord) {
    $myRecord = array();
    $myQuery = "some sql...";
    $stmt = $this->prepare($myQuery);
    $stmt->execute(array($parm1, $parm2, ...));
    if ($myRecord = $stmt->fetch(PDO::FETCH_ASSOC)) return 0;
    return $myErrNum;
}

-1

간단한 해결책이 있습니다. PDO를 사용하는 경우 다음과 같이 DB에 연결하십시오.

try {
    $handler = new PDO('mysql:host=localhost;dbname=name_of_your_db', 'your_login', 'your_password'); 
    $handler -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} 
    catch (PDOException $e) {   
    echo $e->getMessage();
}

그런 다음 DB에 대한 쿼리는 다음과 같습니다.

$query = $handler->query("SELECT id FROM your_table WHERE ...");

마지막으로 쿼리와 일치하는 행을 계산하여 다음과 같이 작성하십시오.

$amountOfRows = $query->rowcount();

왜 이것이 대부분 -1을 반환합니까? 데이터가 있어도. .
Ingus

-1

fetchColumn ()

레코드 수를 얻으려면 사용됨 [effisien]

$sql   = "SELECT COUNT(*) FROM fruit WHERE calories > 100";
$res   = $conn->query($sql);
$count = $res->fetchColumn(); // ex = 2

질문()

데이터 및 레코드 수를 검색하려는 경우 사용 [옵션]

$sql = "SELECT * FROM fruit WHERE calories > 100";
$res = $conn->query($sql);

if ( $res->rowCount() > 0) {

    foreach ( $res as $row ) {
        print "Name: {$row['NAME']} <br />";
    }

}
else {
    print "No rows matched the query.";
}

PDOStatement :: rowCount


절대 그렇게하지 않아야 합니다. 다소 큰 테이블에서 모든 서버 메모리를 소모하고 서버를 중단시킵니다
Common Sense

이제 귀하의 답변은 12 개의 기존 답변을 복제합니다.
당신의 상식

-2

다음과 같이 mysql 문에서 COUNT (*)를 만들 때

$q = $db->query("SELECT COUNT(*) FROM ...");

mysql 쿼리는 이미 PHP에서 다시 계산되는 결과 수를 계산하고 있습니까? mysql의 결과를 얻으려면

$q = $db->query("SELECT COUNT(*) as counted FROM ...");
$nb = $q->fetch(PDO::FETCH_OBJ);
$nb = $nb->counted;

$nb 당신은 당신의 mysql 문으로 계산 한 정수를 조금 쓸 수 있지만 실행하기에는 빠릅니다.

편집 : 잘못된 게시물에 대해 죄송하지만 예를 들어 카운트가있는 쿼리를 표시하는 경우 mysql 결과를 사용하는 것이 좋습니다. 그러나 sql fetchAll ()에서 카운트를 사용하지 않으면 결과를 변수에 저장하면 효율적입니다 당신은 줄을 잃지 않을 것입니다.

$data = $dbh->query("SELECT * FROM ...");
$table = $data->fetchAll(PDO::FETCH_OBJ);

count($table)행 수를 반환하고 유사 $row = $table[0] 하거나 사용 후에도 결과를 계속 사용할 수 있습니다foreach

foreach($table as $row){
  print $row->id;
}

1
문제는 mysql 문에서 COUNT (*)를 만들지 않을 때 계산하는 방법입니다.
Common Sense

-2

다음은 마지막 쿼리의 "WHERE"기준에 포함 된 행 수를 검색하는 도우미 함수와 함께 PDO 클래스의 사용자 정의 확장입니다.

사용하는 명령에 따라 더 많은 '핸들러'를 추가해야 할 수도 있습니다. 현재는 "FROM"또는 "UPDATE"를 사용하는 쿼리에서만 작동합니다.

class PDO_V extends PDO
{
    private $lastQuery = null;

    public function query($query)
    {
        $this->lastQuery = $query;    
        return parent::query($query);
    }
    public function getLastQueryRowCount()
    {
        $lastQuery = $this->lastQuery;
        $commandBeforeTableName = null;
        if (strpos($lastQuery, 'FROM') !== false)
            $commandBeforeTableName = 'FROM';
        if (strpos($lastQuery, 'UPDATE') !== false)
            $commandBeforeTableName = 'UPDATE';

        $after = substr($lastQuery, strpos($lastQuery, $commandBeforeTableName) + (strlen($commandBeforeTableName) + 1));
        $table = substr($after, 0, strpos($after, ' '));

        $wherePart = substr($lastQuery, strpos($lastQuery, 'WHERE'));

        $result = parent::query("SELECT COUNT(*) FROM $table " . $wherePart);
        if ($result == null)
            return 0;
        return $result->fetchColumn();
    }
}

이 문제는 노력할 가치가 없습니다. 그러한 숫자는 거의 필요하지 않으므로 전용 확장이 필요하지 않습니다. 말할 것도없이 PDO를 사용해야하는 유일한 이유는 준비된 문장을 지원하지 않습니다.
당신의 상식

-2

가장 좋은 방법을 한 줄 또는 함수로 결합하고 새로운 쿼리를 자동 생성 할 수 있습니다.

function getRowCount($q){ 
    global $db;
    return $db->query(preg_replace('/SELECT [A-Za-z,]+ FROM /i','SELECT count(*) FROM ',$q))->fetchColumn();
}

$numRows = getRowCount($query);

이 방법에서 가장 좋은 것은 없습니다. 리턴 된 행 수를 알기 위해 추가 쿼리를 실행하는 것은 전혀 의미가 없습니다.
당신의 상식

-2
<table>
      <thead>
           <tr>
                <th>Sn.</th>
                <th>Name</th>
           </tr>
      </thead>
      <tbody>
<?php
     $i=0;
     $statement = $db->prepare("SELECT * FROM tbl_user ORDER BY name ASC");
     $statement->execute();
     $result = $statement->fetchColumn();
     foreach($result as $row) {
        $i++;
    ?>  
      <tr>
         <td><?php echo $i; ?></td>
         <td><?php echo $row['name']; ?></td>
      </tr>
     <?php
          }
     ?>
     </tbody>
</table>

1
이것은 정말 나쁜 생각입니다. 모든 행을 선택하면 대역폭이 크게 낭비됩니다.
Nafees

-2
function count_x($connect) {  
 $query = "  SELECT * FROM tbl WHERE id = '0' ";  
 $statement = $connect->prepare($query);  $statement->execute();  
 $total_rows = $statement->rowCount();  
 return $total_rows; 
}

-4

매개 변수를 사용 array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)하고 그렇지 않으면 -1을 표시 하십시오 .

array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)중고 Parametro , sin ello 판매 -1

예:

$res1 = $mdb2->prepare("SELECT clave FROM $tb WHERE id_usuario='$username' AND activo=1 and id_tipo_usuario='4'", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$res1->execute();

$count=$res1->rowCount();
echo $count;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.