TABLE:
**timeslot**:
----------
id_timeslot times
1 09:00
2 09:30
3 10:00
4 10:30
5 11:00
**bookslot**
id id_timeslot date b_ref
-------------------------------------------
1 2 2010-02-22 001
2 3 2010-02-22 001
3 4 2010-02-22 001
4 5 2010-02-22 001
5 2 2010-02-25 002
6 3 2010-02-27 003
7 4 2010-02-27 003
8 5 2010-02-27 003
PHP
$q = $mysqli->query("SELECT * FROM bookslot
LEFT JOIN timeslot ON bookslot.id_timeslot = timeslot.id_timeslot
WHERE bookslot.status = 1
GROUP BY bookslot.b_ref
ORDER BY bookslot.date ASC, bookslot.id_timeslot ASC LIMIT 20");
HTML RESULT:
DATE TIMES
2010-02-22 10:30
2010-02-25 09:30
2010-02-27 11:00
anyone notice that on the table result. the times is incorrect order?
i changed another way round with ASC / DESC, and still the times showing the last id_timeslot?
EXPECTED RESULT:
DATE TIMES
2010-02-22 09:30
2010-02-25 09:30
2010-02-27 10:00
Your GROUP BY bookslot.b_ref is grouping the records, so you're only seeing the last time in each case.
Try using
SELECT date, time, MIN(bookslot.id_timeslot)
FROM bookslot
LEFT JOIN timeslot ON bookslot.id_timeslot = timeslot.id_timeslot
WHERE bookslot.status = 1
GROUP BY bookslot.b_ref
ORDER BY bookslot.date ASC, bookslot.id_timeslot ASC LIMIT 20
While your SQL is syntactically correct but it will produce unexpected results.
Normally, the columns that you SELECT must be specified in the GROUP BY clause or should be enclosed inside an aggregate function. Otherwise, MySQL will determine, at its own discretion, which records to eliminate in the GROUP BY operation. The ORDER BY does not matter because it is applied after the GROUP BY operation. You should better revise your query like this:
SELECT b_ref, MIN(ADDTIME(date, times)) AS complete_datetime
FROM bookslot
LEFT JOIN timeslot ON bookslot.id_timeslot = timeslot.id_timeslot
WHERE bookslot.status = 1
GROUP BY bookslot.b_ref
ORDER BY bookslot.date, bookslot.id_timeslot
Since the goal appears to be about collecting the earliest timeslots for each bookslot then it's required to narrow the results with MIN
SELECT b.id, b.id_timeslot, b.date, MIN(`date`) , t.times
FROM bookslot b
LEFT JOIN timeslot t ON b.id_timeslot = t.id_timeslot
GROUP BY b.b_ref
Related
I have two MySQL tables, called "accounts" and "events".
Accounts
ID
name
1
Pete
2
Josh
3
Harry
Events
ID
date
account_id
1
2021-10-09
1
2
2021-09-25
1
3
2021-10-23
2
4
2021-11-06
1
5
2021-10-13
1
6
2021-11-17
2
7
2021-11-06
3
8
2021-12-04
3
The account_id in the events table is linked to the id in the accounts table.
My question is: which query can I use to count saturdays in each month (date YYYY-mm-dd format) for each unique user in the accounts table? So I get the next result:
Name
September
October
November
December
Josh
0
1
0
0
Pete
1
1
1
0
Harry
0
0
1
1
I've tried many queries (with i.e. the (inner) JOIN, DISTINCT and GROUP BY keywords) but I don't get the exact result. Can you please help me?
Many thanks in advance!
Basically you can use DAYOFWEEK function and GROUP BY MONTH
SELECT
account_id,
MONTH(date),
COUNT(*)
FROM Events
WHERE DAYOFWEEK(date) = 7
GROUP BY account_id, MONTH(date);
SQL Fiddle here
and when you can use PIVOT on received table like:
WITH res AS (
SELECT
account_id,
MONTH(date) mnth,
COUNT(*) cnt
FROM Events
WHERE DAYOFWEEK(date) = 7
GROUP BY account_id, MONTH(date)
) SELECT
account_id,
name,
SUM(mnth=1) Januar,
--
SUM(mnth=9) September,
SUM(mnth=10) October,
SUM(mnth=11) November,
SUM(mnth=12) December
FROM res
JOIN Accounts ON Accounts.id = account_id
GROUP BY account_id, name;
SQL Pivot Fiddle
I want to fetch data of last two months of each category from table.
Table looks like:
Id
Year
month
category
value
1
2019
1
TEST1
10
2
2018
12
TEST1
10
3
2018
10
TEST1
10
4
2018
1
TEST2
10
5
2018
12
TEST2
10
6
2018
1
TEST3
10
Expected output:
Id
Year
month
category
value
1
2019
1
TEST1
10
2
2018
12
TEST1
10
5
2018
12
TEST2
10
4
2018
1
TEST2
10
6
2018
1
TEST3
10
I tried using:
SELECT a.year,a.month,a.value, a.category
FROM test_data AS a
WHERE
(
SELECT COUNT(*)
FROM test_data AS b
WHERE b.category = a.category AND (b.year >= a.year AND b.month >= a.month)) <= 2
ORDER BY a.year DESC, a.month DESC
But it is giving extra record of TEST1 category. I guess because it is not working as expected for year condition. Please provide solution for this
Your first effort should go into fixing your data model and using a date-like datatype to store the date information, rather than spreading it over different columns. This should be as simple as adding a new column to the table and updating it from the existing columns:
alter table test_data add mydate date;
update test_data set mydate = concat(year, '-', month, '-01');
That said, to make your current query work you need to fine-tune the conditions on the dates as follows. One option uses arithmetics:
SELECT a.year, a.month, a.value, a.category
FROM test_data AS a
WHERE (
SELECT COUNT(*)
FROM test_data AS b
WHERE
b.category = a.category
AND 100 * b.year + b.month >= 100 * a.year + a.month
) <= 2
ORDER BY a.year DESC, a.month DESC
Alternatively, if you are running MySQL 8.0, you can use row_number():
SELECT a.year, a.month, a.value, a.category
FROM (
SELECT
a.*,
ROW_NUMBER() OVER(PARTITION BY a.category ORDER BY a.year DESC, a.month DESC)
FROM test_data AS a
) a
WHERE rn <= 2
I have an issue. I am joining two table and can not get the proper data using MySQL.I am explaining my table below.
db_day:
day_id day_name
1 Monday
2 Tuesday
3 Wednesday
4 Thursday
5 Friday
6 Saturday
7 Sunday
db_images:
id name from_day to_day
1 Raj 1 3
2 Rahul 4 7
I am explaining my query below.
select sl.id,sl.name,sl.from_day,sl.to_day,d.day_name,d.day_id from db_images as sl left join db_day as d on d.day_id=sl.from_day sl.id desc
Here i need both from day and to day with the name after joining the table but here i am getting the from day only .Please help me to resolve this issue.
Join the db_day table twice with different alias names
select sl.id, sl.name, sl.from_day, sl.to_day,
d1.day_name as from_day, d1.day_id as from_id,
d2.day_name as to_day, d2.day_id as to_id
from db_images sl
left join db_day d1 on d1.day_id = sl.from_day
left join db_day d2 on d2.day_id = sl.to_day
I am generating mysql query to show the number of orders received in current month group by days of month.
The table structure of mysql is as follow:
order_id date
======== ==========
1234 2012-07-02
1235 2012-07-02
1236 2012-07-04
1237 2012-07-07
1238 2012-07-08
Now I want it to return following results using mysql statement
count(order_id) day
=============== ===
0 01
2 02
0 03
1 04
0 05
0 06
1 07
1 08
So on and so forth till the end of the month 30/31 depends on the days in month.
Looking forward to your suggestions and help.
Thanks.
SELECT
count(order_id),
dates.dte
FROM
(
SELECT '2011-02-01' + INTERVAL a + b DAY dte
FROM
(SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
UNION SELECT 8 UNION SELECT 9 ) d,
(SELECT 0 b UNION SELECT 10 UNION SELECT 20
UNION SELECT 30 UNION SELECT 40) m
WHERE '2011-02-01' + INTERVAL a + b DAY < '2011-03-01'
ORDER BY a + b
) dates
LEFT JOIN
orders ON orders.`date` = dates.dte
GROUP BY
dates.dte
ORDER BY
dates.dte
generate day column values in your programming language
Thanks to #The Scrum Master for nice answer here
but I also agree this shouldn't be done in database. if you think about it you actually don't need rows with 0 count.
Prepare the calendar table with a list of months and days.
To retrieve all orders from 2012-07:
select day(c.date), count(*)
from calendar c
left join orders o on c.date=o.date
where year(c.date) = 2012
and month(c.date) = 07
group by day(c.date)
I have table structure like this:
Id Name Rank Date
-----------------------------------
1 test 1000 2012-1-11
2 test 7000 2012-1-10
3 test2 2000 2012-1-11
4 test2 200 2012-1-10
5 test3 4000 2012-1-10
6 test4 6500 2012-1-11
Consider today date is 2012-1-11
Yesterday date is 2012-1-10
In single query i get the difference between the each user name for today and yesterday's date.
i.e test has 7000 rank on yesterday and 1000 on today. So the result is 6000
Similarly test2 has -1800.
I need the output as:
Name Difference (Orderby the difference Desc)
--------------------
test 6000
test2 -1800
If the today date or yesterday date's record is not available then we will not take this record to calculation.
Is this possible in PHP MySQL?
How about this? (not very clear what you are trying to achieve though..) Pleaes comment.
SQLFIDDLE DEMO
Code:
select b.id, b.name, (b.rank-a.rank) diff
from t1 a
left join t1 b
on b.date < a.date
and b.name = a.name
having not diff is null
;
Results:
ID NAME DIFF
2 test 6000
4 test2 -1800
Edit as per OP's comment:
Notice that I have added extra few records to your sample table for triggering out conditions.
SQLFIDDLE DEMO2
Code2:
select b.id, b.name,b.rank AS New,
b.Date new_date,
a.Rank as Old, a.date as old_date,
(b.rank-a.rank) diff
from t1 a
left join t1 b
on b.name = a.name
where b.date > a.date and b.date <= Now()
and datediff(b.date, a.date) = 1
having not diff is null and diff <> 0
order by diff desc
;
Results:
ID NAME NEW NEW_DATE OLD OLD_DATE DIFF
3 test 8000 January, 12 2012 1000 January, 11 2012 7000
4 test2 2000 January, 11 2012 200 January, 10 2012 1800
1 test 1000 January, 11 2012 7000 January, 10 2012 -6000
Literally everything you need is on this page
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html