Subquery (COUNT) Doesn't Work - php

I'm working with PHP and MySQL. This query works, where my page URL is MySite/Carl_Sagan (Carl_Sagan = $MyURL) and Carl_Sagan is also a value in a database table named people, field URL:
$sql= "SELECT COUNT(URL) AS num FROM people WHERE URL = :MyURL";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':MyURL',$MyURL,PDO::PARAM_STR);
$stmt->execute();
$Total = $stmt->fetch();
switch($Total['num'])
{
case 1:
echo "\n";
require($BaseINC."/$MyPHP/inc/C/2_Child.php");
break;
case 0:
break;
default:
break;
}
But when I link several tables together through UNION ALL, turning it into a subquery, it doesn't work. I'm not getting any error messages, but the value for $Total['num'] is 0, when it should be 1.
Can anyone see the problem with my subquery, posted below?
$sql = "SELECT SUM(num) FROM (
SELECT COUNT(URL) AS num FROM pox_topics WHERE URL = :MyURL
UNION ALL
SELECT COUNT(URL) AS num FROM people WHERE URL = :MyURL
UNION ALL
SELECT COUNT(Taxon) AS num FROM gz_life WHERE Taxon = :MyURL
) AS X";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':MyURL',$MyURL,PDO::PARAM_STR);
$stmt->execute();
$Total = $stmt->fetch();
I should note that the subquery doesn't work even if I strip it down to the original table, like this:
$sql = "SELECT SUM(num) FROM (
SELECT COUNT(URL) AS num FROM people WHERE URL = :MyURL
) AS X";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':MyURL',$MyURL,PDO::PARAM_STR);
$stmt->execute();
$Total = $stmt->fetch();

There is no $Total['num'] anymore. Try SELECT SUM(num) AS num...

Related

Pagination 2nd page not displaying

