I try to find a similar question but didn't find an exact one so I'll post mine:
I have 2 tables:
room (room_id)
room_reservation (room_id, date)
How can I return list of rooms that have at least 1 day free between 2 dates.
For example, if I have those rooms:
room_id 1, 2 & 3
then in room_reservation table, I have the following:
1 - 2012-07-22
1 - 2012-07-23
1 - 2012-07-24
1 - 2012-07-25
1 - 2012-07-26
2 - 2012-07-23
2 - 2012-07-24
then doing a search for available room between 2012-07-22 and 2012-07-26 should return only room #2 and #3.
I have this query so far but didn't work... please help!
SELECT DISTINCT room_id AS id
FROM room
WHERE (SELECT COUNT('listing') FROM listing_calendar WHERE listing = l.listing_id AND date BETWEEN '2012-07-22' AND '2012-07-26' GROUP BY listing) < 5"
Thanks for the help!
You can use this solution:
SELECT a.room_id
FROM rooms a
LEFT JOIN room_reservations b ON
a.room_id = b.room_id AND
b.date BETWEEN '2012-07-22' AND '2012-07-26'
GROUP BY a.room_id
HAVING COUNT(b.room_id) < DATEDIFF('2012-07-26', '2012-07-22') + 1
SQLFiddle Demo
Related
The user table looks like this:
user_id
name
surname
1
a
aa
2
b
bb
3
c
cc
The book's table looks like this:
user_id
book_name
1
book1
1
book2
1
book3
2
book1
The expenses table looks like this:
user_id
amount_spent
date
1
10
2020-02-03
1
30
2020-02-02
1
10
2020-02-01
1
15
2020-01-31
1
13
2020-01-15
2
15
2020-02-01
3
20
2020-02-01
The result which I want:
CountUsers
amount_spent
2
65
Explanation: I want to count how many users have book1 and how much total they spend on a date between 2020-02-01 - 2020-02-03.
Now how the query should look like?
I am using MySQL version 8.
I have tried:
SELECT
count(*), sum(amount_spend) as total_amount_spend
FROM
(select sum(amount_spend) as amount_spend
FROM expanses
LEFT JOIN books ON books.user_id = expanses.user_id WHERE books.book_name ='book1 GROUP BY expanses.user_id) src'
And the result is wrong because I am getting a higher amount_spend than in my table result above. I think while joining the table there are some duplicates but I do not know how to fix them.
I want to count how many users have book1 and how much total they spend on a date between 2020-02-01 - 2020-02-03.
I am thinking:
select count(*), sum(e.amount_spent)
from user_books ub join
expenses e
on ub.user_id = e.user_id
where book_name = 'book1';
Note: This assumes that user_books doesn't have duplicate rows.
FIDDLE
You miss the date part in your code.
SELECT
count(*), sum(amount_spent) as total_amount_spend
FROM
(select sum(amount_spent) as amount_spent
FROM expanses
LEFT JOIN books ON books.user_id = expanses.user_id
WHERE books.book_name ='book1'
and expanses.date between '2020-02-01' and '2020-02-03'
GROUP BY expanses.user_id) src;
will do a job.
Please note that you don't need to have left join here (unless you're sure that it may happen that no expenses at all for given user will be), and you don't need to have grouping in subquery. So your query could look like:
select count(distinct expanses.user_id), sum(amount_spent) as amount_spent
from expanses
inner join books on books.user_id = expanses.user_id
where books.book_name ='book1'
and expanses.date between '2020-02-01' and '2020-02-03';
So I have this query, that selects the users, some data, with some filters (such as group that they are in and stuff) and with them the amount they produced (in $) last month (get the last existing record from last month, using MAX(created_date)), for a management platform, which shows how much they produced this month and at the previous (us.amount_produced and up.amount_produced last_month_amount).
The problem is that it doesn't select users that are new (that haven´t produced any amount last month), and I need those to return too.
Any help is appreciated, thanks
(I was thinking about doing a JOIN or even two queries, but I´m sure about the best approach)
Note by examples below that the user #3 didnt have any logs at the User_Performance table before February, he was created on february. So the query below won't return him (i need it to return him)
User table structure:
Users
id email login amount_produced created_date
---------------------------------------------
1 foo#bar.com foo 1000 2019-12-20 22:30:01
2 jack#gmail.com jack 0 2019-12-20 22:30:01
3 john#gmail.com john 2000 2020-02-01 00:00:01
User_Group_Config table structure:
User_Group_Config
user_id group_id
---------------------------------------------
1 4
2 1
3 4
User_Performance table structure this table is a log table that a job inserts data every hour, calculating users productivity and logging:
Users
user_id amount_produced created_date
---------------------------------------------
1 500 2020-01-31 22:30:01
2 0 2020-01-31 22:30:01
1 500 2020-01-31 23:30:01
2 0 2020-01-31 23:30:01
1 1000 2020-02-01 00:30:01
2 0 2020-02-01 00:30:01
3 0 2020-02-01 00:30:01
SELECT
us.id,
us.email,
us.login,
ugc.group_id,
up.user_id,
up.amount_produced last_month_amount
FROM
db.User_Performance AS up,
db.User_Group_Config ugc,
db.User AS us
WHERE
created_date IN (SELECT
MAX(created_date)
FROM
User_Performance
WHERE
/* Here it filters only users that have data last month, I need these AND the ones that have no data to return zero here or null or undefined at this row)*/
MONTH(created_date) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
GROUP BY user_id)
AND ugc.group_id = 4
AND up.user_id = ugc.user_id
AND us.id = up.user_id;
Desired Results (note that user #2 wasn´t selected since his group_id is #1
Results
(current month) (previous month)
id email login amount_produced last_month_amount
---------------------------------------------
1 foo#bar.com foo 1000 500
3 john#gmail.com john 0 null or 0
Test
SELECT
us.id,
us.contact_phone,
us.email,
us.first_name,
us.last_name,
us.login,
ugc.group_id,
us.create_date,
us.expire_date,
us.profile_photo,
us.dashboard_enabled,
us.general_rating,
us.rework_rating,
us.amount_produced,
us.amount_spent,
up.user_id,
up.amount_produced last_month_amount
FROM db.User_Performance AS up
LEFT JOIN db.User_Group_Config ugc ON up.user_id = ugc.user_id AND ugc.group_id = 4
LEFT JOIN db.User us ON us.id = up.user_id
WHERE
up.created_date IN (SELECT
MAX(created_date)
FROM
User_Performance
WHERE
/* Here it filters only users that have data last month, I need these AND the ones that have no data to return zero here or null or undefined at this row)*/
MONTH(created_date) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
GROUP BY user_id);
Solved using this, with subquery and JOIN (not the best solution, but a solution):
SELECT
us.id,
us.email,
us.login,
ugc.group_id,
us.amount_produced,
(
SELECT
perf.amount_produced
FROM
User_Performance perf
WHERE
perf.user_id = us.id AND
perf.created_date BETWEEN DATE_FORMAT(CURRENT_DATE - INTERVAL 1 MONTH, '%Y-%m-01 00:00:00') and CONCAT(LAST_DAY(CURRENT_DATE - INTERVAL 1 MONTH), " 23:59:59")
ORDER BY
perf.created_date DESC
LIMIT 1
) as amount_produced_last_month
FROM
User AS us
INNER JOIN
User_Group_Config ugc ON ugc.user_id = us.id
WHERE
ugc.group_id = 4;
Can you help me with a simple task, but I can't really figure out, how I should do that request. Help, please.
I have:
doctors
id name profession
1 James Harden dental
2 James Jones therapist
3 LeBron James cardiologist
4 Kobe Braynt surgeon
5 Sabrina Williams nurse
6 Tyler Okonma speech therapist
patients
id name diagnostic
1 Mo Bamba tooth pulling out
2 Kaney West astma
3 Post Malone heart attack
4 Denzel Curry headache
5 Nicola Jokic stomac-ache
6 Dwayne Wade AIDS
visits
doctorId patientId visitDate
1 1 2019-03-09
2 4 2019-03-01
2 5 2019-02-26
2 6 2019-02-05
3 3 2019-03-03
4 2 2019-03-07
I need to show the doctors serving the largest number of patients in the previous month. I am lost in counting the patients which were serving by doctors. Can you suggest the request, please?
You need to group by doctorid the visits table and join to the doctors table:
select d.name, g.counter
from doctors d inner join (
select doctorid, count(distinct patientid) counter
from visits
where
year(visitdate) = year(current_date - interval 1 month)
and
month(visitdate) = month(current_date - interval 1 month)
group by doctorid
order by counter desc limit 3
) g on g.doctorid = d.id
order by g.counter desc, d.name
You can change limit 3 to what you like.
Try this
select d.name, count( distinct v.patientid) noofvisits
from visits v inner join
doctors d on v.doctorid=d.doctorid
where v.visitdate < '1-mar-2019'
group by d.name
order by noofvisits desc
I have simple table:
Order_ID Client_ID Date Order_Status
1 1 01/01/2015 3
2 2 05/01/2015 3
3 1 06/01/2015 3
4 2 10/01/2015 3
5 1 12/01/2015 4
6 1 05/02/2015 3
I want to identify orders from new customers which are orders in same month in which that customer made first order with Order_Status = 3
So the output table should look like this:
Order_ID Client_ID Date Order_Status Order_from_new_customer
1 1 01/01/2015 3 yes
2 2 05/01/2015 3 yes
3 1 06/01/2015 3 yes
4 2 10/01/2015 3 yes
5 1 12/01/2015 4 NULL
6 1 05/02/2015 3 no
I wasn't able to successfully figure out the query. Thanks a lot for any help.
Join with a subquery that gets the date of the first order by each customer.
SELECT o.*, IF(MONTH(o.date) = MONTH(f.date) AND YEAR(o.date) = YEAR(f.date),
'yes', 'no') AS order_from_new_customer
FROM orders AS o
JOIN (SELECT Client_ID, MIN(date) AS date
FROM orders
WHERE Order_Status = 3
GROUP BY Client_ID) AS f
ON o.Client_ID = f.Client_ID
Use a CASE statement along with a SELF JOIN like below
select t1.*,
case when t1.Order_Status = 3 and MONTH(t1.`date`) = 1 then 'yes'
when t1.Order_Status = 3 and MONTH(t1.`date`) <> 1 then 'no'
else null end as Order_from_new_customer
from order_table t1 join order_table t2
on t1.Order_ID < t2.Order_ID
and t1.Client_ID = t2.Client_ID;
If your order table gets big, the solutions from Rahul and Barmar will tend to get slow.
I would hope your shop will get many orders and you will run into performance trouble ;-). So I would suggest marking the very first order of a new customer with a tinyint column, and when you have the comfort of a tinyint, you could code it like:
0 : unknown
1 : very first order
2 : order in first month
3 : order in "grown-up" mode.
The very first order you could probably mark easily, everyone loves a bright new customer enough to store this event somehow during first ordering. The other orders you can identify in a background job / cronjob by there "0" for unknown, or you mark your old customers and store the "3" on their orders.
The result-set can be achieved without any table-join or subquery:
select
if(Order_Status<>3,null,if(#first_date:=if(#prev_client_id!=Client_ID,month(date),#first_date)=month(date),"yes","no")) as Order_from_new_customer
,Order_ID,Client_ID,date,Order_Status,#prev_client_id:=client_id
from
t1,
(select #prev_client_id:="",#first_date:="")t
order by Client_ID ,date
One extra column added for computation and order by clause is used.
Verify result at http://sqlfiddle.com/#!9/83c29f/24
I have a list of dates called listings where people can signup to take part called a booking.
listings
id | date | capacity
1 2010-01-01 3
2 2010-01-02 1
3 2010-02-02 2
bookings
id | listing_id | name
1 1 Chris
2 1 Steve
3 1 Allen
4 2 Tracy
What I want to do is have a query which returns only the open listings based on the bookings.
Query would only return the listing with id = 3. Since it has no bookings and a capacity of 2.
Sample query which won't work:
SELECT
*
FROM
listings
HAVING COUNT(
SELECT * FROM bookings WHERE listings.id=bookings.listing_id
) < capacity
Any help is appreciated.
SELECT *
FROM listings
WHERE capacity > (SELECT count(*)
FROM bookings
WHERE listings.id=bookings.listing_id)
SELECT
listings.id,
max(listings.date),
max(listings.capacity)
FROM listings
left join bookings on listings.id = bookings.listing_id
group by listings.id
having COUNT(bookings.listing_id) < max(listings.capacity)
*Myself, I would do a join and then count:
SELECT COUNT(*) as count
FROM listings, bookings
WHERE listings.id=bookings.listing_id
AND count < listings.capacity
GROUP by listings.id
I haven't tested it but that's the general idea!