SQL UNION 2 SELECT on same table - php

I have 2 SELECT on the same table "contratto"; in php (and mysql) I do it as:
$sql_1=" SELECT * FROM contratto WHERE id_cliente='2' " ;
$sql_2=" SELECT * FROM contratto JOIN cliente ON contratto.id_cliente=cliente.id WHERE cliente.id_rivenditore = '2' " ;
$sql= "(" . $sql_1 . ") UNION ALL (" . $sql_2 .") ; ";
mysqli_query($connect, $sql);
while($row = mysqli_fetch_assoc($risultato_query)) { ..... }
The 2 SQL query $sql_1 and $sql_2 separately work fine.
The query $sql (union of $sql_1 and $sql_2) doesn't work, that is:
( SELECT * FROM contratto WHERE id_cliente=’2′ ) UNION ALL ( SELECT * FROM contratto JOIN cliente ON contratto.id_cliente=cliente.id WHERE cliente.id_rivenditore = ‘2’ ) ;
I get the error "mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in ..."
What is wrong?

At least one error is coming from the union. All subqueries in the union need to have the same columns, so select * is not appropriate (especially in this case).
Another error comes from PHP, because you are not checking for errors from SQL. If you did, you would see the error message from the database.

Related

Problem trying to join two mysql queries from two different tables in one php function

the problem it presents is the moment of executing the queries, only I am executing the query of the table example2 and not the query of the table example1.
$query = " SELECT a.id, a.name
FROM example1 a
";
$query .= " UNION ";
$query = " SELECT a.id,a.name
FROM example2 a
";
$query .= " WHERE 1 = 1 ";
I believe you're issue stems from the alias you're applying to the tables:
FROM example1 a and FROM example2 a
You'll likely want these aliases to be different as they represent different tables, try something like this instead:
SELECT e1.id, e1.name
FROM example1 e1
UNION
SELECT e2.id, e2.name
FROM example2 e2
WHERE 1=1
EDIT:
It seems as though the original code was missing a .= and was instead just an =.
The updated code would be:
$query = "SELECT e1.id, e1.name FROM example1 e1";
$query .= " UNION ";
$query .= " SELECT e2.id, e2.name FROM example2 e2"; // (.= was missing here)
$query .= " WHERE 1 = 1 ";

Comparison in PHP SELECT statement with multi-row array as comparing variable [duplicate]

