Select Multiple Values SQL - php

I have a table where the data are as follow
ID Classroom Person
1 1 Alfred
2 1 Maria
3 2 Maria
4 2 Zoe
5 2 Alfred
6 3 Nick
7 3 Paul
8 3 Mike
9 3 Alfred
10 4 Zoe
11 4 Maria
I want to select and return only the Classroom that has as Person only 'Alfred' and 'Maria'
Following statement :
Select * from table_name where (Person='maria') and (Person=Alfred')
doesn't seem to work.
You can see a SQL Fiddle here,

You can use group by and having:
select classroom
from table t
group by classroom
having count(*) = 2 and
sum(person in ('maria', 'Alfred')) = 2;
This assumes that one person cannot be in a classroom multiple times.
This checks that there are two names in the classroom and they are for the two names of interest. If you can have duplicates, you would want:
having count(distinct name) = 2 and
count(distinct case when person in ('maria', 'Alfred') then person end) = 2;

Try this. Group by and having with Count should work.
SELECT Classroom
FROM tablename
WHERE Person IN( 'maria', 'Alfred' )
GROUP BY classroom
HAVING Count(Person) = 2

Related

Sql query to show count(*) of groups while keeping all rows of the group

I have a table similar the following
id user_id father_id
1 1 1
2 2 1
3 3 2
4 4 2
5 5 2
6 6 3
7 7 4
I search for a sql query (prefer Fluent or Eloquent for Laravel 4) to give me the following result:
id user_id father_id family_members
3 3 2 3
4 4 2 3
5 5 2 3
1 1 1 2
2 2 1 2
6 6 3 1
7 7 4 1
As it can be observed family_members is the count of users who have the same father_id
select id, user_id, father_id, count(*) as family_members from users group by father_id
The query above, just keeps the top row of each group, but I want to keep all the other records and not only the first one; then sorting them first according to the family_members and then according to father_id
How can I achieve it?
I don´t know Fluent, nor Eloquent, nor Laravel 4, but the sql query would be like this.
SELECT yourTable.*, auxTable.family_members
FROM yourTable
LEFT JOIN
(
SELECT father_id, COUNT(id) as family_members
FROM yourTable
GROUP BY father_id
)auxTable ON yourTable.father_id = auxTable.father_id
ORDER BY family_members DESC, yourTable.father_id ASC
I solved the problem by the following Fluent query based on the answer from segio0983
$users = DB::table('users')
->leftjoin(DB::raw('(SELECT father_id, COUNT(id) as family_members
FROM users
GROUP BY father_id) auxTable '),function($join)
{
$join->on('users.father_id', '=', 'auxTable.father_id');
})
->orderBy('auxTable.family_members','desc')
->orderBy('users.father_id','asc')
->select('users.id','users.father_id','auxTable.family_members');

Merge results from two different tables with different column number, ORDER them by same key

I have two tables:
Table A: ID Cars Planes Num
1 3 5 2
2 8 44 1
3 7 23 6
4 6 2 7
Table B: ID Horses Dogs Cats Elefants Num
1 3 5 2 3 3
2 8 44 1 22 4
3 7 23 4 14 8
4 6 2 3 15 5
What I need to do: I need to get all results from both tables and sort them by the "Num" Column, where the "number" actually is unique for each result from both rows.
Is it even possible to "merge" those two tables and order them by "num" or should I just get each table separately ordered and do two loops checking always for the next num jumping between tables?
Thanks
you can merge them like that with UNION .
try this:
select num from(
select num from table1
union all
select num from table2
)t
order by num asc
DEMO HERE
EDIT:
select id ,Cars,Planes, Horses,Dogs,Cats,Elefants,num from(
select id ,Cars,Planes,'No horses' Horses,'No dogs' Dogs,'No cats' Cats,'No elefants' Elefants,num from table1
union all
select id,'No cars' Cars,'No planes' Planes,Horses,dogs,Cats,Elefants, num from table2
)t
order by num asc;
DEmo with other columns
SELECT NUM FROM TABLEA
UNION ALL
SELECT NUM FROM TABLEB
ORDER BY 1

Mysql query with IF

I have two tables
Users
Id user grade access_level
1 Alice 1 1
2 Charles 3 3
3 Ben 2 2
Class
Id name grade
1 biology 1
2 math 2
3 geography 2
I can read $username = $_SESSION['MM_Username'] and I want to select for each logged user a list of classes depending on their access_level. For access_level => 3 the user can see all the classes, for access_level < 3 user can see only classes with the same grade with his/hers. So:
For Charles, with access_level=3, I want this result
Id name grade
1 biology 1
2 math 2
3 geography 2
For Alice, with access_level=1 and grade = 1, I want this result
Id name grade
1 biology 1
And for Ben, with access_level=2 and grade = 2, I want this result
Id name grade
1 math 2
2 geography 2
Added from the comment
They have the access_levels based on their position in school. Let's say that Charles is a professor and Alice and Ben are students. Students can see only their classes, but the teacher can see everything.
You could use a INNER JOIN with OR:
SELECT Class.*
FROM
Class INNER JOIN Users
ON Class.grade = Users.grade
OR Users.access_level>=3
WHERE
User='username';
Please see fiddle here.
Try this.
SELECT *
FROM Users as U, Class as C
WHERE U.user = $username
AND U.access_level>=C.grade
I'm not quite sure what are you going to achieve, According to my understanding you can do something like this below.
SELECT u.user,c.name
FROM user AS u INNER JOIN class AS c ON u.grade = c.grade
WHERE u.access_level = 1 AND u.grade = 1
SELECT u.user,c.name
FROM user AS u INNER JOIN class AS c ON u.grade = c.grade
WHERE u.access_level = 2 AND u.grade = 2
SELECT u.user,c.name
FROM users AS u INNER JOIN class AS c ON u.grade = c.grade
WHERE u.grade != 3

Sort records from different tables

I have two table with an column 'minute'.
These table are joined with a INNER JOIN.
Now I want to print out all the records from both tables sorted on both the columns 'minute'
Example
Table 1: name - minute
John - 1
Marc - 3
Table 2: name - minute
Gareth - 2
Joe - 3
Output:
John, Gareth, Marc, Joe
The two tables have to remain two separate tables.
You should use UNION :-
(SELECT *
FROM table1)
UNION
(SELECT *
FROM table2)
ORDER BY minute ASC
Output:-
john 1
gareth 2
marc 3
joe 3
Try this
SELECT name
FROM
(
SELECT name, [minute],1 AS sort FROM Table1
UNION ALL
SELECT name, [minute],2 AS sort FROM Table2
) T
ORDER BY [minute],sort
output
name minute
John 1
Gareth 2
Marc 3
Joe 3
OR
SELECT name, [minute]
FROM
(
SELECT name, [minute] FROM Table1
UNION ALL
SELECT name, [minute] FROM Table2
) T
ORDER BY [minute]
output
name minute
John 1
Gareth 2
Joe 3
Marc 3
Try this:
Select name
From table1
Union all
Select name
From table2
order by minute
Not sure if this is what you are looking for
SELECT name, minute FROM table1, table2 ORDER BY table1.minute,table2.minute ASC;

SUM acorrding to another column

I need to know if there is a possible way doing this with out subquery..
Here is my table structure:
id-name-father_id
1 joe 0
2 mark 0
3 muller 0
4 miki 2
5 timi 2
6 moses 2
7 david 1
8 momo 0
9 daniel 0
10 ermi 3
My table logic is
0 means he is not a child of some one
1+ mean that he is son of man in that row.
Note: if some one have a child, he still
will have 0 in father id (it's mean there is not grand-fathers in my table)
My query is :
SELECT id, name, count(id=father_id) as sons
WHERE father_id = 0
What I want to get is a list of non-children (father_id=0) and sum
the childrens it has.
Is there a way to get the results without a subquery?
This should do it (MySQL):
SELECT `parents`.`id`, `parents`.`name`, COUNT(`children`.*) AS sons
FROM `people` AS parents
LEFT JOIN `people` AS children ON `parents`.`id` = `children`.`father_id`
WHERE `parents`.`father_id` = 0
GROUP BY `parents`.`id`
According to Gary we need to add name to GROUP BY in other SQL databases:
SELECT `parents`.`id`, `parents`.`name`, COUNT(`children`.*) AS sons
FROM `people` AS parents
LEFT JOIN `people` AS children ON `parents`.`id` = `children`.`father_id`
WHERE `parents`.`father_id` = 0
GROUP BY `parents`.`id`, `parents`.`name`
We are joing the table with itself here. So we join all parents with their children.
This will lead to a result like that:
parents.id parents.name children.id children.name
1 joe 7 david
2 mark 4 miki
2 mark 5 timi
2 mark 6 moses
3 muller 10 ermi
8 momo - - # left join allows this line
9 daniel - -
But now we have each parent several times. So we are GROUP'ing the whole thing over the parent’s id, which will result in the following:
parents.id parents.name COUNT(children.*)
1 joe 1
2 mark 3
3 muller 1
8 momo 0
9 daniel 0
You should be able to do it without any joins or sub-queries as follows:
select case father_id when 0 then id else father_id end id,
max(case father_id when 0 then name end) name,
sum(sign(father_id)) sons
from table
group by case father_id when 0 then id else father_id

Categories