Selecting random triplicates (or more) from database - php

I have two tables:
Students Student_Grades
V------------------------V
+----+------+ +----+------------+---------+-------+
| id | name | | id | student_id | subject | grade |
+----+------+ +----+------------+---------+-------+
| 0 | Dave | | 0 | 0 | Math | 100 |
+----+------+ +----+------------+---------+-------+
| 1 | John | | 1 | 0 | Chem | 90 |
+----+------+ +----+------------+---------+-------+
| 2 | Kate | | 2 | 0 | CompSCI | 95 |
+----+------+ +----+------------+---------+-------+
| 3 | Mimi | | 3 | 1 | ELA | 98 |
+----+------+ +----+------------+---------+-------+
| 4 | 2 | Biology | 92 |
+----+------------+---------+-------+
| 5 | 2 | Chem | 94 |
+----+------------+---------+-------+
| 6 | 2 | Math | 98 |
+----+------------+---------+-------+
| 7 | 3 | Math | 100 |
+----+------------+---------+-------+
I would like to select all subjects and grades from a random student that is enrolled in more than three subjects. (Either Dave or Kate)
Students John and Mimi would not be even considered because they are not enrolled in three subjects.
I know I can achieve this with PHP but I would like this to be done with one query to the database.
SELECT * FROM Students t JOIN (SELECT CEIL(MAX(ID)*RAND()) AS ID FROM Students) AS x ON t.ID >= x.ID LIMIT 1
With the above query, I have selected a random student, with that I can go in and check if they have three subjects with SELECT count(subjects) FROM Students WHERE id=random_id.
If the count returned is below three, then I throw away the results and run the first query again.
How would I attempt this in one query?

This is tested and working:
SELECT *
FROM Students s
JOIN (
SELECT student_id
FROM Student_Grades
GROUP BY student_id
HAVING COUNT(*) >= 3
ORDER BY RAND()
LIMIT 1
) rs
ON rs.student_id = s.id
JOIN
Student_Grades sg
ON sg.student_id = s.id
Here's the SQL Fiddle: http://sqlfiddle.com/#!2/e5b5b/1

Related

Find the ranking for Concatenated rows in mysql

I have a table with concatenated values within both rows, I am therefore uniquely retrieve ranking for each row in the tables.
UPDATE
The other tables has been added to question
NamesTable
NID | Name |
1 | Mu |
2 | Ni |
3 | ices |
GroupTable
GID | GName |
1 | GroupA |
2 | GroupB |
3 | GroupC |
MainTable
| NID | Ages | Group |
| 1 | 84 | 1 |
| 2 | 64 | 1 |
| 3 | 78 | 1 |
| 1 | 63 | 2 |
| 2 | 25 | 2 |
| 3 | 87 | 2 |
| 1 | 43 | 3 |
| 2 | 62 | 3 |
| 3 | 37 | 3 |
Now the first Name is equated to the first age in the table, I am able to equate them using php and foreach statements, Now the problem is with the ranking of the ages per each group. I am ranking the names uniquely on each row or group.
Results which is expected
| Names | Ages | Group | Ranking |
| Mu,Ni,ices | 84,64,78 | 1 | 1,3,2 |
| Mu,Ni,ices | 63,25,87 | 2 | 2,3,1 |
| Mu,Ni,ices | 43,62,37 | 3 | 2,1,3 |
In my quest to solving this, I am using GROUP_CONCAT, and I have been able to come to this level in the below query
SELECT
GROUP_CONCAT(Names) NAMES,
GROUP_CONCAT(Ages) AGES,
GROUP_CONCAT(Group) GROUPS,
GROUP_CONCAT( FIND_IN_SET(Ages, (
SELECT
GROUP_CONCAT( Age ORDER BY Age DESC)
FROM (
SELECT
GROUP_CONCAT(Ages ORDER BY Ages DESC ) Age
FROM
`MainTable` s
GROUP by `Group`
) s
)
)) rank
FROM
`MainTable` c
GROUP by `Group`
This actually gives me the below results.
| Names | Ages | Group | Ranking |
| 1,2,3 | 84,64,78 | 1 | 7,9,8 |
| 1,2,3 | 63,25,87 | 2 | 5,6,4 |
| 1,2,3 | 43,62,37 | 3 | 2,1,3 |
The only problem is that the ranking Values increase from 1 to 9 instead of ranking each row uniquely. Its there any idea that can help me cross over and fix this? I would be grateful for your help. Thanks

how to calculate unique column values in mysql

Here is my data
cardNo| userName| tablename| hours | date
1 | a | a | 12 | 12-06-2015
1 | a | a | 5 | 11-06-2015
2 | b | b | 3 | 15-06-2015
1 | a | a | 8 | 12-06-2015
2 | b | b | 3 | 21-06-2015
1 | a | a | 12 | 14-06-2015
2 | b | b | 10 | 8-06-2015
cardNo is unique. I need to display all details and total hours for each card, like:
cardNo | userName | tablename | totalhours
1 | a | a | 37
2 | b | b | 16
It's simple SUM() with GROUP BY:
SELECT cardNo,sum(hours)
FROM yourtable
GROUP BY cardNo;
I left it as an exercise for the OP to include userName and tablename columns into the query
SELECT cardNo,userName, tablename, sum(hours) hours
FROM Table_1 GROUP BY cardNo,userName,tablename

