Merging two queries with the same binded parameter - php

I have a first SQL query getting a table with id_member as parameter
$stmt = $mysqli -> prepare("SELECT a.id_alerte,
a.nom_alerte,
ar.id_roster,
r.nom_roster,
FROM alerte a,
alerte_par_roster ar,
roster_par_membre rm
INNER JOIN roster r
ON r.id_roster = rm.id_roster
WHERE rm.id_roster = ar.id_roster
AND ar.id_alerte = a.id_alerte
AND rm.id_membre = ?");
$stmt->bind_param('i', $id_membre);
I need to insert a second query counting the number of lines in another table.
The second query is:
"SELECT COUNT(DISTINCT id_roster)
FROM disponibilites_par_member_alertes
WHERE id_member = ?
AND id_alerte = ?"
As you can notice id_member is the identical in both queries but id_alerte (used as a parameter of the second query is a result of a first query).
I hope I am clear.
Any idea will be very welcome

I don't fully understand what your queries are intended to do. It would help to have clear information on the table structure and what each of the fields represents. I've tried to make a guess based on the table names but can't be certain it's correct.
The first thing I did was just to transform your WHERE condition such that each of the tables are joined explicitly. This is just for readability.
SELECT
a.id_alerte,
a.nom_alerte,
ar.id_roster,
r.nom_roster
FROM alerte a
INNER JOIN alerte_par_roster ar
ON ar.id_alerte = a.id_alerte
INNER JOIN roster_par_membre rm
ON rm.id_roster = ar.id_roster
INNER JOIN roster r
ON r.id_roster = rm.id_roster
WHERE
rm.id_membre = ?
Now we combine with the other query:
SELECT
a.id_alerte,
a.nom_alerte,
ar.id_roster,
r.nom_roster,
rc.id_roster_count
FROM alerte a
INNER JOIN alerte_par_roster ar
ON ar.id_alerte = a.id_alerte
INNER JOIN roster_par_membre rm
ON rm.id_roster = ar.id_roster
INNER JOIN roster r
ON r.id_roster = rm.id_roster
LEFT JOIN (
SELECT id_membre, id_alerte, COUNT(DISTINCT id_roster) AS id_roster_count
FROM disponibilites_par_member_alertes
GROUP BY id_membre, id_alerte
) AS rc
ON rc.id_membre = rm.id_membre
AND rc.id_alerte = ar.id_alerte
WHERE
rm.id_membre = ?
With my own generated data I get results like this:
If this is not enough to solve the problem you will need to provide more details about the tables and the design.

Related

MySQL INNER JOIN IN not getting right result

I have this query in my php and it seems to be fetching the wrong data set from my db.
$querystring = "
SELECT a.*,
b.itemcolour,
b.itemcolourname
FROM itemorders AS a
INNER JOIN catalogueitemscolour AS b
ON a.colourid = b.colourid
WHERE a.colourid IN(SELECT colourid
FROM itemorders
WHERE orderid = 61)
";
Here is a picture of my results
Can I know why it's not selecting the specific orderID of 61?
You can try below -
SELECT a.*, b.itemColour,b.itemColourName FROM itemorders
AS a INNER JOIN CatalogueItemsColour AS b ON a.colourID = b.colourID WHERE
a.orderID = 61
Because you are not putting condition on orderID, rather putting it on colorID. What you actually want is this condition: WHERE a.orderID = 61.

Can't display query when using inner join with php?

I have a drop down menu form like so: https://ibb.co/eX5BhH
Each selected option will filter the query and return the query. So far, my "disability" and "veteran" option are querying correctly. I'm trying to get the "Type of Resource" category to work by using inner join. Here's the sql command:
SELECT shelter_name, shelter_address, disability, veteran
FROM shelter s
INNER JOIN shelter_type st ON s.shelter_id = st.shelter_id
INNER JOIN s_type stt on st.type_id = stt.type_id
WHERE type_name = "Charitable Organization";
This sql command works but it only query the resources under the "Charitable Organization" category. The user will be able to choose other category so instead of "Charitable Organization" I replace it with "$value_4":
SELECT shelter_name, shelter_address, disability, veteran
FROM shelter s
INNER JOIN shelter_type st ON s.shelter_id = st.shelter_id
INNER JOIN s_type stt on st.type_id = stt.type_id
WHERE type_name = "$value_4";
Here is my php code:
<?php
require'/Library/WebServer/Documents/Require/require.php';
$value_1 = $_POST["county"];
$value_2 = $_POST["disability"];
$value_3 = $_POST["veteran"];
$value_4 = $_POST["resources"];
$sql = "SELECT shelter_name, shelter_address, disability, veteran
FROM shelter s
INNER JOIN shelter_type st ON s.shelter_id = st.shelter_id
INNER JOIN s_type stt on st.type_id = stt.type_id
WHERE type_name = '$value_4'";
$result = mysqli_query($dbc, $sql) or die (mysql_error());
echo"<table border='1'>";
echo"<tr><td>Shelter</td><td>Address</td><td>Disability</td></tr>";
//iterate through the table
while ($row = mysqli_fetch_assoc($result)){
echo"<tr><td>{$row['shelter_name']}</td><td>{$row['shelter_address']}</td><td> {$row['disability']}</td><td>{$row['veteran']}</td></tr>";
}
echo"</table>"; //close table
echo"success";
?>
However, when I use "$value_4", the table doesn't display. If I change it back to "Charitable Organization", the table is displayed again. What can I do to make my table display when I use "$value_4"?
I think to resolve this issue you should be using LEFT JOIN rather than INNER JOIN.
Inner Joins expect data from the left table and right table to match. If it only exists in the left table but not the right then it won't show the records.
By using Left Join you are saying you want everything from the left table and then if there is information from the right table (i.e. the one you're joining on) then bring that too.
It might be worth reading this tutorial on joins to help you get more experience.

Is there a better way to get info from 2 tables

In database the users have a row called weapon_id which determines what weapon he uses from another table with weapons.
Is there a better way to get that info like join table or something?
$user_get = mysqli_query($db, "SELECT * FROM members WHERE id = '".$_SESSION['sess_id']."'");
$user = mysqli_fetch_assoc($user_get);
$weapon_get = mysqli_query($db, "SELECT * FROM weapons WHERE weapon_id = '".$user['weapon_id']."'");
$weapon = mysqli_fetch_assoc($weapon_get);
use a join like this
$user_get = mysqli_query($db, "SELECT * FROM members m LEFT JOIN weapons w ON(w.weapon_id=m.weapon_id) WHERE m.id = '".$_SESSION['sess_id']."'");
$user = mysqli_fetch_assoc($user_get);
change the join type as per your requirement. the above query for only example
INNER JOIN: Returns all rows when there is at least one match in BOTH
tables
LEFT JOIN: Return all rows from the left table, and the matched rows
from the right table
RIGHT JOIN: Return all rows from the right table, and the matched
rows from the left table
FULL JOIN: Return all rows when there is a match in ONE of the tables
more about join click here
AND also check this http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
SELECT * FROM `weapon` as w
JOIN `user` as u
on w.weapon_id = u.weapon_id
and u.id = :session_id
How about this ?

I would like to expand a SQL query to also get the name of the ID's it is selecting. How do I do that?

At the moment I have a very basic SQL query, however I would like to expand it in order to fetch the names of the ID's it is referencing as well. The problem is, it's a Parent > Child relationship table. The Parent and Children items are part of the same table, but different rows.
$GetRelations = "
SELECT RelationUID, BlockTypeUID, ChildBlockUID, Weight FROM block_type_relations
WHERE BlockTypeUID = '$BlockTypeUID'
";
When I only have a single BlockTypeUID to initially fetch the records, how can I shift this query around so that it also fetches the names from table block_types for both BlockTypeUID and ChildBlockUID? I'm writing this in mySQLi.
Assuming the name is in a column named "name", the query could look like this
$GetRelations = "
SELECT a.RelationUID, a.BlockTypeUID, a.ChildBlockUID, a.Weight
b.NAME AS BlockTypeName, c.NAME AS ChildBlockName
FROM block_type_relations a
INNER JOIN block_types b ON b.ID = a.BlockTypeUID
INNER JOIN block_types c ON c.ID = a.CildBlockUID
WHERE a.BlockTypeUID = '$BlockTypeUID'
";
$GetRelations = "SELECT btr.RelationUID, btr.BlockTypeUID, btr.ChildBlockUID,
btr.Weight,bt.Name FROM block_type_relations btr
INNER JOIN block_types bt ON bt.BlockTypeUID =btr.BlockTypeUID
WHERE BlockTypeUID = '$BlockTypeUID'";

PHP / MySQL - Confusing Query

Im trying to construct a query that goes over 3 tables and im COMPLETELY stumped ... my knowledge limit is basic 1 table query and i need some help before i stick my head in a blender.
I have the following query
SELECT * FROM internalrole WHERE introle = $imarole
Im fine with that part .. its the next thats getting me all stressed.
That query returns the following columns ( id, user_id, introle, proven, used )
What i then need to do is take the user_id from the results returned and use it to get the following
SELECT * FROM users WHERE id = user_id(from previous query) AND archive = 0 and status = 8
I need to put that into 1 query, but wait, theres more .... from the results there, i need to check if that user's 'id' is in the availability table, if it is, check the date ( column name is date ) and if it matches todays date, dont return that one user.
I need to put all that in one query :S ... i have NO IDEA how to do it, thinking about it makes my head shake ... If someone could help me out, i would be eternaly grateful.
Cheers,
Use INNER JOIN, which links tables to each other based on a common attribute (typically a primary - foreign key relationship)
say an attribute, 'id', links table1 and table2
SELECT t1.att1, t2.att2
FROM table1 t1
INNER JOIN table2 t2
ON t1.id = t2.id --essentially, this links ids that are equal with each other together to make one large table row
To add more tables, just add more join clauses.
SELECT u.*
FROM internalrole ir
INNER JOIN users u
ON ir.user_id = u.id
AND u.archive = 0
AND u.status = 8
LEFT JOIN availability a
ON ir.user_id = a.user_id
AND a.date = CURDATE()
WHERE ir.introle = $imarole
AND a.user_id IS NULL /* User does NOT exist in availability table w/ today's date */
EDIT: This second query is based on the comments below, asking to show only users who do exist in the availability table.
SELECT u.*
FROM internalrole ir
INNER JOIN users u
ON ir.user_id = u.id
AND u.archive = 0
AND u.status = 8
INNER JOIN availability a
ON ir.user_id = a.user_id
WHERE ir.introle = $imarole
Hmm, maybe something like this
SELECT * FROM users WHERE id IN (SELECT user_id FROM internalrole WHERE introle = $imarole) AND archive = 0 and status = 8;
A handy thing for me to remember is that tables are essentially arrays in SQL.
HTH!
Nested queries are your friend.
SELECT * FROM users WHERE id in (SELECT user_id FROM internalrole WHERE introle = $imarole) AND archive = 0 and status = 8
Alternatively joins:
SELECT * FROM users INNER JOIN internalrole ON users.id = internalrole.user_id WHERE internalrole.user_id = $imarole AND users.archive = 0 and users.status = 8

Categories