My system for appointments has some managers(Ex. doctor), and I intend for all appointment times to display in a table so appointments are filled or empty with the name of the user
Create a table for times appointments :
+-----------+-----------+
| id | time
+-----------+------------
| 1 | 10:00 |
| 2 | 10:30 |
| 3 | 11:00 |
| 4 | 11:30 |
| 5 | 12:00 |
| 6 | 12:30 |
| 7 | 13:00 |
| 8 | 13:30 |
| 9 | 14:00 |
+-----------+-----------+
manager table
+-----------+-------------+-----------+
| id | name | phone |
+-----------+-------------+-----------+
| 1 | alex | 123456 |
| 2 | dany | 123456 |
user table :
+----+------+-------+-----------+
| id | manager_id | name | phone |
+----+------------+------+-----------+
| 1 | 1 | John | 123456 |
| 2 | 1 | Sara | 123456 |
| 3 | 2 | lorem | 123456 |
+----+------+-------+-----------+
and order table(for appointments)
+----+------+-------+------------------+-----------+
| id | manager_id | userid | reserveid| datereserve
+----+------------+------+-------------+-----------+
| 1 | 1 | 1 | 1 |2016/12/28
| 2 | 1 | 2 | 2 |2016/12/28
| 3 | 2 | 3 | 3 |2016/12/28
+----+------+-------+-----------+-----------+------+
Now I want to display reserved time in a table in which appointments filled or empty with the name of the user
like :
Similar this photo
I Joined all of tables in query but can't display similar photo and fetch data:(
How can I implement it?
SELECT
m.name,
a.time,
u.phone,
u.name <- if u.name or u.phone is NULL, then appointment is free now
FROM manager as m
CROSS JOIN appointments as a
LEFT JOIN order as o ON o.manager_id = m.id AND o.appointmentsid = a.id
LEFT JOIN user as u ON u.id = o.userid
#for some doctor
WHERE m.id = DoctorID
I would suggest another table
create table status(id int, name varchar(50));
and insert values (1, "reserved"), (2, "free").
select t.time, s.name, m.name, u.name, u.phone
from time t left join status s on t.id = s.id
left join order o on o.appointmentsid = t.id
left join manager m on o.manager_id = m.id
left join users u on o.userid = u.id;
Related
I need to select calls, answers, deals, rate, talking_time by the grouped working time.
Here is my select:
SELECT
users.username as username,
DATE_FORMAT(users_worktime.start,'%Y-%m-%d') as start,
SUM(users_worktime.length) as working_time
FROM
users_worktime
LEFT JOIN users ON users.id = users_worktime.user_id
WHERE 1
AND users_worktime.user_id = '8'
AND users_worktime.start >= '2015-12-30 00:00:00'
AND users_worktime.start <= '2015-12-31 23:59:59'
GROUP BY
DAY(users_worktime.start)
It's all good, i got 2 rows by date 2015-12-30 and 2015-12-31:
| username | start | working_time |
-----------------------------------------
| Haroldas | 2015-12-30 | 85.00 |
| Haroldas | 2015-12-31 | 170.00 |
And my question: how to select COUNT calls from table calls, answers - SUM all calls where status = 'ended', select COUNT deals from table orders, rate - Deals / SUM calls, and talking_time - calls.call_length. And all of these select by the grouped working time.
I need result like this:
| username | start | calls | answers | deals | rate | talking_time| working_time |
----------------------------------------------------------------------------------------
| Haroldas | 2015-12-30 | 1 | 1 | 1 | 100% | 35 | 85.00 |
| Haroldas | 2015-12-31 | 3 | 2 | 1 | 50% | 160 | 170.00 |
And here are my data tables:
users_worktime:
| id | user_id | length | start |
-----------------------------------------------
| 1 | 8 | 30 | 2015-12-30 07:53:38 |
| 2 | 8 | 55 | 2015-12-30 12:53:38 |
| 3 | 8 | 170 | 2015-12-31 22:53:38 |
users:
| id | username |
-----------------
| 8 | Haroldas |
calls:
| id | user_id | order_id | status | call_length | created_at |
-------------------------------------------------------------------------
| 1 | 8 | 3 | ended | 35 | 2015-12-30 07:53:38 |
| 2 | 8 | 4 | ended | 100 | 2015-12-31 12:53:38 |
| 3 | 8 | NULL | started | 15 | 2015-12-31 14:53:38 |
| 4 | 8 | NULL | ended | 45 | 2015-12-31 20:53:38 |
orders:
| id | user_id | call_id | start |
-----------------------------------------------
| 3 | 8 |1 | 2015-12-30 07:53:38 |
| 4 | 8 |2 | 2015-12-31 12:53:38 |
How many calls / answers / deals / etc / were when user Haroldas working on these days.
Thank you
You could use subqueries to achive your goal. I've also changed your base query because you'll not see records if user didn't work at specified period of time.
SELECT T2.*,
(deals / answers_cnt) * 100 AS rate
FROM
(SELECT T.username,
T.day_start
SUM(T.working_time) AS working_time,
(SELECT COUNT(*) FROM calls AS C
WHERE DATE(created_at) = T.day_start
AND C.user_id = T.user_id) AS calls_cnt,
(SELECT COUNT(*) FROM calls AS C
WHERE DATE(created_at) = T.day_start
AND C.user_id = T.user_id
AND C.status = 'ended') AS answers_cnt,
(SELECT SUM(call_length) FROM calls AS C
WHERE DATE(created_at) = T.day_start
AND C.user_id = T.user_id) AS talking_time,
(SELECT COUNT(*) FROM orders AS O
WHERE DATE(O.start) = T.day_start
AND O.user_id = T.user_id) AS deals_cnt
FROM
(SELECT U.username,
U.id AS user_id,
DATE(UW.start) as day_start,
UW.length AS working_time
FROM users AS U
LEFT JOIN users_worktime AS UW ON UW.user_id = U.id
WHERE U.id = 8
AND UW.start >= '2015-12-30 00:00:00'
AND UW.start <= '2015-12-31 23:59:59') AS T
GROUP BY T.username, T.user_id, T.day_start
) AS T2
You can LEFT JOIN by user_id plus DAY of time. E.g.
FROM
users_worktime
LEFT JOIN users ON users.id = users_worktime.user_id
LEFT JOIN users ON users.id = calls.user_id
AND DAY(users_worktime.start)=DAY(calls.created_at)
Then apply all necessary aggregate functions to the calls data
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
I have a problem with a SQL query and the resultset being returned not being what I expected.
I have these three tables that I am trying to relate.
events_detail
__________________
| ID | start_date |
| 1 | 2012-08-09 |
| 2 | 2013-02-13 |
| 3 | 2012-12-12 |
| 4 | 2013-01-21 |
| 5 | 2012-12-25 |
-------------------
where ID is the primary key
events_category_relationship
__________________________
| ID | event_id | cat_id |
| 1 | 1 | 1 |
| 2 | 2 | 4 |
| 3 | 3 | 2 |
| 4 | 4 | 2 |
| 5 | 5 | 3 |
--------------------------
where ID is primary key
events_category_detail
__________________________________
| ID | name | description |
| 1 | Europe | Kings and castles! |
| 2 | USA | Freedoms |
| 3 | China | Made in China |
| 4 | UK | Big Brother |
------------------------------------
where ID is primary key
What I need to do is grab only 1 event from each category and sorted by date of earliest appearance. So what I should expect in my result is the following
Result Set
________________________________________________________________
| e_id | start_date | c_id | category_name | category_desc |
| 1 | 2012-08-09 | 1 | Europe | Kings and castles! |
| 3 | 2012-12-12 | 2 | USA | Freedoms |
| 5 | 2012-12-25 | 3 | China | Made in China |
| 2 | 2013-02-13 | 4 | UK | Big Brother |
-----------------------------------------------------------------
My SQL query that I tried looks like this
SELECT e.id, e.start_date, c.category_name, c.category_desc
FROM events_detail e
JOIN events_category_relationship r ON r.event_id = e.id
JOIN events_category_detail c ON c.id = r.cat_id
ORDER BY date(e.start_date)
This just joins the 3 tables and returns the result in order by date. What I am stuck on is making it so that only one of each category is displayed like the desired result set above. I have tried using DISTINCT c.category_name and GROUP BY c.category_name, but none of them works.
Any help or advice will be greatly appreciated.
You will want to use a subquery to get the min(start_date) for each name and description. You will then use this result to join back to your events_details table to get the id associated with the data in the subquery:
SELECT e.id,
d.start_date,
d.name,
d.description
FROM events_detail e
INNER JOIN
(
select min(e.start_date) Start_date,
c.name,
c.description
from events_detail e
INNER JOIN events_category_relationship r
ON r.event_id = e.id
INNER JOIN events_category_detail c
ON c.id = r.cat_id
group by c.name, c.description
) d
on e.start_date = d.Start_date
ORDER BY date(e.start_date)
See SQL Fiddle with Demo
user table
.--------------------------------.
| userid| val | Create_Date |
.--------------------------------.
| U1 | foo | 2011-05-01 |
| U1 | foo | 2011-11-18 |
| | | |
| U2 | foo | 2011-11-18 |
| U2 | foo | 2011-11-28 |
| | | |
| U3 | foo | 2011-04-11 |
| U3 | foo | 2011-11-04 |
| | | |
| U4 | foo | 2011-11-21 |
| U4 | foo | 2011-11-28 |
.________________________________.
I have a table similar to the above one. What I need to get is the latest record, and make sure that the latest record is more than 5 days the current date.
for instance, the current date is 2011-11-29
the output of the SQL statement should be
.--------------------------------.
| userid| val | Create_Date |
.--------------------------------.
| U3 | foo | 2011-11-04 |
| U1 | foo | 2011-11-18 |
.________________________________.
my current SQL is able to get the latest records but unable to compare to the latest date.
please help me debug. thanks.
SELECT * FROM user_table t1
WHERE DATEDIFF(NOW(), (SELECT MAX(create_date)
FROM user_table t2
WHERE t2.userid = t1.userid)) > 5
thanks in advance.
You could use a subquery to filter out older records per user. Then you can use a where condition to demand that the latest record is more than five days old.
select *
from UserTable u
join (
select userid
, max(Create_Date) as LatestCreateDate
from YourTable
group by
userid
) filter
on filter.userid = u.userid
and filter.LatestCreateDate = u.Create_Date
where datediff(now(), u.Create_Date) > 5
Try:
select user_id, val, min(Create_date)
from table
group by user_id
having datediff(now(), min(Create_date)) > 5
My MySQL DB looks like this
**table_schools**
id | name
1 | school_1
2 | school_2
**table_classes**
id | class | school_id
1 | a | 1
2 | b | 1
3 | c | 2
4 | d | 2
5 | e | 2
**table_students**
id | name | class_id
1 | Nick | 1
2 | Tom | 2
3 | Kevin | 3
4 | Jane | 4
5 | Mark | 5
6 | Tim | 5
7 | Lynn | 5
I would like to have an output like this:
school_name | class_count | student_count
school_1 | 2 | 2
school_2 | 3 | 5
Is there a way to do this in ONE sql query? And how?
SELECT s.name, COUNT(DISTINCT c.id) AS classes, COUNT(st.id) AS students
FROM table_schools s
LEFT JOIN
table_classes c
ON c.school_id = s.id
LEFT JOIN
table_students st
ON st.class_id = c.id
GROUP BY
s.id
SELECT table_schools.name, COUNT(table_classes.name) AS classes, COUNT(table_students.id) AS students
FROM table_schools
LEFT JOIN table_classes ON table_schools.id = table_classes.school_id
LEFT JOIN table_students ON table_students.class_id = table_classes.id
GROUP BY table_schools.id, table_classes.id
ORDER BY table_schools.name