I have 3 table : events,students and parent_student_relation.
events
id | class_id | title
----------------------
1 | 16 | ABC
2 | 17 | JKL
3 | 18 | XYZ
students
id | class_id | name
----------------------
5 | 18 | StudentName1
6 | 17 | StudentName2
7 | 16 | StudentName3
parent_student_relation
student_id | parent_id
----------------------
4 | 10
5 | 10
6 | 11
7 | 11
Now i want to get data from events where i pass parent_id = 10 then get following output.
Output
id | class_id | title
----------------------
3 | 18 | XYZ
And i pass parent_id = 11 then get following output.
Output
id | class_id | title
----------------------
1 | 16 | ABC
2 | 17 | JKL
I tried with following code :
$q_student = "SELECT student_id FROM parent_student_relation WHERE parent_id = " . $parent_id;
$q_class = "SELECT class_id FROM students WHERE id IN($q_student) GROUP BY class_id";
$q = "SELECT * FROM events WHERE class_id IN($q_class)";
So i can get perfect output in $query = mysql_query($q);
But I want to all in only one join query. So how can do it?? Or its possible or not?
try this
$query="SELECT *
FROM parent_student_relation AS a
JOIN students AS b
ON a.student_id = b.id
JOIN events AS c
ON b.class_id = c.class_id
WHERE a.parent_id = " . $parent_id;
Use this:
$query="select e.id,e.class_id,e.title,s.id from event e
inner join student s on e.class_id=s.class_id
inner join parent_student_relation p on s.id=p.student_id
where p.parent_id=$parent_id";
Related
I'm needing to retrieve shared values from a table based on a value from another table, but don't show duplicates.
Example of what tables I have...
Table - members
+-----------------+
| ID | NAME |
+-----------------+
| 1 | Bob |
| 2 | Jack |
| 3 | Jane |
| 4 | Bruce |
| 5 | Clark |
| 6 | Peter |
+-----------------+
Table - groups
+--------------------------------+
| ID | NAME | MANAGER_ID |
+--------------------------------+
| 1 | Group A | 1 | (Bob)
| 2 | Group B | 2 | (Jack)
| 3 | Group C | 1 | (Bob)
+--------------------------------+
Table - group_members
+--------------------------------+
| ID | GROUP_ID | MEMBER_ID |
+--------------------------------+
| 1 | 1 | 3 | (Group A - Jane)
| 2 | 1 | 4 | (Group A - Bruce)
| 3 | 1 | 5 | (Group A - Clark)
| 4 | 1 | 6 | (Group A - Peter)
| 5 | 2 | 3 | (Group B - Jane)
| 6 | 3 | 4 | (Group B - Bruce)
| 7 | 3 | 5 | (Group C - Clark)
+--------------------------------+
What I am needing
(Note: I'm using * in queries here to shorten code.)
If 'Bob' sees all his groups.
Look at 'group_members' table and show all members that belong to it...
$q = SELECT * FROM groups WHERE manager_id = $id;
$r = mysqli_query($dbc, $q);
while ($row = mysqli_fetch-assoc($r) {
$q2 = SELECT *, count(MEMBERS_ID) AS group_count FROM group_members LEFT JOIN members ON group_members.MEMBER_ID = members.id WHERE group_id = '$row[GROUP_ID]';
$r2 = mysqli_query($dbc, $q2);
while ($row2 = mysqli_fetch-assoc($r2) {
echo $row2['name'];
}
}
This shows me the list as expected.
+------------------------+
| NAME | GROUP COUNT |
+------------------------+
| Jane | 1 |
| Bruce | 1 |
| Clark | 1 |
| Peter | 1 |
| Bruce | 1 |
| Clark | 1 |
+------------------------+
I Add GROUP BY group_members.group_id to my 2nd query and that shows.
+------------------------+
| NAME | GROUP COUNT |
+------------------------+
| Jane | 1 |
| Bruce | 2 |
| Clark | 2 |
| Peter | 1 |
+------------------------+
Which is perfect... But here is the problem
if I add a WHERE members.name LIKE \'%clark%\' then it outputs...
+------------------------+
| NAME | GROUP COUNT |
+------------------------+
| | |
| | |
| Clark | 1 |
| | |
| | |
| Clark | 1 |
+------------------------+
It ignores GROUP BY and shows blank rows where other entries would show.
So with all that said. Does any one know why or a better way to do this please?
Been at it for a while now and would really appreciate any assistance.
EDITED:
Here's the full query with all the columns used:
$q = SELECT * FROM groups WHERE manager_id = $id;
$r = mysqli_query($dbc, $q);
while ($row = mysqli_fetch-assoc($r) {
$q2 = SELECT members.id) AS memid, members.first, members.last, members.comname, members.email, members.sector, (members.status) AS memstatus, (group_members.id) AS groupid, (group_members.member_id) AS memidgroup, group_members.group_id, COUNT(group_members.member_id) AS groupcount, member_roles.role FROM members LEFT JOIN group_members ON members.id = group_members.member_id LEFT JOIN member_roles ON members.role_id = member_roles.id WHERE group_id = '$row[GROUP_ID]' AND members.name LIKE '%clark%' GROUP BY group_members.group_id;
$r2 = mysqli_query($dbc, $q2);
while ($row2 = mysqli_fetch-assoc($r2) {
echo $row2['name'];
}
}
Your query or problem is not completely stated. One cannot guess or assume.
Post your last query as well as all queries dont worry about saving the space.
Those blank rows have data that why they are in the table.
Base on your explanation or your query, here is my simple answer
SELECT id,
(select groups.id from groups where groups.id = group_members.group_id )AS group_members_id,
(select groups.name from groups where groups.id = group_members.group_id )AS group_members_name,
(select members.id from members where members.id = group_members.member_id )AS members_id,
(select members.name from members where members.id = group_members.member_id )AS members_name,
count((select members.id from members where members.id = group_members.member_id ) )as members_id_count FROM group_members WHERE (select members.name from members where members.id = group_members.member_id ) LIKE '%clark%' group by members_id
As you mentioned
WHERE members.name LIKE \'%clark%\'
you were selecting data from the members table whereas you have to select the data from group_members table.
I have three tables :
mls_category
points_martix
mls_entry
My first table (mls_category) is like below:
*--------------------------------*
| cat_no | store_id | cat_value |
*--------------------------------*
| 10 | 101 | 1 |
| 11 | 101 | 4 |
*--------------------------------*
My second table (points_martix) is like below:
*----------------------------------------------------*
| pm_no | store_id | value_per_point | max_distance |
*----------------------------------------------------*
| 1 | 101 | 1 | 10 |
| 2 | 101 | 2 | 50 |
| 3 | 101 | 3 | 80 |
*----------------------------------------------------*
My third table (mls_entry) is like below:
*-------------------------------------------*
| user_id | category | distance | status |
*-------------------------------------------*
| 1 | 10 | 20 | approved |
| 1 | 10 | 30 | approved |
| 1 | 11 | 40 | approved |
*-------------------------------------------*
I am using the following query to show the sum of distance with some condition:
SELECT SUM(t1.totald/c.cat_value)
AS total_distance
FROM mls_category c
JOIN
(SELECT SUM(distance) totald, user_id, category
FROM mls_entry
WHERE user_id = 1
AND status = 'approved'
GROUP BY user_id, category) t1
ON c.cat_no = t1.category
This gives me sum 60 as total_distance, that is correct which I wanted.
Now, I want to include the third table (points_matrix) and want to compare my sum(60) is less than or equal to 80(max_distance) then my new value would be 60*3=180.
So, suppose my sum comes 10 then my new value will be 10*1=10 and if my sum comes 25 then my new value will be according to point matrix 25*2=50.
Yon can using MIN() to calculate what value_per_point you need, and the whole sql is like this:
SELECT MIN(b.value_per_point) * d.total_distance FROM points_matrix b
JOIN
(
SELECT store_id, sum(t1.totald/c.cat_value) as total_distance FROM mls_category c
JOIN
(
SELECT SUM(distance) totald, user_id, category FROM mls_entry
WHERE user_id= 1 AND status = 'approved' GROUP BY user_id, category
) t1 ON c.cat_no = t1.category
) d ON b.store_id = d.store_id AND b.max_distance >= d.total_distance
Use Correlated Subquery:
SELECT
dt.total_distance * dt.max_points
FROM (
SELECT SUM(t1.totald/c.cat_value) AS total_distance,
(
SELECT value_per_point
FROM points_martix
WHERE SUM(t1.totald/c.cat_value) >= max_distance
ORDER BY max_distance ASC LIMIT 1
) AS max_points
FROM mls_category AS c
JOIN (
SELECT SUM(distance) AS totald,
user_id,
category
FROM mls_entry
WHERE user_id= 1 AND
status = 'approved'
GROUP BY user_id, category
) AS t1 on c.cat_no = t1.category
) AS dt
I have the following 'categories' table:
+--------+---------------+----------------------------------------+
| ID | Parent ID | Name |
+--------+---------------+----------------------------------------+
| 1 | 0 | Computers |
| 2 | 1 | Apple |
| 3 | 1 | HP |
| 4 | 2 | Macbook Air |
| 5 | 2 | Macbook Pro |
| 6 | 1 | Dell |
| 7 | 6 | Inspiron |
| 8 | 6 | Alienware |
| 9 | 8 | Alienware 13 |
| 10 | 8 | Alienware 15 |
| 11 | 8 | Alienware 17 |
| 12 | 0 | Smartphones |
| 13 | 12 | Apple |
| 14 | 12 | Samsung |
| 15 | 12 | LG |
+--------+---------------+----------------------------------------+
Let's say I have the following 'products' table:
+--------+---------------+----------------------------------------+
| ID | Category ID | Name |
+--------+---------------+----------------------------------------+
| 1 | 13 | Apple iPhone 8 |
| 2 | 13 | Apple iPhone 8 Plus |
| 3 | 14 | Samsung Galaxy S8 |
+--------+---------------+----------------------------------------+
With the following query, I select all the products in a category:
SELECT
id,
name
FROM
products
WHERE
category_id = ?
Ok, my question:
The product 'Apple iPhone 8' is in the category Apple, this is a subcategory of the category Smartphones. If I replace the '?' in my query with 13 (the category ID of Apple), I get the product. When I replace the '?' in my query with 12 (the category ID of Smartphones), I don't get the product. I want to select all products that are in the category or in one of the child/grandchild/... categories. How can I do this with a single query (if possible)?
you can use join .
your query should be like this
SELECT
id,
name
FROM
products
JOIN
categories
ON
products.category_id = categories.id;
It can be achieved using join
SELECT
id,
name
FROM
products
JOIN
categories
ON
products.category_id = categories.id
WHERE products.category_id = 13 OR categories.parent_id = 12
SELECT id, name FROM products LEFT JOIN categories ON products.category_id = categories.id
1) A QUERY. I'm taking a query from this answer.
How to create a MySQL hierarchical recursive query Please read it for a full explanation of the query. The query assumes that the parent ID will be less than the child IDs (like 19 is less than 20,21,22).
select * from products where `Category ID` in
(select ID from
(select * from categories order by `Parent ID`, ID) categories_sorted,
(select #pv := '12') initialisation
where (find_in_set(`Parent ID`, #pv) > 0
and #pv := concat(#pv, ',', ID)) or ID = #pv)
You have to set the "12" to be whatever the parent category is.
2) Via two sections in PHP, one that loops until you have all category IDs. Then a second section that gets all products in those categories. This is far more verbose but I like how clear you can see what is happening.
$db = new mysqli(host, user, password, database);
$all_ids = []; // total ids found, starts empty
$new_ids = [12]; // put parent ID here
do {
// master list of IDs
$all_ids = array_merge($new_ids, $all_ids);
// set up query
$set = "(".implode($new_ids, ',').")";
$sql = "select ID from categories where `Parent ID` in $set";
// find any more parent IDs?
$new_ids = []; // reset to nothing
$rows = $db->query($sql) or die("DB error: (" . $db->errno . ") " . $db->error);
while ($row = mysqli_fetch_assoc($rows)) {
$new_ids[] = $row['ID'];
}
} while (count($new_ids) > 0);
// get products
$set = "(".implode($all_ids, ',').")";
$sql = "select * from products where `Category ID` in $set";
$rows = $db->query($sql) or die("DB error: (" . $db->errno . ") " . $db->error);
while ($row = mysqli_fetch_assoc($rows)) {
echo "{$row['Name']}<br>\n";
}
I have this table:
// mytable
+----+---------+
| id | related |
+----+---------+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 1 |
| 5 | 3 |
| 6 | 2 |
| 7 | 4 |
| 8 | 4 |
| 9 | 2 |
+----+---------+
I have just an id number like $id = 6. And I want to select all rows which have identical related. So this is expected result:
// newmytable
+----+---------+
| id | related |
+----+---------+
| 3 | 2 |
| 6 | 2 |
| 9 | 2 |
+----+---------+
How can I do that?
Here is my query but doesn't work:
SELECT *
FROM mytable m
WHERE (SELECT related
FROM mytable
WHERE id = :id) t m.related = t.related
select m2.id, m2.related
from
mytable m1
join mytable m2
on m2.related = m1.related
where m1.id = 6
SQL Fiddle sample
SELECT * FROM mytable
WHERE related = ( SELECT related FROM mytable WHERE id = 6)
Not tested...
Try this
select *from mytable
where related = (select related from mytable where id = 6)
Hello please replace your query with below query you will get your expected output.
SELECT * FROM mytable WHERE = (SELECT related FROM mytable WHERE id = :id)
This will work
SELECT * FROM mytable WHERE related = (SELECT releated FROM mytable WHERE id = 6)
I have 2 tables:
sma_db
+----+----------+-------+
| ID | title | catid |
+----+----------+-------+
| 1 | Hi | 4 |
| 2 | Hello | 4 |
| 3 | Test | 5 |
+----+----------+-------+
sma_files
+----+----------+---------+
| ID | name |entry_id |
+----+----------+---------+
| 1 | a.jpg | 1 |
| 2 | b.jpg | 1 |
| 3 | c.jpg | 2 |
+----+----------+---------+
My query as:
$sql = mysql_query("SELECT * FROM sma_db
LEFT OUTER JOIN sma_files
ON sma_db.id = sma_files.entry_id
WHERE catid = '4'") or die(mysql_error());;
while($affcom = mysql_fetch_assoc($sql)){
$title = $affcom['title'];
$name = $affcom['name'];
echo $title;
echo $name;
}
How to select only one row from sma_files table ???
The output for above query:
Hi a.jpg
Hi b.jpg
Hello c.jpg
The output I need:
Hi a.jpg
Hello c.jpg
$sql = mysql_query("SELECT * FROM sma_db
LEFT OUTER JOIN sma_files
ON sma_db.id = sma_files.entry_id
WHERE catid = '4'
GROUP BY sma_files.entry_id")
or die(mysql_error());
try below query
SELECT * FROM `sma_db`
INNER JOIN `sma_files`
ON `sma_db`.`id` = `sma_files`.`entry_id`
WHERE `sma_db`.`catid` = '4'"
Use Group By
SELECT * FROM sma_db
LEFT OUTER JOIN sma_files
ON sma_db.id = sma_files.entry_id
WHERE catid = '4'
GROUP BY `entry_id`