I tried to execute the query, but the result was null, I executed the same query in PhpMyAdmin and returns the result.
The problem is when the query contains SELECT inside another SELECT statement (imbricate), so when the query contains only one SELECT statement, it works fine and returns the result. Here is the code:
db_config.php
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "university_db";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
get_planning.php
<?php
require 'db_config.php';
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT cours.jour,
TIME_FORMAT(cours.heure_debut, '%H:%i') AS debut,
TIME_FORMAT(cours.heure_fin, '%H:%i') AS fin,
enseignant.nom_ens as prof, modules.nom_mod as module, salles.nom_salle as salle
FROM cours, promotion, enseignant, modules, salles
WHERE cours.id_promo = (SELECT id_promo FROM promotion WHERE promotion.niveau = '2'
AND promotion.id_speci = (SELECT id_speci FROM spécialité WHERE nom_speci = 'MGL'))
AND cours.id_promo = promotion.id_promo AND cours.id_ens = enseignant.id_ens AND cours.id_salle = salles.id_salle AND cours.id_mod = modules.id_mod
ORDER BY cours.id_cours;";
$result = $conn->query($sql);
if($result == null)
echo "Result is empty!";
Output:
Result is empty!
Information:
PHP: Version 7.3.5
Database: MySQL
Three suggestions for troubleshooting this problem:
Change your cours.id_promo = (SELECT ... to cours.id_promo IN (SELECT... and do the same to the line after it. Why? if you use = and the inner select statement returns more than one result, boom. Query fails. SQL is, at its heart, a set-processing language, and this IN that checks that this is a member of the set that.
echo your $sql value to make sure the statement in it is correct. Try running the exact statement via phpmyadmin to make sure it gives you what you expect.
You have this
if($result == null)
echo "Result is empty!";
Change it to this
if(!$result)
echo 'sql failure:', $conn->error, ': ', $sql;
The query() method only returns a falsey result if the query failed. If it succeeds but finds no matching rows, query() returns an empty result set. So anytime your $result is falsey, you made a programming error in your query. The echo I mentioned will diagnose it for you.
Pro tip Always check SQL operations for errors.
Pro tip 2. Bring your SQL skills into the 21st century. Use explicit join operations rather than old-timey comma-join operations. Change ...
SELECT cours.jour, whatever, whatever
FROM cours
JOIN promotion ON cours.id_promo = promotion.id_promo
JOIN enseignant ON cours.id_ens = enseignant.id_en
JOIN modules ON cours.id_mod = modules.id_mod
JOIN salles ON cours.id_salle = salles.id_salle
WHERE cours.id_promo IN (SELECT id_promo FROM promotion WHERE promotion.niveau = '2')
AND promotion.id_speci IN (SELECT id_speci FROM spécialité WHERE nom_speci = 'MGL')
ORDER BY cours.id_cours
The relationships between your tables are much easier to read and understand this way. And, you can change JOIN to LEFT JOIN if your application requires it.
Just a suggestion.
Instead of nested old implicit join syntax based list table, where clause and nested sub-query should use explicit join syntax.
SELECT cours.jour
, TIME_FORMAT(cours.heure_debut, '%H:%i') AS debut
, TIME_FORMAT(cours.heure_fin, '%H:%i') AS fin
, enseignant.nom_ens as prof
, modules.nom_mod as module
, salles.nom_salle as salle
FROM cours
INNER JOIN promotion ON cours.id_promo = promotion.id_promo
AND promotion.niveau = '2'
INNER JOIN enseignant ON cours.id_ens = enseignant.id_ens
INNER JOIN modules cours.id_mod = modules.id_mod
INNER JOIN salles ON cours.id_salle = salles.id_salle
ORDER BY cours.id_cours;
Related
I've the following query executed via PHP, it used to work like yesterday, and stopped working today, here's it :
SELECT
*,
(SELECT IF (pro.uid= '4342','True','False') FROM pro) AS 'uid'
FROM
Episodes, pro
ORDER BY
Episodes.id DESC
LIMIT 9
The '4342' is changed with GET param, I'm having the following error :
Commands out of sync; you can't run this command now
My PHP API is as the following ( snippets ) :
<?php
include_once "db_config.php";
DEFINE ('DB_HOST', $host);
DEFINE ('DB_USER', $user);
DEFINE ('DB_PASSWORD', $pass);
DEFINE ('DB_NAME', $database);
$mysqli = #($GLOBALS["___mysqli_ston"] = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD)) OR die ('Could not connect to MySQL');
#((bool)mysqli_query($GLOBALS["___mysqli_ston"], "USE " . constant('DB_NAME'))) OR die ('Could not select the database');
?>
<?php
if(isset($_GET['meaE'], $_GET['uid']))
{
$query="SELECT * , (SELECT IF (pro.uid= '".$_GET['uid']."','True','False') FROM pro ) AS 'uid' FROM Episodes,pro ORDER BY Episodes.id DESC LIMIT 9
";
$resouter = mysqli_query($GLOBALS["___mysqli_ston"], $query);
}
$set = array();
$total_records = mysqli_num_rows($resouter);
if($total_records >= 1){
while ($link = mysqli_fetch_array($resouter, MYSQLI_ASSOC)){
$set['APITest'][] = $link;
}
}
echo $val= str_replace('\\/', '/', json_encode($set));
?>
I want to have the following output :
TABLE A - TABLE B
ID NAME TEXT UID - Check_ID
The query I want :
Select * From Table A, Check if "134123123" is exists in B, if yes / no add a record for all the taken records from Table A with the value of checking (True/False) .
What's happening with #sagi query is :
There are 3 records in Table B, and 10 records in Table A, when the query is executed, the result is 30 records, each record in Table B has 10 records from Table A, and the "uid" record value is True where the uid is '134123123', and it's false where it's not '134123123' .
Your query seems wrong, I don't know how it worked yesterday, but right now your are cross joining with out a condition (could be correct but I doubt it) - that means each record in episodes will be joined to each record in pro . In addition, your subquery with the IF will return more then 1 record unless this table contains only 1 record (which again - I doubt it) .
Try this:
SELECT distinct t.*, IF (s.uid is null,'True','False') AS 'uid'
FROM Episodes t
Left JOIN pro s
ON(s.uid = '4342')
ORDER BY t.id DESC
LIMIT ?????
Try using a sub query instead of a join:
Select t.*,
Case when exists(select 1 from pro s where s.uid = '4342')
Then 'true' else 'false'
End as 'uid'
From episodes t
Order by t.id desc
Limit 9;
<?php
$hostdb = "localhost";
$userdb = "root";
$passdb = "";
$namedb = "dctdb3";
$dbhandle = new mysqli($hostdb, $userdb, $passdb, $namedb);
if ($dbhandle->connect_error) {
exit("There was an error with your connection: ".$dbhandle->connect_error);
}
$query = "SELECT msdnd_oct.id as id1, msakl_oct.id as id2, msdnd_oct.sold as sold1, msakl_oct.sold as sold2, msdnd_oct.sales as sales1, msakl_oct.sales as sales2 FROM msdnd_oct inner join msakl_oct ON msakl_oct.id=msdnd_oct.id";
?>
The code above is the only thing I have found from searches but it's not what i'm looking for.
Hi there I have been searching for awhile but cannot find what I'm looking for.
I have two tables named "msdnd_oct" and "msakl_oct".
They are both basically monthly summaries.
I want to make a comparison between the two tables. Display both tables together. So that I can see which table has more 'sold' items. So for example, if the table 'msdnd_oct' has 40 'sold' and 'msakl_oct' has 39. I can see that dnd has more.
The three rows that I want to display is 'id', 'sold' and 'sales'
Thank you for your help!
If I understood you correctly, you want something like this.
"SELECT
msdnd_oct.id as id1,
msakl_oct.id as id2,
msdnd_oct.sold as sold1,
msakl_oct.sold as sold2,
msdnd_oct.sales as sales1,
msakl_oct.sales as sales2
FROM msdnd_oct inner join msakl_oct ON msakl_oct.id=msdnd_oct.id"
If you want to compare total sales, or sold items you can use GROUP BY
Or If you simply want to combine to tables without joining them you can use UNION
You can execute above query in php as below
$query = "SELECT
msdnd_oct.id as id1,
msakl_oct.id as id2,
msdnd_oct.sold as sold1,
msakl_oct.sold as sold2,
msdnd_oct.sales as sales1,
msakl_oct.sales as sales2
FROM msdnd_oct inner join msakl_oct ON msakl_oct.id=msdnd_oct.id";
$result = mysqli_query($dbhandle,$query);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "id1: " . $row["id"]. " - id2: " . $row["id2"]. " <br>";
}
} else {
echo "0 results";
}
$conn->close();
I encourage you learn much more about connecting to Mysql, retrieving data from Mysql with PHP. Take a look at below links. Then you will get the clear idea of how to do your given task.
Learn about Php & Mysql
Learn about GROUP BY statement
Learn ab obout UNION operator
Honestly I have no idea how to do what I am trying to do. I am not overly experienced in php nor in Mysql but I am trying and could use some help, preferably with working example code.
Problem: I have 3 tables
members
customfields
customvals
members contains:
membername | Id
customfields contains:
rank | name
customvals contains
fieldid | userid | fieldvalue
Table columns match at
customvals.userid=members.id
customvals.fieldid=members.rank
What I need to do is match the data so that when page.php?user=membername is called it displays on the page
Table1.membername:<br>
Table2.name[0] - Table3.fieldvalue[0]<br>
Table2.name[1] - Table3.fieldvalue[1]<br>
etc...
(obviously displaying only the information for the said membername)
The more working the code, the more helpful it is for me. Please don't just post the inner join statements. Also it is most helpful to me if you could explain how and why your solution works
So far here is what I have for code:
$profileinfocall = "SELECT Table1.`membername`, Table2.`name`, Table3.`fieldvalue`
FROM members AS Table1
LEFT JOIN customvals AS Table3 ON Table1.`id` = Table3.`userid`
LEFT JOIN customfields AS Table2 ON Table3.`fieldid` = Table2.`rank`
WHERE Table1.`membername` = $username;";
$membercall = "SELECT * FROM members WHERE membername=$username";
$profileinfo = mysql_query($profileinfocall, $membercall);
while($row = mysql_fetch_array($profileinfo)) {
echo $row['membername'];
}
Obviously this doesn't work as I get the following errors:
Warning: mysql_query() expects parameter 2 to be resource, string given on line 534.
Warning: mysql_fetch_array() expects parameter 1 to be resource, null given in on line 535
While this is a very broad question and you have not provided any PHP code, you might want to break it down into various sections:
Establishing a connection to the database (with mysqli) and sending a query:
$c = mysqli_connect("localhost","user","password","db");
if (mysqli_connect_errno())
echo "Failed to connect to MySQL: " . mysqli_connect_error();
else {
$result = mysqli_query($c,"SELECT * FROM members");
while($row = mysqli_fetch_assoc($result)) {
echo "{$row['membername']}";
}
}
mysqli_close($c);
Tieing your tables together:
It is better to start off with a clear structure (including line breaks) when getting into the MySQL syntax. One way would be to have some sort of query skeleton:
SELECT tablealias.column, table2alias.field3
FROM table AS tablealias
LEFT|RIGHT|INNER JOIN table2 AS table2alias ON table.id=table2.id
WHERE (this and that = true or false, LIKE and so on...)
Breaking it down to your specific problem this would be:
SELECT Table1.`membername`, Table2.`name`, Table3.`fieldvalue`
FROM members AS Table1
LEFT JOIN customvals AS Table3 ON Table1.`id` = Table3.`userid`
LEFT JOIN customfields AS Table2 ON Table3.`fieldid` = Table2.`rank`
WHERE Table1.`Id` = 'UserID to be searched for'
Improvements & Security measures:
But there is even more to it than meets the eye. If you have just begun, you might as well dive directly into prepared mysqli- statements. Given the query to get your members, the only changing part is the ID. This can be used for a prepared statement which is much more secure than our first query (though not as fast). Consider the following code:
$sql = "SELECT Table1.`membername`, Table2.`name`, Table3.`fieldvalue`
FROM members AS Table1
LEFT JOIN customvals AS Table3 ON Table1.`id` = Table3.`userid`
LEFT JOIN customfields AS Table2 ON Table3.`fieldid` = Table2.`rank`
WHERE (Table1.`Id` = ?)";
$c = mysqli_connect("localhost","user","password","db");
$stmt = $c->stmt_init();
if ($stmt->prepare($sql)) {
$stmt->bind_params("i", $userid);
$stmt->execute();
while ($stmt->fetch()) {
//do stuff with the data
}
$stmt->close();
}
$mysqli->close();
This SQL query should do it:
SELECT a.membername, a.Id, b.fieldid, b.userid, b.fieldvalue, c.rank, c.name
FROM members AS a
LEFT JOIN customvals AS b ON a.id = b.userid
LEFT JOIN customfields AS c ON b.rank = c.fieldid
WHERE a.Id = #MEMBERIDHERE#;
I have a query with multiple joins in it. After I take the results and run it through a Id-checker I want to be able to delete records from that array where the IDDestination equals $ID.
Since this query has joins on it and I am filtering them based on one of the joined tables, How do I go about deleting those records from the array based off that joined table?
And I only wanted this to happen after the user confirms.
$query = "
select d.IDCourse,
d.name as course_name,
d.slug,
d.short_description,
d.address,
e.city_name,
e.state_code,
d.zip,
e.city_slug,
e.state_slug,
h.IDDestination,
LOWER(e.iso_code) as country_slug, a.*,
b.IDTeetimeType,
c.name as teetime_type,
b.start_time,b.end_time,
(case dayofweek(a.teetime_dt)
when 1 then `b`.`sun`
when 2 then `b`.`mon`
when 3 then `b`.`tue`
when 4 then `b`.`wed`
when 5 then `b`.`thu`
when 6 then `b`.`fri`
when 7 then `b`.`sat`
end) AS `price`, g.tax_rate, f.alias
from cart_course_teetimes a
join course_priceplan b
on a.IDCoursePricePlan = b.IDCoursePricePlan
join course_teetime_type c
on b.IDTeetimeType = c.IDTeetimeType
join course d
on b.IDCourse = d.IDCourse
join vw_cities e
on d.IDCity = e.IDCity
join destinations_cities h
on h.IDCity= d.IDCity
LEFT JOIN (SELECT * FROM media_mapping WHERE is_main_item=1 AND IDGalleryType=3) f
ON d.IDGallery = f.IDGallery
left join course_tax
g on a.IDCourseTax = g.IDCourseTax
where a.IDCart = :cart_id
order by d.name, a.teetime_dt, b.start_time;";
$prepared = array(
"cart_id" => $idCart,
);
$conn = new DBConnection();
$results = $conn->fetch($query, $prepared);
$conn = null;
$results = !empty($results) ? $results : array();
$id = null;
foreach($results as $row) {
// Set ID for the first record.
if($id === null)
$id = $row['IDDestination'];
// will stay true, otherwise it's false and we should kill the loop.
if($id != $row['IDDestination']) {
$newid=$row['IDDestination'];
echo "<script type='text/javascript'> emptycart();</script>";
$query = "DELETE FROM cart_course_teetimes a WHERE h.IDDestination='.$id.'";
$res =mysql_query($query) or die (mysql_error());
break;
}
}
This is incorrect PHP:
$query = "DELETE FROM cart_course_teetimes a WHERE h.IDDestination='.$id.'"
You're already inside a "-quoted string, so . PHP concatenation operators aren't operators, they're just a period.
You want either of these instead:
$query = "DELETE FROM cart_course_teetimes a WHERE h.IDDestination='" . $id . "'";
$query = "DELETE FROM cart_course_teetimes a WHERE h.IDDestination='$id'"
Right now you're producing
... WHERE h.IDDestination = .42.
which is not valid SQL.
Plus it appears you're mixing database libraries. You've got $conn->fetch() which implies you're using one of the OO db libraries (mysqli? pdo? custom wrapper?). But you then call mysql_query(). Unless you've EXPLICITLY called mysql_connect(), that delete query will never execute. Database connections made in one of the libraries are utterly useless in any of the other libraries.
I apply the same 2 queries to 3 tables, so just loop round and substitute the table names. The first INSERT query always works on test servers and on production. The second DELETE query works on two different test servers but is failing on production and throwing mysql error 1046 No database selected.
Affected code extract:
$queries = array(
"INSERT INTO knd_bkg.#table#
SELECT DISTINCT SQL_NO_CACHE
B.ASIN, Author, Title, EditorialReview, DetailPageURL, current_price, salesrank, number_reviews, erotica, G.BrowseNodeId, price_salesrank_checked_on
FROM bkd_books.club_books B
USE INDEX (free_quality)
RIGHT JOIN bkd_books.book_genre G on G.ASIN=B.ASIN
WHERE EXISTS
(
SELECT 1 FROM knd_bkg.genres K WHERE K.browsenode=G.BrowseNodeId
)
AND #priceWhere#
AND price_salesrank_checked_on > '#newerThan#'
AND B.number_reviews >= 4
AND B.rating >= 4.0
AND B.language = 'english'
AND B.hide_knd=0
AND B.public_domain=0;",
"DELETE T FROM knd_bkg.#table# T
INNER JOIN
(
SELECT N.* FROM knd_bkg.#table# N
INNER JOIN
(
SELECT DISTINCT ASIN, BrowseNodeId FROM knd_bkg.#table#
INNER JOIN knd_bkg.genres ON knd_bkg.genres.browsenode=knd_bkg.#table#.BrowseNodeId
WHERE isFiction=1
) F
ON F.ASIN=N.ASIN
INNER JOIN knd_bkg.genres
ON knd_bkg.genres.browsenode=N.BrowseNodeId
WHERE knd_bkg.genres.isNonFiction=1
) D
USING (ASIN, BrowseNodeId)
WHERE D.ASIN=T.ASIN AND D.BrowseNodeId=T.BrowseNodeId"
);
$tables = array(
"free_books" => array('priceWhere' => "B.current_price = 0", 'timePeriod' => $freeTimePeriod),
"99_books" => array('priceWhere' => "B.current_price > 0 AND B.current_price < 100", 'timePeriod' => $paidTimePeriod),
"399_books" => array('priceWhere' => "B.current_price >= 100 AND B.current_price < 400", 'timePeriod' => $paidTimePeriod),
);
connectSlaveDB();
foreach ($tables as $table => $data) {
$newerThan = date("Y-m-d H:i:s", strtotime("-" . $data['timePeriod'] . " hours"));
foreach ($queries as $query) {
$query = str_replace('#table#', $table, $query);
$query = str_replace('#newerThan#', $newerThan, $query);
$query = str_replace('#priceWhere#', $data['priceWhere'], $query);
Logger::_write(LOG_VERBOSE, "API - api/bkg/rebuild query: $query");
$result = mysql_query($query);
if (!$result) {
Logger::_write(LOG_ERR, "API - api/bkg/rebuild FAILED: " . mysql_error());
$success = false;
} else {
Logger::_write(LOG_VERBOSE, "API - api/bkg/rebuild SUCCESS");
}
}
}
And connectSlaveDB()
function connectSlaveDB()
{
global $dbSlave, $dbUser, $dbPass, $dbName;
$connSlave = mysql_connect($dbSlave, $dbUser, $dbPass, TRUE);
if (!$connSlave) {
Logger::_write(LOG_CRIT, "Unable to connect to slave DB");
include 'screens/error.inc.php';
exit();
}
mysql_set_charset('utf8', $connSlave);
mysql_select_db($dbName, $connSlave);
return TRUE;
}
The tables are MEMORY tables, but I get the same error with MYISAM, and only on production. This query is running on a replication slave and does not involve the master, but previous code TRUNCATES the tables so I don't believe it is down to permissions. When the query is taken out of the log file, it works fine in phpMyAdmin. And it's fine on the test servers.
I don't get the reason for the 1046 No database selected error. And after 3 hours I might be missing something really obvious. Especially as the failure pattern is like this, for one DB connection:
INSERT on free_books - success
DELETE on free_books - fail
INSERT on 99_books - success
DELETE on 99_books - fail
INSERT on 399_books - success
DELETE on 399_books - fail
Please excuse ugly globals and deprecated mysql* functions. This is a legacy app that is rather out of date. I know...
The syntax of your DELETE query may be causing the problem
DELETE T FROM
I know this has caused issues with UPDATE queries sometimes before due to a mysql bug.
Re-writing your query to avoid the T reference should resolve this issue.
Looks like the T alias in the DELETE was causing problems, but I'm not quiet sure why. The problem is now fixed by making the DELETE query to be:
"DELETE knd_bkg.#table# FROM knd_bkg.#table#
INNER JOIN
(
SELECT N.* FROM knd_bkg.#table# N
INNER JOIN
(
SELECT DISTINCT ASIN, BrowseNodeId FROM knd_bkg.#table#
INNER JOIN knd_bkg.genres ON knd_bkg.genres.browsenode=knd_bkg.#table#.BrowseNodeId
WHERE isFiction=1
) F
ON F.ASIN=N.ASIN
INNER JOIN knd_bkg.genres
ON knd_bkg.genres.browsenode=N.BrowseNodeId
WHERE knd_bkg.genres.isNonFiction=1
) D
USING (ASIN, BrowseNodeId)
WHERE D.ASIN=knd_bkg.#table#.ASIN AND D.BrowseNodeId=knd_bkg.#table#.BrowseNodeId"