I have this query:
SELECT *
FROM `classes`
JOIN `classes_students`
ON `classes`.`id` = `classes_students`.`class`
And I need to add condition for selecting just classes, in which are not currently logged student (user ID is not in classes_students connected with class id) and also count how many students are in that class.
Table structure:
classes: id, name, etc
classes_students: class_id, user_id, etc
Table data:
classes:
1 | test
2 | test2
3 | test3
classes_students:
1 | 1
1 | 2
2 | 3
3 | 4
3 | 5
Expected output if im user with id 1:
classes names (with number of students in):
2 (1 student)
3 (2 students)
All this in one query. It is possible? If yes, how?
Select classid, count(*)
from class
left join student on student.classid = class.classid
group by classid
Glad help for you
Try this query:
$user_id = 1; // current user_id
$query = "SELECT `classes`.`id`, `classes`.`name`, COUNT(*) as students FROM `classes`
JOIN `classes_students`
ON `classes`.`id` = `classes_students`.`class_id`
AND `classes_students`.`user_id` != $user_id
GROUP BY `classes_students`.`class_id`
";
I figured it out! :)
Thank you guys for ur help.
$user_id = 1; // current user_id
$query = "SELECT `classes`.`id`, `classes`.`name`, COUNT(*) as students FROM `classes`
LEFT JOIN `classes_students`
ON `classes`.`id` = `classes_students`.`class_id`
WHERE `classes`.`id` NOT IN (SELECT `class_id` FROM `classes_students` WHERE `user_id`='.$user_id.')
GROUP BY `classes_students`.`class_id`
";
Related
I am working on a photography project and I am facing a bit issue with joining tables and retrieving data from mysql database.
I have created two tables for this project. One table named cm_team is for team members and another table named cm_events for photography events..Assume to shoot a event, we require 6 persons and the id of the person is stored in cm_events table.
As you can see from the above images.. I am storing the id's of members of cm_team in cm_events table.. I wish to obtain the name of the team member in the respective highlighted fields in the cm_events table..Any help is highly appreciated.
for example my desired output should be: instead of 5 under team_lead heading, I should get the name corresponding to 5 i.e Arjun
Something like this? (cleaner and faster than subqueries)
SELECT
`event`.client_name,
`event`.client_number,
# some more event cols ..
`team_lead`.`cm_name` AS `team_lead`,
`candid_photo`.`cm_name` AS `candid_photo`,
`candid_video`.`cm_name` AS `candid_video`,
`traditional_photo`.`cm_name` AS `traditional_photo`,
`traditional_video`.`cm_name` AS `traditional_video`,
`helper`.`cm_name` AS `helper`
FROM cm_events `event`
JOIN cm_team `team_lead` ON `team_lead`.`cm_code` = `event`.`team_lead`
JOIN cm_team `candid_photo` ON `candid_photo`.`cm_code` = `event`.`candid_photo`
JOIN cm_team `candid_video` ON `candid_video`.`cm_code` = `event`.`candid_video`
JOIN cm_team `traditional_photo` ON `traditional_photo`.`cm_code` = `event`.`traditional_photo`
JOIN cm_team `traditional_video` ON `traditional_video`.`cm_code` = `event`.`traditional_video`
JOIN cm_team `helper` ON `helper`.`cm_code` = `event`.`helper`
With Sub queries
DROP TABLE IF EXISTS T,t1;
CREATE TABLE T (
id int, name varchar(10));
insert into t values
(1 , 'aaa'),
(2 , 'bbb');
create table t1 (
id int, team_lead int,team_a int);
insert into t1 values
(1,1,2),
(2,2,2);
select t1.id, (select t.name from t where t.id = t1.team_lead) team_lead,
(select t.name from t where t.id = t1.team_a) team_a
from t1;
+------+-----------+--------+
| id | team_lead | team_a |
+------+-----------+--------+
| 1 | aaa | bbb |
| 2 | bbb | bbb |
+------+-----------+--------+
2 rows in set (0.001 sec)
This is what I want:
Users will send one or two values in my website and I will store them in two variables $genres1 and $genres2.
Like: If user sends, Action, then my code will show all movies with Action genres. If user sends Action+Crime, then my table will fetch all movies with Action+Crime.
Got it?
My current table structure is one to many relationship, like this
tmdb_id movie_title
-----------------------------
1 Iron man
2 Logan
3 Batman
4 The hangover
tmdb_id genres
-----------------------------
1 Action
1 Crime
2 Drama
2 Action
3 Crime
3 Action
4 Comedy
4 Drama
But the problem here is, I can't achieve what I explained above with this.
2nd option: I make a single table like this:
movie_tile genres1 genres2 genres3 genres4
----------------------------------------------------
Logan Action Crime Drama Null
Iron man Action Crime Null Null
And I can do what, I want with this single line:
SELECT * FROM movies WHERE (genres1='$genres1' or genres2='$genres1' orgenres1='$genres3' or genres3='$genres1')
Any other option?
use a table width genres
and use an other table connecting the movie to any genre
-----
movieid title
-----
1 Logan
2 Smurf
-----
-----
genreid genre
-----
1 animated
2 blue people
-----
-----
movieid genreid
-----
1 1
2 1
2 2
-----
that way you won't be limited to 4 genres per movie
now I read your question better.
That's what you do, but you put left out the genre-table.
The 2nd option is bad, as you limit yourself to only 4 categories
Is this connected to PHP? I think is easiest to solve this further by a join query, sorted by movie and a loop in PHP
you want all movies where (by user request) the genres are both Crime And Action?
SELECT mg.movieid, count(1), m.title
FROM movies_genres mg
JOIN movies m ON m.movieid mg.movieid
WHERE mg.genreid = 1 OR mg.genreid =3
group by mg.movieid, m.title
HAVING COUNT(1) = 2
edit: see other genres as well
SELECT movies.movieid,movies.title, genres.genre
FROM movies
JOIN movie_genre mg ON mg.movieid = movies.movieid
JOIN genres on genres.genreid = mg.genreid
WHERE movie.movieid IN (
SELECT mg.movieid
FROM movies_genres mg
WHERE mg.genreid = 1 OR mg.genreid =3
GROUP BY mg.movieid
HAVING COUNT(1) = 2
)
forgot to mention: count = 2, means you gave 2 genreid's to find. This could also be 1, 3 or 25
select distinct a.tmdb_id, a.movie_tittle
from movie_tittle a inner join genre_tittle b
on a.tmdb_id = b.tmdb_id
where b.genres in ('Action', 'Crime')
Based on your comment, try this :
SELECT
a.tmdb_id, a.movie_tittle
FROM
movie_tittle a inner join genre_tittle b
ON
a.tmdb_id = b.tmdb_id
WHERE
b.genres in ('Action', 'Crime')
GROUP BY
a.tmdb_id, a.movie_tittle
HAVING
count(a.tmdb_id) = 2
tmdb_id and genres in table genre_tittle should not duplicated. Make it as primary key.
But the problem here is, I can't achieve what I explained above with [the first two tables]
Yes, you can. Assuming the two tables are called movies and movie_genres, you can select the movies which have both tags using:
SELECT movie_title FROM movies
JOIN movie_genres genre1 USING (tmdb_id)
JOIN movie_genres genre2 USING (tmdb_id)
WHERE genre1.genres = 'Action'
AND genre2.genres = 'Crime'
See it for yourself here.
try something like this :
tableA
Movie_ID Movie_title
1 Iron man
2 Logan
3 Batman
4 The hangover
tableB
Genre_ID Genre_title
1 Action
2 Crime
3 Drama
4 Comedy
tableC
ID Movie_ID Genre_ID
1 1 1
2 1 2
3 2 2
4 2 3
query :
Select A.Movie_title,B.Genre_title
from tableC C
inner join tableA A on A.Movie_ID = C.Movie_ID
inner join tableB B on B.Genre_ID = C.Genre_ID
where
C.Genre_ID in (IFNULL(val1,0),IFNULL(val2,0))
you should make a relational table to solve you issues like so
movie table
movie_id movie_name genre_id
1 alien 2
2 logan 1
3 ps i love you 4
4 click 3
then you will need a genre table
genre table
genre_id genre_type
1 action
2 sci fi
3 comedy
4 romance
then your select would link the to tables
function get_movies_by_genre($genre_id) {
global $MySQLiConnect;
$query = '
SELECT *
FROM movies m
INNER JOIN genre g ON (g.genre_id = m.genre_id)
WHERE g.genre_id = ?
';
$stmt = $DBConnect->stmt_init();
if ($stmt->prepare($query)) {
$stmt->bind_param("i", $genre_id);
$stmt->execute();
$result = $stmt->get_result();
$rows = $result->fetch_all(MYSQLI_ASSOC);
$stmt->close();
}
return $rows;
}
or
function get_movies_by_genre($genre_id) {
global $MySQLiConnect;
$query = '
SELECT *
FROM movies m
INNER JOIN genre g ON (g.genre_id = m.genre_id)
WHERE g.genre_name = ?
';
$stmt = $DBConnect->stmt_init();
if ($stmt->prepare($query)) {
$stmt->bind_param("i", $genre_id);
$stmt->execute();
$result = $stmt->get_result();
$rows = $result->fetch_all(MYSQLI_ASSOC);
$stmt->close();
}
return $rows;
}
This is the base function to get you all information from the movie table depending on which genre id you send to it.
as for multiple ids you can then run the function through a foreach loop for as many genre_ids as you need and then display them as you need.
I hope this helps.
maybe someone can help me.
I have 2 sql tables:
// groups
| id_group | namegroup |
+------------+-----------+
| 30 | s |
// contacts
| name | group |
+------+-------+
| juan | s |
I need to DELETE a group from ID, but no has contacts associated with it.
I test the following query but doesnt work.
DELETE
FROM group
WHERE id_group = 30
AND (
SELECT
count(*) AS id
FROM contacts co
INNER JOIN GROUP c ON co. GROUP = c.namegroup
WHERE c.id_group = 30
) = 0
Thanks
You can try the following query if you want to delete group having ID = 30 only if the group is not associated to any contact :
Query #1:
DELETE
`groups`
FROM `groups`
LEFT JOIN contacts
ON contacts.`group` = `groups`.namegroup
WHERE `groups`.id_group = 30
AND contacts.`group` IS NULL;
And if you want to delete all groups which don't have any associated contact then try the following query instead:
Query #2:
DELETE
`groups`
FROM `groups`
LEFT JOIN contacts
ON contacts.`group` = `groups`.namegroup
WHERE contacts.`group` IS NULL;
If you define firigen key mysql will handle this issue and you do not need to do anything
In these cases(without forigen key) i usually first run following query:
select count(*) as id from contacts co inner join group c on co.group=c.namegroup where c.id_group=30
And say to user which if they can delete or not and if he could delete that row:
delete from group where id_group=30
I tried to find a solution like query which you had but could not and suggest this solution for you.
I've tried to find a way to select data from two tables within the same query as follows:
Suppose I have this as table1
id | item | qty
1 | 1bb1 | 12
2 | 1cc1 | 10
and as table2
id | item | qty
6 | 1bb1 | 12
7 | 1vv1 | 4
And I have an imported file which contains data item as $sheetData[$i]['A'] from an excel sheet that I need to use it to find out if BOTH tables have this item or not.
My code as follows :
$query1="SELECT * FROM table1.item,table2.item WHERE item ='".$sheetData[$i]['A']."'";
$result1= mysql_query($query1);
if(mysql_num_rows($result1)>0){
echo "This Item Found in Both Tables";
echo $sheetData[$i]['A'];
echo "<br />";
}
else{
echo "Item Could Not Be Found in both tables";
echo $sheetData[$i]['A'];
}
Its basically I want to find out if the imported item found in both tables or not. I hope this makes sense for you!
Any help would be really appreciated
Compiler can't decide which item needs to compare. item from table1 or item from table2
So write query as:
SELECT A.* , B.*
FROM table1 A, table2 B
WHERE A.item = B.item AND
A.item = '".$sheetData[$i]['A']."'
Try with -
"SELECT t1.id, t1.item, t1.qty, t2.id id_2, t2.qty qty_2 FROM table1 t1
INNER JOIN table2 t2 ON t2.item = t1.item
WHERE table1.item ='".$sheetData[$i]['A']."'"
Try to avoid using mysql, it is deprecated now. mysqli/PDO instead.
Try something like this:
SELECT COUNT(*)
FROM (
SELECT DISTINCT 1
FROM table1
WHERE item = ?
UNION ALL
SELECT DISTINCT 1
FROM table2
WHERE item = ?) AS t
This will return 2 if the item exists in both tables, 1 if it exists in only 1 table and 0 if the item doesn't exists in any of the two tables.
I have two table in my DB as table tbl_a and tbl_b which are having following data.
tbl_a
tbl_a_id u_id a_name
1 1 Joe
2 1 Joel
3 1 Joele
4 1 Joelle
5 3 Joeee
tbl_b
tbl_b_id u_id a_name
1 1 Joe
2 1 Joel
3 1 Joele
4 1 Joelle
5 3 Joeee
5 1 Joeees
5 1 Joeeess
How can I get the tbl_b.a_name values which are not present in the tbl_a table as a_name.
My desire output should be like,
Joeees
Joeeess
Right now I am having the following code.
$qqq = $this->db->query("
SELECT
tbl_b.a_name
FROM tbl_b
WHERE tbl.u_id='1'
");
foreach($qqq->result() as $ggg)
{
echo $ggg->a_name;
}
Thank in advance.
The simplest way is to use not exists:
select a.*
from tbl_a a
where not exists (select 1 from tbl_b b where b.b_name = a.a_name);
I got the solution thanks for the help anyways..
SELECT
tbl_b.a_name
FROM tbl_b
WHERE tbl_b.u_id='1'
AND NOT EXISTS (SELECT * FROM tbl_a WHERE tbl_a.u_id='1' AND tbl_b.a_name = tbl_a.a_name)
You can try not in same as follow:
SELECT * FROM `tbl_b`
where a_name not in (select DISTINCT a_name from tbl_a)
select a.*,b.*
from tbl_a a left join tbl_b b on a.u_id = b.u_id
where b.b_name != a.a_name
You can try this it may be useful and execute fast then other query.
Try this
SELECT
DISTINCT tbl_b.a_name
FROM tbl_b where tbl_b.a_name NOT IN (SELECT DISTINCT tbl_a.a_name from tbl_a)