我有个问题。我们需要知道 SELECT 查询返回的行数。我遇到了各种解决方案,但我不明白哪个是正确的。出于某种原因,在英文 StackOverflow 上,许多人建议简单地而不是SELECT * FROM...做SELECT COUNT(*) FROM.... 如果我有半屏请求怎么办?具有嵌套SELECT'ami、JOIN'ami等魅力?我应该复制它并在任何地方添加 COUNT() 吗?这是歪的,恕我直言。我不想要那个。
还有第二种选择。这样做:
$result = $pdo->query( 'SELECT * FROM `foo_bar`;' );
$count_result = $pdo->query( 'SELECT FOUND_ROWS();' );
$row_count = $count_result->fetchColumn();
然后我们会取回我们需要的东西。但立即的问题是 - 这种方法有哪些限制/错误?陷阱,或不明显的问题。
还有第三种选择。
$result = $pdo->query( 'SELECT * FROM `foo_bar`;' );
$row_count = $result->rowCount();
官方 PDO 文档说 rowCount() 不适用于 SELECT 查询。相反,它写的是不能保证它对所有数据库的正确操作。我的测试表明 MySQL 和 PostgreSQLrowCount()可以正常工作。
毕竟,问题是如何计算 SELECT 查询选择的行数是否正确?
PScount( $result->fetchAll() ) 不提供。即使是悲惨的 100k 记录……你明白的。
请求示例:
$sql="SELECT SQL_CALC_FOUND_ROWS
metering.id,
metering.super_number,
metering.contract,
metering.name,
metering.city,
metering.address,
metering.phone,
metering.additional_phone,
metering.responsible,
metering.name_metering,
metering.number_card_customer,
metering.date_contract,
metering.date_metering,
metering.time_metering,
metering.status_customer,
metering.status,
metering.notification,
metering.date_status,
metering.date,
metering.creator,
metering.type,
metering.importance,
metering.source_attraction,
metering.production,
metering.status_metering,
metering.delivery_date,
metering.delivery_time,
metering.production_date,
user_retail.login AS login_responsible,
login_name_metering.login AS login_name_metering,
(SELECT COUNT(*) FROM prepay_metering WHERE prepay_metering.id_custom = metering.id) AS prepay,
(SELECT COUNT(*) FROM manufacture_cost WHERE manufacture_cost.name = metering.id) AS prepay_cost,
(SELECT COUNT(*) FROM `communication_metering` WHERE `communication_metering`.`id_metering` = `metering`.`id`) AS comment
FROM `metering`
LEFT JOIN user_retail ON user_retail.id = metering.responsible
LEFT JOIN user_retail AS login_name_metering ON login_name_metering.id = metering.name_metering
WHERE
metering.group_id = '".$_SESSION['group_id']."%' AND
metering.id LIKE '".$_SESSION['id']."%' AND
metering.super_number LIKE '".$_SESSION['super_number']."%' AND
metering.contract LIKE '".$_SESSION['contract']."%' AND
metering.name LIKE '%".$_SESSION['name']."%' AND
metering.city LIKE '%".$_SESSION['city']."%' AND
metering.address LIKE '%".$_SESSION['address']."%' AND
(metering.phone LIKE '%".$_SESSION['phone']."%' OR metering.additional_phone LIKE '%".$_SESSION['phone']."%') AND
metering.name_metering LIKE '".$_SESSION['name_metering']."%' AND
metering.number_card_customer LIKE '".$_SESSION['number_card_customer']."%' AND
metering.type LIKE '".$_SESSION['type']."%' AND
metering.responsible LIKE '".$_SESSION['name_responsible']."%'
";
这是最初的要求。接下来是这个请求发生了什么的两个屏幕:
$_SESSION['status_customer']=$_POST['status_customer'];
if (!empty($_SESSION['status_customer'])) $sql.="AND metering.status_customer='".$_SESSION['status_customer']."'";
$_SESSION['status']=$_POST['status'];
if (!empty($_SESSION['status'])) $sql.="AND metering.status_customer=2 AND metering.status='".$_SESSION['status']."'";
$_SESSION['contract_yes']=$_POST['contract_yes'];
if (!empty($_SESSION['contract_yes'])) $sql.="AND metering.contract!=''";
$_SESSION['metering_sr']=$_POST['metering'];
if (!empty($_SESSION['metering_sr'])) $sql.="AND metering.metering='3'";
//Дата создания
if (!empty($_SESSION['date1'])) {
$start_date = substr($_SESSION['date1'],6,4).'-'.substr($_SESSION['date1'],3,2).'-'.substr($_SESSION['date1'],0,2);
$sql=$sql."AND metering.date >= '".$start_date."'";
}
if (!empty($_SESSION['date2'])) {
$end_date = substr($_SESSION['date2'],6,4).'-'.substr($_SESSION['date2'],3,2).'-'.substr($_SESSION['date2'],0,2);
$sql=$sql."AND metering.date <= '".$end_date."' ";
}
//Дата замера
if (!empty($_SESSION['date_metering1'])) {
$start_date = substr($_SESSION['date_metering1'],6,4).'-'.substr($_SESSION['date_metering1'],3,2).'-'.substr($_SESSION['date_metering1'],0,2);
$sql=$sql."AND metering.date_metering >= '".$start_date."'";
}
if (!empty($_SESSION['date_metering2'])) {
$end_date = substr($_SESSION['date_metering2'],6,4).'-'.substr($_SESSION['date_metering2'],3,2).'-'.substr($_SESSION['date_metering2'],0,2);
$sql=$sql."AND metering.date_metering <= '".$end_date."' ";
}
//Дата контракта
if (!empty($_SESSION['date_contract1'])) {
$start_date = substr($_SESSION['date_contract1'],6,4).'-'.substr($_SESSION['date_contract1'],3,2).'-'.substr($_SESSION['date_contract1'],0,2);
$sql=$sql."AND metering.date_contract >= '".$start_date."'";
}
if (!empty($_SESSION['date_contract2'])) {
$end_date = substr($_SESSION['date_contract2'],6,4).'-'.substr($_SESSION['date_contract2'],3,2).'-'.substr($_SESSION['date_contract2'],0,2);
$sql=$sql."AND metering.date_contract <= '".$end_date."' ";
}
//Дата доставки
if (!empty($_SESSION['date_delivery1'])) {
$start_date = substr($_SESSION['date_delivery1'],6,4).'-'.substr($_SESSION['date_delivery1'],3,2).'-'.substr($_SESSION['date_delivery1'],0,2);
$sql=$sql."AND metering.delivery_date >= '".$start_date."'";
}
if (!empty($_SESSION['date_delivery2'])) {
$end_date = substr($_SESSION['date_delivery2'],6,4).'-'.substr($_SESSION['date_delivery2'],3,2).'-'.substr($_SESSION['date_delivery2'],0,2);
$sql=$sql."AND metering.delivery_date <= '".$end_date."' ";
}
//Постраничное отображение
if (isset($_GET['pag'])) $pag=$_GET['pag'];
else $pag=0;
if (empty($_GET['lim'])) $sql .=" LIMIT ".$pag.", 30;";
代码不是我的。有一个任务要转移到 PDO。因此,我不希望看到“歪手”和“谁这样写”的评论,因为它会在错误的地址:) 谢谢
你不需要它
总之,
rowCount()对于一个select来说,这是所有Database API中最没意义的函数当您可能需要计算某些东西时,恰好有两种情况:
count(данные)。SELECT count(*)从没有选项的基础。一切,没有更多的情况了,lamers喜爱的mysql_num_rows和rowCount都失灵了。
SQL_CALC_FOUND_ROWS不是很理想,只能在总行数很少的情况下使用。否则,它将过多地加载基础。因此,正如评论中正确建议的那样,将字段列表设为变量,并根据请求替换它或计数 (*)。那些。
您进行这样的查询“SELECT COUNT(*) FROM...”,然后在 PDO 中,您在查询此查询 fetchColumn(); 之后执行此操作。它将返回记录数。http://php.net/manual/ru/pdostatement.fetchcolumn.php
示例:请求:
$res = $pdo->query("SELECT COUNT(*) FROM table");获取号码:$countNum = $res->fetchColumn();