This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed last year.
I have a query to group by id, sum, and then rank. The issue is that the table contains all classes and doesn't have a column to define the class of each data.
Therefore, I have to use another table to get the id's that are in the same class as the id being ranked and then compare them.
Here is the code that I have already tried but results to errors:
$que = "SELECT * FROM registration WHERE CurrentClass = (SELECT CurrentClass FROM registration WHERE AdmNo = '$user_id')";
$statemen = $connect->prepare($que);
$statemen->execute();
$res = $statemen->fetchAll();
foreach($res as $rowww) {
$resu1 = mysqli_query($conn, "SELECT AdmNo, rank, total_score
FROM (SELECT * WHERE AdmNo = '".$rowww['AdmNo']."', IF(#marks=(#marks:=total_score), #auto, #auto:=#auto+1) AS rank
FROM (SELECT * FROM
(SELECT AdmNo, SUM(Score) AS total_score
FROM `{$examination}`,
(SELECT #auto:=0, #marks:=0) as init
GROUP BY AdmNo) sub ORDER BY total_score DESC)t) as result
WHERE AdmNo = '$user_id'");
$row1 = mysqli_fetch_assoc($resu1);
$sum = $row1['total_score'];
$position = $row1['rank'];
$totalMarks = round($sum, 2);
}
To my understanding, the error
Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, bool given in E:\xampp\htdocs\user...
Is because of the multi-row returned in the first query and that's why I need help with how I can solve this problem.
The required result are that the AdmNo's selected from registration are the only one that should be used in ranking.
Try this:
$query = "SELECT AdmNo, rank, total_score FROM (
SELECT * WHERE AdmNo = '" . $rowww['AdmNo'] . "', IF(#marks=(#marks:=total_score), #auto, #auto:=#auto+1) AS rank FROM (
SELECT * FROM (
SELECT AdmNo, SUM(Score) AS total_score FROM `" . $examination . "`, (
SELECT #auto:=0, #marks:=0
) as init GROUP BY AdmNo
) sub ORDER BY total_score DESC
) t
) as result WHERE AdmNo = '" . $user_id . "'";
$resu1 = mysqli_query($conn, $query);

generate 100 10-digit random numbers and save to database

This is a pretty simple function yet it keeps giving me errors. Im writing a script to generate 100 10-digit random numbers but I keep having this error: "check the manual that corresponds to your MySQL server version for the right syntax to use near 'rand(1111111111, 9999999999)' at line 1.
This is my code
<?php
$cxn = new mysqli("localhost", "CJroot", "password", "random");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
for ($i=0; $i < 100; $i++) {
$sql = "INSERT INTO random (random) VALUES 'rand(1111111111, 9999999999)'";
if(!mysqli_query($cxn,$sql)) {
die("Error: ".mysqli_error($cxn));
}
}
/* close connection */
$cxn->close();
?>
you need to concat your string like so.
$sql = "INSERT INTO random (random) VALUES '" . rand(1111111111, 9999999999) . "'";
The syntax error that MySQL is complaining about (in your SQL statement) is missing parens around the values list. This is invalid:
INSERT INTO ... VALUES 'foo'
Should be
INSERT INTO ... VALUES ( 'foo' )
^ ^
Once you get over that hump, the value enclosed in single quotes is interpreted as a string literal. In the example code, 'rand(11111,99999)' is a literal, a string of characters. It's not a reference to a function.
If we want to use the MySQL RAND() function, we could do something like this:
INSERT INTO random (random) VALUES ( FLOOR(1000000000 + RAND() * 9000000000) )
We can execute that 100 times, or, it would be more efficient to write SELECT statement that returns 100 rows, and insert 100 rows in a single insert.
Or:
INSERT INTO random (random) VALUES
( FLOOR(1000000000 + RAND() * 9000000000) )
,( FLOOR(1000000000 + RAND() * 9000000000) )
,( FLOOR(1000000000 + RAND() * 9000000000) )
, ...
,( FLOOR(1000000000 + RAND() * 9000000000) )
In terms of database performance, it is usually more efficient to run a single INSERT statement that inserts 100 rows, than it is to execute 100 individual insert statements. Processing RBAR (row by agonizing row) can be excruciatingly slow.
If there's a need for a loop, if we insert four rows at time, we need only need to go through the loop 25 times. And that's 75% fewer statements we need to execute.
We can specify the SQL text to be executed just one time, outside of the loop, and then just repeatedly execute that same SQL
$sql = "INSERT INTO random (random) VALUES"
. " ( FLOOR(1000000000 + RAND() * 9000000000) )"
. ",( FLOOR(1000000000 + RAND() * 9000000000) )"
. ",( FLOOR(1000000000 + RAND() * 9000000000) )"
. ",( FLOOR(1000000000 + RAND() * 9000000000) )";
for ($i=0; $i < 25; $i++) {
if(!mysqli_query($cxn,$sql)) {
die("Error: ".mysqli_error($cxn));
}
}
you can also do it direct with MySQL like this:
INSERT INTO random (random)
SELECT CAST( (RAND()*(9999999999-1111111111)) AS UNSIGNED) + 1111111111;
or for 100 rows:
INSERT INTO random (random)
SELECT CAST( (RAND()*(9999999999-1111111111)) AS UNSIGNED) + 1111111111 AS random FROM (
SELECT 0 AS h UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) h
CROSS JOIN
( SELECT 0 AS l UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) l;
This works fine
<?php
$cxn = new mysqli("localhost", "CJroot", "password", "random");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$sql = "INSERT INTO random (random) VALUES"
. " ( FLOOR(1000000000 + RAND() * 9000000000) )"
. ",( FLOOR(1000000000 + RAND() * 9000000000) )"
. ",( FLOOR(1000000000 + RAND() * 9000000000) )"
. ",( FLOOR(1000000000 + RAND() * 9000000000) )";
for ($i=0; $i < 25; $i++) {
if(!mysqli_query($cxn,$sql)) {
die("Error: ".mysqli_error($cxn));
}
}
$cxn->close();
?>

UNION SELECT to get ID's from news and page (A database error occurred: Every derived table must have its own alias)

I'm trying to get the ID's of found items via a custom query. To avoid double results because of searching in 2 tables I understood that I should use UNION.
I wrote this little query:
SELECT * FROM( SELECT `news_item`.`id` as nId, `news_item`.`title`, `news_item`.`content` FROM `news_item` ni UNION SELECT `page_item`.`id` as pId, `page_item`.`title`, `page_item`.`content` FROM `page_item` pi ) WHERE `news_item`.`title` LIKE '%serious%' OR `news_item`.`content` LIKE '%serious%' OR `page_item`.`title` LIKE '%serious%' OR `page_item`.`content` LIKE '%serious%' LIMIT 0, 4
Which results in an SQL error: A database error occurred: Every derived table must have its own alias
I've tried using aliasses(As ni and pi. Also for the select values(ie. ni.title).) and tried without aliases, to no avail.
Here's the PHP:
$searchTerms = array();
foreach($searchWords as $word){
$searchTerms[] = "`news_item`.`title` LIKE '".$word."'";
$searchTerms[] = "`news_item`.`content` LIKE '".$word."'";
$searchTerms[] = "`page_item`.`title` LIKE '".$word."'";
$searchTerms[] = "`page_item`.`content` LIKE '".$word."'";
}
$newsAndPageItemsQry = "
SELECT
*
FROM(
SELECT `news_item`.`id` as nId, `news_item`.`title`, `news_item`.`content` FROM `news_item` ni
UNION
SELECT `page_item`.`id` as pId, `page_item`.`title`, `page_item`.`content` FROM `page_item` pi
)
WHERE
" . implode(" OR ", $searchTerms) . "
LIMIT
" . $scope;
Instant edit: When I give the initial FROM an alias I get the database error: A database error occurred: Unknown column 'news_item.id' in 'field list'. It exists. Definitely.
My question basically: How can I search in page_item and news_item to get the ID's for my keywords in title and content without getting duplicate results?
You say:
Unknown column 'news_item.id' in 'field list'. It exists. Definitely.
But it is not true. Your columns are nId, title and content:
SELECT
`news_item`.`id` as nId, #nId
`news_item`.`title`, #title
`news_item`.`content` #content
FROM `news_item` ni
You should create an alias for subquery:
SELECT
*
FROM(
SELECT `news_item`.`id` as nId, `news_item`.`title`, news_-...
UNION
SELECT `page_item`.`id` as pId, `page_item`.`title`, page_it...
) T <---- here!!!
WHERE
" . implode(" OR ", $searchTerms) . "
LIMIT
" . $scope
Use alias name rather than news_item
Like myAlias.nId=123 or myAlias.title like '%word%'

MySQL query to select specific data

I would like to display the data that belongs to any of my users when they login to the site, as well as the name of each table (they completed offers on them).
This is the code I used, but when I add it it's not working.
$result = mysql_query('SELECT *,\'tbl1\' AS tablename FROM (SELECT * FROM table1 WHERE user_id='$user_id') as tbl1 UNION SELECT *,\'tbl2\' AS tablename FROM (SELECT * FROM table1 WHERE user_id='$user_id') as tbl2'. ' ORDER BY `date` DESC');
while($sdata = mysql_fetch_array($result)){
echo $sdata['date'];
echo $sdata['tablename'];
echo $sdata['user_reward'];
}
Where did I make a mistake?
You are missing the concatenation operators here, around $user_id:
$result = mysql_query(
'SELECT *,\'tbl1\' AS tablename FROM (
SELECT * FROM table1 WHERE user_id=' . $user_id . '
) as tbl1
UNION
SELECT *,\'tbl2\' AS tablename FROM (
SELECT * FROM table1 WHERE user_id=' . $user_id . '
) as tbl2' . ' ORDER BY `date` DESC'
);
I've wrapped the call for more clarity - I suggest you do the same in your own code. I'd be inclined to use " marks here instead, so you don't need to escape apostrophes.
The ORDER BY clause seems to be redundantly concatenated as well - remove the dot and add this part of the query to the as tbl2 part.
Here's how I would do it:
$sql = "
SELECT *, 'tbl1' AS tablename FROM (
SELECT * FROM table1 WHERE user_id={$user_id}
) as tbl1
UNION
SELECT *, 'tbl2' AS tablename FROM (
SELECT * FROM table1 WHERE user_id={$user_id}
) as tbl2
ORDER BY `date` DESC
";
$result = mysql_query($sql);
Make sure that $user_id is properly escaped or cast, to avoid security problems. Also, this database library is no longer recommended, and will be removed in a future version of PHP. It would be better to move to PDO or mysqli, and use parameterisation.
Finally, it does rather look like the query itself is rather cumbersome - it looks like it could be simplified. Perhaps ask a separate question on that?

Categories