Pagination works fine when I don't use the WHERE statement in my SELECT statement. For some reason as soon as I add additional requests in the SELECT statement, only the 1st pagination page works. So it seems like the variable data is lost after the first page is displayed. Below is some of the code:-
<?php
include 'database.php';
include 'paginator.php';
$pdo = Database::connect();
$paginator = new Paginator();
$sql = "SELECT count(*) FROM customer_crm ";
$paginator->paginate($pdo->query($sql)->fetchColumn());
$query = $_GET["query"];
if (isset($query)) {
($_GET['query'])?('%'.$_GET['query'].'%'):'%';
$sql = "SELECT * FROM customer_crm WHERE firstname LIKE :query OR email LIKE :query OR telephone LIKE :query ";
}
else {
$start = (($paginator->getCurrentPage()-1)*$paginator->itemsPerPage);
$length = ($paginator->itemsPerPage);
//$sql = "SELECT * FROM customer_crm WHERE customer_group_id = $input OR date_followup= CURDATE() ORDER BY customer_group_id DESC limit $start, $length ";
$sql = "SELECT * FROM customer_crm ORDER BY date_followup DESC limit $start, $length ";
//$sql = "SELECT * FROM customer_crm WHERE customer_group_id = $input ORDER BY date_followup DESC limit $start, $length ";
}
$sth = $pdo->prepare($sql);
$sth->bindParam(':start',$start,PDO::PARAM_INT);
$sth->bindParam(':length',$length,PDO::PARAM_INT);
$sth->bindParam(':query',$query,PDO::PARAM_STR);
$sth->execute();
foreach ($sth->fetchAll(PDO::FETCH_ASSOC) as $row) {
Without knowing which Paginator are we talking about, I could only advise you to do something like
include 'database.php';
include 'paginator.php';
$pdo = Database::connect();
$paginator = new Paginator();
$query = (isset($_GET["query"]) && strlen($_GET["query"])>1)? '%'.$_GET["query"].'%':'%';
$countsql = "SELECT * FROM customer_crm WHERE firstname LIKE :query OR email LIKE :query OR telephone LIKE :query ";
$sthcount = $pdo->prepare($countsql);
$sthcount->bindParam(':query',$query,PDO::PARAM_STR);
$sthcount->execute();
$count=$sthcount->fetchColumn();
$paginator->paginate($count);
$start = (($paginator->getCurrentPage()-1)*$paginator->itemsPerPage);
$length = ($paginator->itemsPerPage);
$sql = $countsql . ' ORDER BY date_followup DESC limit :start, :length ';
$sth = $pdo->prepare($sql);
$sth->bindParam(':start',$start,PDO::PARAM_INT);
$sth->bindParam(':length',$length,PDO::PARAM_INT);
$sth->bindParam(':query',$query,PDO::PARAM_STR);
$sth->execute();
See, you where making two mistakes here:
getting your count value without considering the query. You should set the value of $query regardless of the existance of $_GET['query'], and use it in your count query as well as your results query.
binding parameters whose placeholders and values do not exist in the query you're executing. Make sure your results query contains :query, :start and :length or you will be binding more parameters than the query has.
You should also have wrapped your statements in try/catch blocks so you could debug what was happening.
try {
$sth = $pdo->prepare($sql);
$sth->bindParam(':start',$start,PDO::PARAM_INT);
$sth->bindParam(':length',$length,PDO::PARAM_INT);
$sth->bindParam(':query',$query,PDO::PARAM_STR);
$sth->execute();
} catch(\PDOException $e) {
die('Error in query: '. $e->getMessage());
}
That way you would have known that the query was failing because of
Invalid parameter number: parameter was not defined
NOTE I have no clue about how your paginator will know about the current page, nor can I see where are you setting the itemsPerPage value.

Why FOUND_ROW() works without putting the function into SELECT statement?

Here is my code:
$query = "SELECT SQL_CALC_FOUND_ROWS 1, id, name
FROM users where id > ?";
$sth = $this->dbh->prepare($query);
$sth->execute([4]);
echo $total_num = $this->dbh->query('SELECT FOUND_ROWS()')->fetchColumn();
//=> 43
My code works as well and prints 43.
My question is, why my code still works when I remove SQL_CALC_FOUND_ROWS 1 from SELECT statement?
$query = "SELECT id, name
FROM users where id > ?";
$sth = $this->dbh->prepare($query);
$sth->execute([4]);
echo $total_num = $this->dbh->query('SELECT FOUND_ROWS()')->fetchColumn();
//=> 43
See? It still prints 43. So is putting SQL_CALC_FOUND_ROWS 1 in the SELECT statement mandatory? Why should we put it there anyway?

get information from other table where id=id

soo i have 2 tables.
train_information
user_train_information
When somebody submits something in a form. it get put in the train_information table and looks like this:
Now, when people are logged in and select the train from a selector. his happens in the database:
On a other page, i want the users to see a whole list of things they selected over the time. So i run a query: SELECT * FROM user_train_information WHERE user_id=user_id;
This shows me the table user_train_information
But is it posible to show the train_information where user_id = user_id ? because i want the user to show the trains he added.
EDIT:
What i have now:
function testingggg() {
$sql = "SELECT *
FROM train_information
INNER JOIN user_train_information
ON train_information.train_id = user_train_information.train_id
WHERE user_train_information.user_id = user_id";
$sth = $this->pdo->prepare($sql);
$sth->bindParam("user_id", $_GET["user_id"], PDO::PARAM_INT);
$sth->execute();
return $sth->fetchAll();
}
And i call i here:
<?php
$summary = $database->testingggg();
?>
<?php
foreach ($summary as $result){
echo $result['train_name'];
}
?>
I get the error:
This is how i use query in such case and it works. In your case there ambiguity somewhere. Also make sure you have proper value in $_GET["user_id"]. Please check
function testingggg() {
$sql = "SELECT ti.train_name, ti.train_id, uti.user_id
FROM train_information as ti
JOIN user_train_information as uti
ON ti.train_id = uti.train_id
WHERE uti.user_id = :user_id";
$sth = $this->pdo->prepare($sql);
$sth->bindParam(":user_id", $_GET["user_id"], PDO::PARAM_INT);
$sth->execute();
return $sth->fetchAll();
}
SELECT t.train_id
, t.country_id train_country_id
, t.train_name
, t.number_of_bogies
, t.number_of_axles
, t.wheel_diameter_min
, t.wheel_diameter_max
, u.user_row_id
, u.user_id
, u.country_id user_country_id
FROM user_train_information u
JOIN train_information t
ON t.train_id = u.train_id
WHERE u.user_id = :user_id;
You try this one.
SELECT * FROM train_information INNER JOIN user_train_information
ON train_information.train_id = user_train_information.train_id
WHERE user_train_information.user_id = $user_id;
SELECT *
FROM train_information
INNER JOIN user_train_information
ON train_information.train_id = user_train_information.train_id
WHERE user_train_information.user_id = user_id;

SQL Select count of repeated dates

I'm trying to select count of repeated dates and output its numbers
$user_curr_id = $_SESSION['user_id'];
$sql = "SELECT COUNT(datum) FROM table_name WHERE user_ids = $user_curr_id";
I have no idea how to do it.
2014-07-23,2014-07-23,2014-07-23 => 3
2014-07-24,2014-07-24 =>2
2014-07-25 => 1
and get $result = 3,2,1
I assume you're looking after the GROUP BY clause:
$sql = "SELECT datum, COUNT(datum) as cnt
FROM table_name
WHERE user_ids = $user_curr_id
GROUP BY datum
ORDER BY COUNT(datum) DESC;";
if your column datum is of the data type DATE.
Note
As already mentioned you're vulnerable to sql injection. You should use a parameterized prepared statement and bind your input value to this parameter like that:
$sql = "SELECT datum, COUNT(datum) cnt
FROM table_name
WHERE user_ids = ?
GROUP BY datum
ORDER BY COUNT(datum) DESC;";
$result = array();
if ($stmt = $mysqli->prepare($sql)) {
if ($stmt->bind_param('s', $user_curr_id)) {
if($res = $stmt->execute()) {
while ($row = $res->fetch_assoc()) {
$result[] = $row['cnt']; // add the content of field cnt
}
}
}
}
echo implode(',', $result);

PHP coding question

How can I grab the count value from the query MySQL query below using PHP.
Here is My MySQL code.
$dbc = mysqli_query($mysqli,"SELECT COUNT(*) FROM((SELECT users_friends.id
FROM users_friends
INNER JOIN users ON users_friends.user_id = users.user_id
WHERE users_friends.user_id = 1
AND users_friends.friendship_status = '1')
UNION
(SELECT users_friends.id
FROM users_friends
INNER JOIN users ON users_friends.friend_id = users.user_id
WHERE users_friends.friend_id = 1
AND users_friends.friendship_status = '1')) as friends");
using SQL_CALC_FOUND_ROWS should simplify things:
$dbc = mysqli_query($mysqli,"SELECT SQL_CALC_FOUND_ROWS users_friends.id
FROM users_friends
INNER JOIN users ON users_friends.user_id = users.user_id
WHERE users_friends.user_id = 1
AND users_friends.friendship_status = '1'
");
then afterwards do
$rs = mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$rec = $rs->fetch_array();
$count = $rec[0];
This method will return the number of records that match the query, ignoring any LIMIT statement, whereas using $rs->num_rows will only give you the number of records actually returned. Depends which one you want.
if ($result = mysqli_query($link, "SELECT Name FROM City LIMIT 10")) {
printf("Select returned %d rows.\n", mysqli_num_rows($result));
/* free result set */
mysqli_free_result($result);
http://us.php.net/manual/en/mysqli.query.php
Assuming that you are correctly connected to the MySQL server and your query are executed correctly, you can use the following code:
$values = mysql_fetch_row($dbc);
$count = $values[0];
Your query should look like SELECT COUNT(*) as numThings FROM xxx
The numThings is what you will reference in PHP:
$result = mysql_query("SELECT COUNT(*) as `numThings` FROM xxx");
$row = mysql_fetch_assoc($result);
$count = $row['numThings'];

Categories