Error when I used GROUP_CONCAT on mysql query - php

my code worked good , but when i add
GROUP_CONCAT(CONCAT("<a href='index.php?id=", awards_user.userid, "'>", awards_user.username, "</a>")) AS userlist
to get users-id with username , show me error
Parse error: syntax error, unexpected T_STRING [in this line]
SELECT awards.name as name, awards.link as link,
GROUP_CONCAT(DISTINCT awards_user.username) AS username,
GROUP_CONCAT(DISTINCT awards_user.userid) AS userid,
GROUP_CONCAT(CONCAT("<a href='index.php?id=", awards_user.userid, "'>", awards_user.username, "</a>")) AS userlist
FROM awards LEFT JOIN awards_user ON (awards_user.awardid = awards.awardid)
where awards.forumid = '".$_REQUEST['forumid']."'
GROUP BY awards.awardid, awards.name, awards.link

You should escape double quotes " with backslash \ otherwise php will understand this as the end of the string :
$sql = "SELECT awards.name as name
, awards.link as link
, GROUP_CONCAT(DISTINCT awards_user.username) AS username
, GROUP_CONCAT(DISTINCT awards_user.userid) AS userid
, GROUP_CONCAT(CONCAT(\"<a href='index.php?id=\", awards_user.userid, \"'>\"
, awards_user.username, \"</a>\")) AS userlist
FROM awards LEFT JOIN awards_user ON (awards_user.awardid = awards.awardid)
WHERE awards.forumid = '" . $_REQUEST['forumid'] . "'
GROUP BY awards.awardid
, awards.name
, awards.link";

The escaping of quotes is an issue. So why not use heredoc syntax like this.
$formid = $_REQUEST['forumid'];
$query = <<<EOT
SELECT awards.name as name, awards.link as link,
GROUP_CONCAT(DISTINCT awards_user.username) AS username,
GROUP_CONCAT(DISTINCT awards_user.userid) AS userid,
GROUP_CONCAT(CONCAT("<a href='index.php?id=", awards_user.userid, "'>", awards_user.username, "</a>")) AS userlist
FROM awards LEFT JOIN awards_user ON (awards_user.awardid = awards.awardid)
where awards.forumid = '$formid'
GROUP BY awards.awardid, awards.name, awards.link
EOT;
The idea is heredoc syntax allows for a full string with string replacement & without having to worry about escaping quotes. Or knowing that you can set variables for "<a href='index.php?id=", '> and </a> like this:
$formid = $_REQUEST['forumid'];
$id_link_1 = "<a href='index.php?id=";
$id_link_2 = "'>";
$id_link_3 = "</a>";
$query = <<<EOT
SELECT awards.name as name, awards.link as link,
GROUP_CONCAT(DISTINCT awards_user.username) AS username,
GROUP_CONCAT(DISTINCT awards_user.userid) AS userid,
GROUP_CONCAT(CONCAT($id_link_1, awards_user.userid, $id_link_2, awards_user.username, $id_link_3)) AS userlist
FROM awards LEFT JOIN awards_user ON (awards_user.awardid = awards.awardid)
where awards.forumid = '$formid'
GROUP BY awards.awardid, awards.name, awards.link
EOT;

Related

PDO error "Truncated incorrect DOUBLE value" using placeholder

I have the following PHP code that works perfectly ($qry_str is actually generated in the PHP):
$qry_str = <<<'QRY'
FIND_IN_SET('6-47', attributes)
AND FIND_IN_SET('4-176', attributes)
AND FIND_IN_SET('9-218', attributes)
QRY;
$pdo->query('DROP TEMPORARY TABLE IF EXISTS `temp_attr`');
$temp_sql = <<<"TEMP"
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_attr` (
SELECT product_id, GROUP_CONCAT(CONCAT(group_id, '-', IF (custom_value != '', custom_value, value_id)) SEPARATOR ',') AS attributes
FROM `products_attributes`
GROUP BY `product_id`
HAVING $qry_str
);
TEMP;
$pdo->query($temp_sql);
$sql = "SELECT
m.recommended_price AS msrp,
m.purchase_price AS cost,
pp.USD AS regular_price,
pc.USD AS special_price,
pc.start_date AS start_date,
pc.end_date AS end_date,
pl.permalink AS permalink,
pi.name AS description,
m.sku AS sku,
m.default_category_id AS cat,
m.id AS prod_id
FROM `products` AS m
LEFT JOIN `products_prices` AS pp ON m.id = pp.product_id
LEFT JOIN `products_campaigns` AS pc ON m.id = pc.product_id
LEFT JOIN `permalinks` AS pl ON (m.id = pl.resource_id AND pl.resource = 'product')
LEFT JOIN `products_info` AS pi ON (m.id = pi.product_id)
LEFT JOIN `products_to_categories` AS ptc ON (m.id = ptc.product_id)
INNER JOIN `temp_attr` AS pa
WHERE ptc.category_id = :cat
AND m.status = 1
AND m.id = pa.product_id
LIMIT 55;
";
$data = $pdo->prepare($sql)
->bindValue('cat', 100)
->execute()
->fetchAll();
However, when I use a placeholder in the temp table code, i.e.
$temp_sql = <<<"TEMP"
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_attr` (
SELECT product_id, GROUP_CONCAT(CONCAT(group_id, '-', IF (custom_value != '', custom_value, value_id)) SEPARATOR ',') AS attributes
FROM `products_attributes`
GROUP BY `product_id`
HAVING :qry_str
);
TEMP;
$sth = $pdo->prepare($temp_sql);
$sth->bindValue('qry_str', $qry_str, PDO::PARAM_STR);
$sth->execute();
I get the following error:
PHP Fatal error: Uncaught PDOException: SQLSTATE[22007]: Invalid datetime format: 1292 Truncated incorrect DOUBLE value: 'FIND_IN_SET('6-47', attributes)
AND FIND_IN_SET('4-176', attributes)
AND FIND_IN_SET('9-218', attributes)
AND FIND_IN_SET(...'
There are no datetime columns in this table.
group_id and value_id are integer columns
Since the code works fine without the placeholder, I'm at a loss as to why the use of a placeholder breaks the code. The placeholder in the main SQL works properly.
PHP 8.0
https://dev.mysql.com/doc/refman/8.0/en/prepare.html explains:
Parameter markers can be used only where data values should appear, not for SQL keywords, identifiers, and so forth.
In your case, you're apparently trying to bind an expression with the FIND_IN_SET() function. You can't do that. All expressions and other SQL syntax must be fixed in the query at the time you prepare it. You can use a parameter only in a place where you would otherwise use a scalar literal value. That is, a quoted string or a numeric literal.

Adding WHERE cause to COUNT query

I am having trouble getting a where clause to be part of a COUNT query.
This works to get total count of the table:
$search = $_POST['search_text'];
SELECT COUNT(*)
FROM
stories')
->fetchColumn();
However, when I try to add WHERE stories.category = $search i get syntax errors when I try any of these:
$total = $dbh->query('
SELECT
COUNT(*)
FROM
stories
WHERE
stories.category = "$search"
');
->fetchColumn();
FROM
stories
WHERE stories.category='$search'
FROM
stories
WHERE (stories.category="$search")
You can use a variable inside double quotes, but must use concatenation to use one inside single quotes. (ex.. 'my string '.$myvar.' some more string' )
SQL expects strings in either format '' or "" so you can use them interchangeably or with escaped quotes ...
You can escape like this inside of single and double quotes ...
" \" <--- puts a quote in without terminating the string "
' \' <--- same with single quotes '
$total = $dbh->query("
SELECT
COUNT(*)
FROM
stories
WHERE
stories.category = \"$search\"
")
->fetchColumn();
Or
$total = $dbh->query("
SELECT
COUNT(*)
FROM
stories
WHERE
stories.category = '$search'
")
->fetchColumn();
OR
$total = $dbh->query("
SELECT
COUNT(*)
FROM
stories
WHERE
stories.category = '".$search."'
")
->fetchColumn();
Or
$total = $dbh->query('
SELECT
COUNT(*)
FROM
stories
WHERE
stories.category = \''.$search.'\'
')
->fetchColumn();
Also, you can't do this...
');
->fetchColumn();
You are terminating with semi colon, then trying to invoke an object method.

Error: Join in MySql, PHP

I have two tables in mysql one is quote and the fields are quote_id, status, created and submit_by. in submit_by field i am saving username of the employee and in employee table the fields are firs_name, last_name, username, password. I want to show in a php table the employee first name instead of username of the employee.
full quote table stucture
full employee table sructure
this is the code i am using but not getting any result
$sql = "SELECT q.quote_id, q.client_name, q.status, e.first_name
FROM `quote` AS q
LEFT JOIN `employee` AS e ON q.submit_by = e.username";
Use this one
$sql = "SELECT * , employee.first_name FROM quote
LEFT JOIN employee ON quote.submit_by = employee.username ORDER BY quote.client_name";
$result = $dbLink->query($sql);
try this:
SELECT quote.quote_id, quote.client_name, quote.status, employee.first_name FROM quote
LEFT JOIN employee ON quote.submit_by = employee.username ORDER BY quote.client_name;
You can use below Query to get the result.
SELECT q.`quote_id`, q.`client_name`, q.`status`, e.`first_name` FROM `quote` q , `employee` e WHERE q.`submit_by` = e.`username`;

$_GET for MySQL query causing Unknown column error

I have a series of links that pass information to a new page to run a MySQL query. This is one of the links from source code:
<a class="bloglink" href="parknews.php?tpf_news.park_id=5">
and this is the code that generates the links:
<a class="bloglink" href="parknews.php?tpf_news.park_id=<?php echo $row2['park_id'];?>">
<?php echo $row2['name']; ?>
</a>
The query that uses that info is here:
$park_id = $_GET['tpf_news.park_id'];
$sql = 'SELECT headline, story, DATE_FORMAT(date, "%d-%M-%Y") AS date, name
FROM tpf_news
INNER JOIN tpf_parks ON tpf_news.park_id = tpf_parks.park_id WHERE tpf_news.park_id = $park_id ORDER BY date DESC' ;
This causes this error to display:
Error fetching news: SQLSTATE[42S22]: Column not found: 1054 Unknown column '$park_id' in 'where clause'
I can't work out why it is not working. If in the query I replace WHERE tpf_news.park_id = $park_id with WHERE tpf_news.park_id = 6 (or any other number), it works fine.
Any ideas?
When your strings are in quotes your variables aren't interpolated. So you need to use double quotes instead:
$sql = "SELECT headline, story, DATE_FORMAT(date, '%d-%M-%Y') AS date, name
FROM tpf_news
INNER JOIN tpf_parks ON tpf_news.park_id = tpf_parks.park_id WHERE tpf_news.park_id = $park_id ORDER BY date DESC" ;
Or use concatenation:
$sql = 'SELECT headline, story, DATE_FORMAT(date, "%d-%M-%Y") AS date, name
FROM tpf_news
INNER JOIN tpf_parks ON tpf_news.park_id = tpf_parks.park_id WHERE tpf_news.park_id =' . $park_id .' ORDER BY date DESC' ;
FYI, you also wide open to SQL injections
You have your SQL in single quotes. That means the variable will not be displayed as you think. Use double quotes.
And for the love of GOD us prepared statements.
$sql = "SELECT headline, story, DATE_FORMAT(date, "%d-%M-%Y") AS date, name
FROM tpf_news
INNER JOIN tpf_parks ON tpf_news.park_id = tpf_parks.park_id WHERE tpf_news.park_id=$park_id ORDER BY date DESC" ;
$sql = 'SELECT headline, story, DATE_FORMAT(date, "%d-%M-%Y") AS date, name
FROM tpf_news
INNER JOIN tpf_parks ON tpf_news.park_id = tpf_parks.park_id WHERE tpf_news.park_id='.$park_id.' ORDER BY date DESC' ;

Concatinating several values into one row works in MySQL console but not in PHP

When I try to run the following code in the MySQL console it gives me a valid output that is correct:
SELECT * , GROUP_CONCAT( phonenr
SEPARATOR ', ' )
FROM employee AS e
JOIN phonenr AS p ON p.ssn = e.ssn GROUP BY e.ssn
When I run the same code in PHP:
$result = mysql_query(
'SELECT * , GROUP_CONCAT(phonenr
SEPARATOR ', ' )
FROM employee AS e JOIN phonenr AS p ON p.ssn = e.ssn GROUP BY e.ssn');
I get the following error when I launch the website:
Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in C:\AppServ\www\test.php on line 17
Could not query:
Have no clue why PHP rejects this.
It's a quote issue. You're wrapping your query in single quotes which conflicts with the single quotes you use in the GROUP_CONCAT function.
$result = mysql_query(
"SELECT * , GROUP_CONCAT(phonenr
SEPARATOR ', ' )
FROM employee AS e JOIN phonenr AS p ON p.ssn = e.ssn GROUP BY e.ssn");

Categories