How can I use FOUND_ROWS() function in PDO? - php

Already, when I was using mysql_query, I used FOUND_ROWS() function like this:
$query = 'SELECT SQL_CALC_FOUND_ROWS * FROM Users';
mysql_query($query);
$query = 'SELECT FOUND_ROWS()';
mysql_query($query);
Now I use PDO and here is my query:
$sth = $this->dbh->prepare("SELECT SQL_CALC_FOUND_ROWS *,
u.id user_id,
u.avatar,
u.date_time,
CONCAT(u.user_fname, ' ', u.user_lname) name,
sum($this->table_alias.vote_value) vote_value,
sum($this->table_alias.score) score,
$category_in_the_select AS tc $tag_in_the_select AS tt
FROM users u
JOIN reputations $this->table_alias ON u.id = $this->table_alias.owner_id $query_join
WHERE $time_limitation $query_where
GROUP BY user_id, u.avatar, u.date_time, name, tc, tt
ORDER BY score DESC, vote_value DESC
LIMIT :j, $this->per_page");
$this->parameters[":j"] = $j;
$sth->execute($this->parameters);
$users = $sth->fetchAll(PDO::FETCH_ASSOC);
As you can see, I've used SQL_CALC_FOUND_ROWS in the SELECT statement and I want to know how can I use FOUND_ROWS()?

All you need to do is run a ->query('SELECT FOUND_ROWS()') after your original execute.
$sth = $this->dbh->prepare("SELECT SQL_CALC_FOUND_ROWS *,
u.id user_id,
u.avatar,
u.date_time,
CONCAT(u.user_fname, ' ', u.user_lname) name,
sum($this->table_alias.vote_value) vote_value,
sum($this->table_alias.score) score,
$category_in_the_select AS tc $tag_in_the_select AS tt
FROM users u
JOIN reputations $this->table_alias ON u.id = $this->table_alias.owner_id $query_join
WHERE $time_limitation $query_where
GROUP BY user_id, u.avatar, u.date_time, name, tc, tt
ORDER BY score DESC, vote_value DESC
LIMIT :j, $this->per_page");
$this->parameters[":j"] = $j;
$sth->execute($this->parameters);
$users = $sth->fetchAll(PDO::FETCH_ASSOC);
$count = $this->dbh->query('SELECT FOUND_ROWS()')->fetchColumn();

Related

How can I get the latest item price in mysql query?

I manage to get the lowest, highest and average price of the item but couldn't get the latest price. Below is the select query i am using by joining the item and item_price tables. How can I fix the problem?
$sql = 'SELECT *, MIN(ip_price) AS lowest_price, MAX(ip_price) AS highest_price,
AVG(ip_price) AS average_price, MAX(ip_price_date) AS latest_date,
(SELECT ip_price FROM cnf_item_price WHERE ip_price_date = "latest_date") AS latest_price
FROM cnf_item
INNER JOIN cnf_item_price ON cnf_item_price.ip_item_id = cnf_item.it_id
WHERE 1 AND cnf_item_price.ip_supp_id=?
GROUP BY cnf_item.it_id
ORDER BY cnf_item.it_name ASC';
$stmt = $DB->prepare($sql);
$stmt->bindValue(1,$supplier_id);
$stmt->execute();
can you try following query:
$sql = 'SELECT *, MIN(ip_price) AS lowest_price, MAX(ip_price) AS highest_price,
AVG(ip_price) AS average_price, MAX(ip_price_date) AS latest_date,
(SELECT ip_price FROM cnf_item_price order by ip_price_date desc limit 1) AS latest_price
FROM cnf_item
INNER JOIN cnf_item_price ON cnf_item_price.ip_item_id = cnf_item.it_id
WHERE 1 AND cnf_item_price.ip_supp_id=?
GROUP BY cnf_item.it_id
ORDER BY cnf_item.it_name ASC';
$stmt = $DB->prepare($sql);
$stmt->bindValue(1,$supplier_id);
$stmt->execute();
Thanks #ahmet kamaran. It's working for my case here. I also replace * with those columns needed as suggested by others. So, after some testing from the above suggestions, here is my codes which retrieve those data i needed.
$sql = 'SELECT it_id, it_code, it_name, it_desc,
ip_id, ip_item_id, ip_supp_id, ip_price, ip_price_date, ip_ref_no, ip_remarks,
MIN(ip_price) AS lowest_price, MAX(ip_price) AS highest_price,
AVG(ip_price) AS average_price, MAX(ip_price_date) AS latest_date,
(SELECT ip_price FROM cnf_item_price ORDER BY ip_price_date DESC LIMIT 1) AS latest_price
FROM cnf_item
INNER JOIN cnf_item_price ON cnf_item_price.ip_item_id = cnf_item.it_id
WHERE 1 AND cnf_item_price.ip_supp_id=?
GROUP BY cnf_item.it_id
ORDER BY cnf_item.it_name ASC';
$stmt = $DB->prepare($sql);
$stmt->bindValue(1,$supplier_id);
$stmt->execute();
http://sqlfiddle.com/#!9/ca6234/2
Thanks.
SELECT it_id, it_code, it_name, it_desc,
ip_id, ip_item_id, ip_supp_id, ip_price, ip_price_date, ip_ref_no, ip_remarks,
MIN(ip_price) AS lowest_price, MAX(ip_price) AS highest_price,
AVG(ip_price) AS average_price, MAX(ip_price_date) AS latest_date,
(SELECT ip_price FROM cnf_item_price WHERE cnf_item_price.ip_item_id = cnf_item.it_id
ORDER BY ip_price_date DESC LIMIT 1) AS latest_price
FROM cnf_item
INNER JOIN cnf_item_price ON cnf_item_price.ip_item_id = cnf_item.it_id
WHERE 1
GROUP BY cnf_item.it_id
ORDER BY cnf_item.it_name ASC;

SELECT custom fields and all fields when LEFT JOIN

I'm selecting data from 2 tables.
$sql = "SELECT tb1.id, tb2.name FROM tblA tbl1 LEFT JOIN tblB tbl2 ON tb1.id = tbl2.studentID ORDER BY tbl1.id DESC LIMIT 20";
$statement = $con_db->prepare($sql);
My question is now can I SELECT custom fields from tb1 and all fields in tb2? e.g.
$sql = "SELECT tb1.id, tb1.subject, tb2.(*) FROM ....";
You can write the code like below
$sql = "SELECT tb1.id, tb1.subject, tb2.* FROM tblA tbl1 LEFT JOIN tblB tbl2 ON tb1.id = tbl2.studentID ORDER BY tbl1.id DESC LIMIT 20";

Codeigniter combine two results

I have two queries. I have to execute both queries and return in same result object.
for example
$query1 = "SELECT name,age from students";
$query2 = "SELECT name,age from users";
$result1 = $this->db->query($query1)
$result2 = $this->db->query($query2)
return result1 and result 2 together ;
I have to return the result of both queries in same object. please help me
the actual query is ::
SELECT dev_members.name,dev_members.id,dev_members.age,dev_members.family_id,dev_family.house_name,dev_ib_account_registration.account_id FROM (dev_members)
JOIN dev_family ON dev_family.id=dev_members.family_id
JOIN dev_ib_account_registration ON dev_ib_account_registration.member_id=dev_members.id
UNION
SELECT dev_members.name,dev_members.id,dev_members.age,dev_members.family_id, dev_family.house_name,dev_ib_sub_member_registration.account_id FROM (dev_members)
JOIN dev_family ON dev_family.id=dev_members.family_id
JOIN dev_ib_sub_member_registration ON dev_ib_sub_member_registration.member_id=dev_members.id
You can use UNION
$query = "SELECT name,age from students
UNION
SELECT name,age from users";
$result = $this->db->query($query);
Or if you want to identify records from which table row belongs to then
$query = "SELECT name,age, 'students ' AS `table_type` from students
UNION
SELECT name,age, 'users' AS `table_type` from users";
$result = $this->db->query($query);
You might want to search for a question before asking it..
Here is the same question already with an answer.
$query = "SELECT name,age from students UNION ALL SELECT name,age from users";
You need to use UNION ALL instead of UNION in your query
SELECT dev_members.name,dev_members.id,dev_members.age,dev_members.family_id,dev_family.house_name,dev_ib_account_registration.account_id FROM (dev_members)
JOIN dev_family ON dev_family.id=dev_members.family_id
JOIN dev_ib_account_registration ON dev_ib_account_registration.member_id=dev_members.id
UNION ALL
SELECT dev_members.name,dev_members.id,dev_members.age,dev_members.family_id, dev_family.house_name,dev_ib_sub_member_registration.account_id FROM (dev_members)
JOIN dev_family ON dev_family.id=dev_members.family_id
JOIN dev_ib_sub_member_registration ON dev_ib_sub_member_registration.member_id=dev_members.id
UNION removes repeating rows in final result set while UNION ALL keeps the duplicate.

How to rewrite normal sql select with IF to Zend Framework select?

I have a normal mysql select and I would like to rewrite it to a Zend Framework mysql select. Here is my select:
$sql = "
SELECT
IF(mu.recieverUserId = '{$userId}', u.senderUserId,
mu.recieverUserId) friend1,
u.mesaj, u.senderUserId, mu.recieverUserId,
u.created
FROM
(SELECT *
FROM mesaje
ORDER BY `created` desc) AS u
LEFT JOIN `mesaje_utilizatori` AS `mu` ON u.id=mu.mesajId
WHERE (mu.recieverUserId = '{$userId}' OR u.senderUserId='{$userId}')
GROUP BY friend1 ASC
ORDER BY `u`.`created` DESC, u.id DESC
";
Here is the documentation: Zend_Db_Statement
Zend Query
$sql = $db->query(
'SELECT
IF(mu.recieverUserId = ?, u.senderUserId,
mu.recieverUserId) friend1,
u.mesaj, u.senderUserId, mu.recieverUserId,
u.created
FROM
(SELECT *
FROM mesaje
ORDER BY `created` desc) AS u
LEFT JOIN `mesaje_utilizatori` AS `mu` ON u.id=mu.mesajId
WHERE (mu.recieverUserId = ? OR u.senderUserId = ? )
GROUP BY friend1 ASC
ORDER BY `u`.`created` DESC, u.id DESC',
array($userId, $userId,$userId)
);
Zend Result
while ($row = $sql->fetch()) {
Zend_Debug::dump($row);
}

Combine Entry Count in a UNION Query

How do i combine the counts from all the tables being used in a UNION query. This is what i have:
$query = "SELECT COUNT(*) as num
from table_one LEFT JOIN table_constant on table_one.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
UNION
SELECT COUNT(*) as num
from table_two LEFT JOIN table_constant on table_two.c_id
= table_constant.c_id
where table_two.added_by = '$uid'
UNION
SELECT COUNT(*) as num
from table_three LEFT JOIN table_constant ON table_three.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
UNION
SELECT COUNT(*) as num
from table_four LEFT JOIN table_constant ON table_four.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
ORDER BY date_time_added DESC";
$total_pages = mysql_fetch_array(mysql_query($query));
$total_pages = $total_pages[num];
Wrap the whole thing in yet another query and do the summation there.
SELECT sum(num)
FROM ( ... union queries here ...) as subquery;
Or loop over the returned rows in PHP and do the summation yourself.
Did you try to put count outside and apply it on sub query containing all tables union result.
SELECT COUNT(*) FROM (SELECT ...) as abc
Or try this out
Select mytable .userid, sum(mytable .subcount) as totalcount from
(
select userid, count(*) as subcount from table1 group by userid
union all
select userid, count(*) as subcount from table2 group by userid
)
as mytable
group by mytable .userid
or try using FULL OUTER JOIN instead of union it will give you the same result..
SELECT Count(UserID), UserId
FROM MyTable1
GROUP BY MyTable1.UserID
UNION
SELECT Count(UserID), UserId
FROM MyTable2
FULL OUTER JOIN MyTable2 ON (MyTable1.UserId=MyTable2.UserId)
GROUP BY MyTable2.UserID
Updated answer:
IF Your query is working fine follow my first option that i gave means
select count(*) from (your query) as pagecount..
Then your query would be like this.....
select count(*) from
(
SELECT COUNT(*) as num
from table_one LEFT JOIN table_constant on table_one.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
UNION
SELECT COUNT(*) as num
from table_two LEFT JOIN table_constant on table_two.c_id
= table_constant.c_id
where table_two.added_by = '$uid'
UNION
SELECT COUNT(*) as num
from table_three LEFT JOIN table_constant ON table_three.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
UNION
SELECT COUNT(*) as num
from table_four LEFT JOIN table_constant ON table_four.c_id
= table_constant.c_id
where table_constant.user_id = '$uid'
ORDER BY date_time_added DESC") as pagecount
There must be a better way to write that :/. A union is very powerful, but you are calling 4 selects in a single query, and if that is run every page, it will really hurt performance.
To answer you question, something like:
SELECT
SUM (mnTbl.num) as sumNum
FROM
(
SELECT
COUNT(*) as num
FROM
table_one
LEFT JOIN
table_constant
ON
table_one.c_id = table_constant.c_id
WHERE
table_constant.user_id = '$uid'
UNION
SELECT
COUNT(*) as num
FROM
table_two
LEFT JOIN
table_constant
ON
table_two.c_id = table_constant.c_id
WHERE
table_two.added_by = '$uid'
UNION
SELECT
COUNT(*) as num
FROM
table_three
LEFT JOIN
table_constant
ON
table_three.c_id = table_constant.c_id
WHERE
table_constant.user_id = '$uid'
UNION
SELECT
COUNT(*) as num
FROM
table_four
LEFT JOIN
table_constant
ON
table_four.c_id = table_constant.c_id
WHERE
table_constant.user_id = '$uid'
) as mnTbl
ORDER BY
date_time_added DESC

Categories