MySQL Statement to joins 2 tables and sum same items qty

I have 2 tables, customer and transaction.
Customer:
--------------------------------------------
ID | Name | Tel
--------------------------------------------
1 | Peter | 123 4567
2 | John | 456 1234
3 | Alice | 789 4561
4 | Amy | 741 8525
Transaction:
--------------------------------------------
CustID | Books | Pens | Ruler
--------------------------------------------
1 | 2 | 0 | 1
2 | 1 | 0 | 0
1 | 0 | 3 | 0
1 | 0 | 0 | 1
2 | 1 | 1 | 1
3 | 0 | 2 | 2
I need the following
Results:
-------------------------------------------------------------------
ID | Name | Tel | Books | Pens | Ruler
-------------------------------------------------------------------
1 | Peter | 123 4567 | 2 | 3 | 2
2 | John | 456 1234 | 2 | 1 | 1
3 | Alice | 789 4561 | 0 | 2 | 2
4 | Amy | 741 8525 | 0 | 0 | 0
Basically it will sum the Books, Pens and Ruler of the same Customer.
I've tried:
$sql = "select
`customer`.id,
`custmaster`.name,
`custmaster`.tel,
`transaction`.id,
`transaction`.books,
`transaction`.pens,
`transaction`.ruler,
from `customer`
left join `transaction`
on `customer`.id=`transaction`.custid
ORDER BY `customer`.id ASC";
But display none. :( I do understand that I needed the sum() function somewhere. Anybody can help?
Use SUM and GROUP BY.
SELECT c.id, c.name, c.tel, SUM(t.books) as books, SUM(t.pens) AS pens, SUM(t.ruler) AS ruler
FROM customer AS c
LEFT JOIN transactions AS t ON c.id = t.custid
GROUP BY c.id
ORDER BY c.id
Try this way
select
`customer`.id,
`custmaster`.name,
`custmaster`.tel,
`transaction`.id,
sum(`transaction`.books) as books,
sum(`transaction`.pens) as pens,
sum(`transaction`.ruler) as ruler,
from `customer`
left join `transaction`
on `customer`.id=`transaction`.custid
Group by `customer`.id,`customer`.Name
ORDER BY `customer`.id ASC";

MySQL getting total number of enquiries for each branch

I have three tables and they are the following
User Table
+---------+-----------+--------+
| user_id | user_name | branch |
+---------+-----------+--------+
| 1 | John | 1 |
| 2 | Jim | 2 |
| 3 | Jern | 3 |
| 4 | Jack | 1 |
| 5 | Jery | 2 |
| 6 | Tom | 3 |
| 7 | Sona | 1 |
| 8 | Tina | 3 |
+---------+-----------+--------+
Branch Table
+-----------+----------------+
| branch_id | branch_name |
+-----------+----------------+
| 1 | IT |
| 2 | SALES |
| 3 | Administration |
+-----------+----------------+
Enquiry Table
+------------+---------------+---------+
| enquiry_id | enquiry_name | user_id |
+------------+---------------+---------+
| 1 | enqury_test1 | 1 |
| 2 | enqury_test2 | 2 |
| 3 | enqury_test3 | 1 |
| 4 | enqury_test4 | 3 |
| 5 | enqury_test5 | 2 |
| 6 | enqury_test6 | 5 |
| 7 | enqury_test7 | 1 |
| 8 | enqury_test8 | 2 |
| 9 | enqury_test9 | 4 |
| 10 | enqury_test10 | 6 |
| 11 | enqury_test11 | 2 |
| 12 | enqury_test12 | 7 |
+------------+---------------+---------+
From the above tables its clear that, each branch contains a number of users.
These users post multiple enquiries.
I need to get the total number of enquiries in each branch as
branch id => number of enquiries
I have tried various queries. But i couldn't get the result. Any one can help?
I am using MySQL and i need a single query to do this.
Thanks in advance
You need count and group by
select
b.branch_id,
count(e.user_id) as `total_enq`
from Branch b
left join User u on u.branch = b.branch_id
left join Enquiry e on e.user_id = u.user_id
group by b.branch_id
The query you have to perform to get you desired result is like this :-
$query = "SELECT u.branch, COUNT(u.user_id) AS `total_enquires`
FROM enquiry e INNER JOIN user u ON e.user_id = u.user_id
GROUP BY u.branch"
This will help you,and i think you don't need to join branch table as user table already contain branch_id.
This is the query
SELECT `branch`,`branch_name`,count(`user`.`user_id`),count(`enquiry_id`) FROM `user` inner join `branch` on `user`.`branch`=`branch`.`branch_id` inner join `enquiry` on `user`.`user_id`=`enquiry`.`user_id` group by `branch`
try it here
http://sqlfiddle.com/#!9/cf3eb/1
SELECT
bt.branch_id
,COUNT(enquiry_id) AS total_enquiry
FROM
enquiry_table et
INNER JOIN user_table ut on ut.user_id = et.user_id
INNER JOIN branch_table bt ON bt.branch_id = ut.branch
WHERE
1=1
GROUP BY
bt.branch_id
you can try this

sum the quantity from 3rd relational table

I have following tables, i want to fetch the purchase_order and his order_quantity and sum of received quantity for each purchase_order. i know how to sum the quantity from single table but from multiple tables, it is confusing me a lot...
mysql> select * from purchase_order;
+-------------------+-------------------------+-------+---------------------+
| purchase_order_id | purchase_order | cost | created_on |
+-------------------+-------------------------+-------+---------------------+
| 1 | Dell Computer 000001256 | 10000 | 2015-02-19 22:14:52 |
| 2 | HP Computer 000001256 | 50000 | 2015-02-19 22:14:52 |
+-------------------+-------------------------+-------+---------------------+
2 rows in set (0.00 sec)
mysql> select * from purchase_order_detail;
+--------------------------+-------------------+---------+------------------+
| purchase_order_detail_id | purchase_order_id | item_id | ordered_quantity |
+--------------------------+-------------------+---------+------------------+
| 1 | 1 | 279 | 100 |
| 2 | 1 | 286 | 100 |
| 3 | 2 | 279 | 200 |
| 4 | 2 | 286 | 300 |
+--------------------------+-------------------+---------+------------------+
4 rows in set (0.00 sec)
mysql> select * from delivery_order;
+-------------------+--------------------------+-------------------+---------------------+
| delivery_order_id | purchase_order_detail_id | recieved_quantity | recieved_on |
+-------------------+--------------------------+-------------------+---------------------+
| 1 | 1 | 50 | 2015-02-19 22:22:51 |
| 2 | 2 | 50 | 2015-02-19 22:24:59 |
| 3 | 1 | 50 | 2015-02-19 22:34:14 |
| 4 | 3 | 70 | 2015-02-20 11:11:31 |
| 5 | 4 | 150 | 2015-02-20 11:11:31 |
| 6 | 3 | 90 | 2015-02-20 11:12:20 |
| 7 | 4 | 100 | 2015-02-20 11:12:20 |
| 8 | 3 | 40 | 2015-02-20 11:12:55 |
| 9 | 4 | 50 | 2015-02-20 11:12:55 |
+-------------------+--------------------------+-------------------+---------------------+
So far, i have this query, but id doesn't returns correct record..
SELECT po.purchase_order_id, SUM(pod.ordered_quantity) AS Sum_of_ordered_quantity, SUM(dor.recieved_quantity) AS Sum_of_recieved_quantity
FROM purchase_order AS po
INNER JOIN purchase_order_detail AS pod ON po.purchase_order_id = pod.purchase_order_id
INNER JOIN delivery_order AS dor ON dor.purchase_order_detail_id = pod.purchase_order_detail_id
GROUP BY po.purchase_order_id
it returns this,
+-------------------+-------------------------+--------------------------+
| purchase_order_id | Sum_of_ordered_quantity | Sum_of_received_quantity |
+-------------------+-------------------------+--------------------------+
| 1 | 300 | 150 |
| 2 | 1500 | 500 |
+-------------------+-------------------------+--------------------------+
you can see in the question that , purchase_order_id 1 has 200 ordered quantity and 150 received quantity while purchase_order_id 2 has 500 ordered_quantity and 500 received quantity.
Please try this code:
SELECT po.purchase_order_id,
SUM(pod.ordered_quantity) AS Sum_of_ordered_quantity,
(SELECT `mySelect`.`desired_sum` FROM
(SELECT B.`purchase_order_id` AS myID, SUM( `A`.`recieved_quantity` ) AS desired_sum
FROM `delivery_order` AS A
LEFT JOIN `purchase_order_detail` AS B ON A.purchase_order_detail_id = B.purchase_order_detail_id
GROUP BY B.`purchase_order_id` ) AS mySelect
WHERE `mySelect`.`myID` = `po`.`purchase_order_id`) AS Sum_of_received_quantity
FROM purchase_order AS po
INNER JOIN purchase_order_detail AS pod ON po.purchase_order_id = pod.purchase_order_id
GROUP BY po.purchase_order_id
This is usual while doing aggregate sum function with multiple many-to-many tables with different joining condition.
One way is to use correlated subquery to get the aggregate value and then do the join. Something as
select
po.purchase_order_id,
pod.Sum_of_ordered_quantity,
do.Sum_of_received_quantity
from purchase_order po
join
(
select purchase_order_id,sum(ordered_quantity) as Sum_of_ordered_quantity
from purchase_order_detail
group by purchase_order_id
)pod on pod.purchase_order_id = po.purchase_order_id
join
(
select
t1.purchase_order_id,
sum(t2.recieved_quantity) as Sum_of_received_quantity
from purchase_order_detail t1
join delivery_order t2 on t1.purchase_order_detail_id = t2.purchase_order_detail_id
group by t1.purchase_order_id
)do on do.purchase_order_id = po.purchase_order_id
DEMO

Categories