How to get the number of days in period? - mysql

Storage table
| id| product_id | date_add | date_remove
------------------------------------------------------------------
| 1 | 10 |2018-04-02 08:28:43 | 2018-04-03 07:21:08
| 2 | 10 |2018-04-05 08:28:43 | 2018-04-06 08:28:50
| 3 | 10 |2018-04-01 08:28:43 | 2018-04-05 08:28:50
| 4 | 12 |2018-04-01 08:28:43 | 2018-04-03 07:21:08
| 5 | 12 |2018-04-04 08:28:43 | 2018-04-04 10:28:43
| 6 | 13 |2018-03-01 08:28:43 | 2018-03-01 10:28:43
how to find ?
how many days product was in the storage in period 2018-04-01 to 2018-04-05?
find result
| product_id | days
| 10 | 5
| 12 | 3
try
SELECT product_id, SUM(DATEDIFF(date_remove, date_add)) as days
FROM storage
where date_remove BETWEEN '2018-04-01 00:00:00'
AND '2018-04-05 23:59:59'
AND date_add BETWEEN '2018-04-01 00:00:00'
AND '2018-04-05 23:59:59'
GROUP BY product_id
but result wrong because 'SUM' sums all days
get result
| product_id | days
| 10 | 7
correct result
| product_id | days
| 10 | 5
upd
http://rextester.com/QFS96125
result 9,646805555556 but probably maximum 5 days and product_id 13 correct 0,436608796296 but result 0,87

First you want to look at all date ranges that are within or overlap with the range 2018-04-01 to 2018-04-05.
where date_add < date '2018-04-06' and date_remove >= date '2018-04-01'
Then, with the ranges found, you want to consider only their days in the range 2018-04-01 to 2018-04-05.
greatest(date_add, date '2018-04-01')
least(date_remove, date '2018-04-06')
Then you want to count days. Here you need a rule. Do you want to look at single ranges and only take their full days which you add up then? Or do you want to consider day fractions, add all up and see how many full days result? For the latter you could get durations in seconds and add these up:
select
product_id,
sum(timestampdiff(second, greatest(date_add, date '2018-04-01'),
least(date_remove, date '2018-04-06'))
) / 60 / 60 / 24 as days
from storage
where date_add < date '2018-04-06' and date_remove >= date '2018-04-01'
group by product_id
order by product_id;
This gets you
product_id | days
-----------+---------------
10 | 5,599872685185
12 | 2,036400462963
Feel free to use FLOOR, CEIL or ROUND on the resulting days.
Rextester demo: http://rextester.com/XTVU47656

To obtain such result, try
SELECT SUM(DATEDIFF(date_remove, date_add)) as days
FROM table
GROUP BY product_id
Keep in mind that this will sum all the days for the same product_id. To get the result for each id, use:
SELECT id, product_id, DATEDIFF(date_remove, date_add) as days
FROM table

Related

select item from table and order by amount on 2 days?

For example I have below table:
---------------------
| amount | date |
---------------------
| 50 | Day 1 |
| 60 | day 2 |
| 20 | day 3 |
| 25 | day 3 |
| 23 | day 4 |
| 26 | day 4 |
| 15 | day 5 |
---------------------
What I basically want to do is to retrieve item from last 2 days and order the row by max amount. so the result would be like:
---------------------
| amount | date |
---------------------
| 26 | day 4 |
| 23 | day 4 |
| 15 | day 5 |
---------------------
FYI: the date input is in 2018-06-10 14:37:44 mode above is just an example
I tried: SELECT AMOUNT FROM table WHERE AMOUNT=(SELECT MAX(AMOUNT) FROM table) ORDER BY DATE;
But the result I am getting is only | 60 | day 2 | which is the max amount and is not from 2 recent dates;
You could use the DATE_ADD function that gives you a date after a certain time alongside CURDATE() that gives you current date;
SELECT * FROM table WHERE date >= DATE_ADD(CURDATE(), INTERVAL -2 DAY)
ORDER BY amount DESC;
Try this:
SELECT amount, date FROM table WHERE date >= DATE_ADD(CURDATE(), INTERVAL -2 DAY) ORDER BY amount DESC;
-- date > DATE_ADD(CURDATE(), INTERVAL -2 DAY) will give you all rows within 2 days
-- ORDER BY amount DESC will give you ordered by amount descending

Get sales per hour

I want to get the number of sales per hour in a specific date:
table : invoices
+-------+-----------+-----------+--------------------------+
| id | name | amout | date |
+-------+-----------+-----------+--------------------------+
| 1 | John | 12313 | 2017-05-20 13:50:08 |
| 2 | Mary | 5335 | 2017-05-17 22:21:35 |
| 3 | Jeff | 23 | 2017-05-17 22:32:13 |
| 4 | Bill | 132 | 2017-05-17 23:25:55 |
| 5 | Bob | 853 | 2017-05-17 24:52:37 |
+-------+-----------+-----------+--------------------------+
So, I want to get this output:
9 a.m. to 10 a.m. we generated X invoices.
10 a.m. to 11 a.m. we generated Y invoices.
11 a.m. to 12 a.m. we generated Z invoices.
X,Y and Z it's the number of invoices generated in these interval.
How I can do that? I use MySQL.
Thanks!
Three SQL concepts will help you get an answer to this question.
"Truncating" a datestamp; that is, extracting the hour from it. For example, 2017-05-27 14:37.20 is truncated to 2017-05-27 14:00:00.
Selecting rows from your table with datestamps on a particular day.
Using COUNT(*) and GROUP BY.
You can truncate like this.
SELECT DATE_FORMAT(`date`, '%y-%m-%d %H:00:00') hour_starting
FROM invoices
You can add to that query to select rows for a particular date like this
SELECT DATE_FORMAT(`date`, '%y-%m-%d %H:00:00') hour_starting
FROM invoices
WHERE `date` >= '2017-05-27`
AND `date` < '2017-05-27' + INTERVAL 1 DAY
Notice that this chooses all rows with date values on or after (>=) midnight on 2017-05-27. and before but not including (<) midnight on the next day.
Finally, you can use COUNT like this.
SELECT DATE_FORMAT(`date`, '%y-%m-%d %H:00:00') hour_starting,
COUNT(*) invoice_count
FROM invoices
WHERE `date` >= '2017-05-27`
AND `date` < '2017-05-27' + INTERVAL 1 DAY
GROUP BY DATE_FORMAT(`date`, '%y-%m-%d %H:00:00')

Selecting the last record of yesterday and all records of today in single query

I know it's possible to get yesterday records, most common way using SUBDATE(CURDATE(), 1) or maybe simply use CURDATE() - 1 and use LIMIT and ORDER to retrieve the last record of yesterday.
But here, I need to get the last record of yesterday in the first row and the rest will be all records of today. I need to run this within single query.
For example, I have following records in one of my table:
--------------------------------------------------
| value | created_at |
--------------------------------------------------
| 70 | 1/1/2017 |
| 300 | 1/1/2017 |
| 100 | 1/1/2017 |
| 235 | 1/2/2017 |
| 45 | 1/2/2017 |
--------------------------------------------------
The created_at column is a timestamp, if today is 1/2/2017 (2th January 2017) then the result of the query should be:
--------------------------------------------------
| value | created_at |
--------------------------------------------------
| 100 | 1/1/2017 |
| 235 | 1/2/2017 |
| 45 | 1/2/2017 |
--------------------------------------------------
So far, I only able to retrieve the records of today with following query:
SELECT * FROM my_table WHERE created_at >= CURDATE();
What query I need to accomplish this?
Hoping you have id as primary key
select * from
(select
*
from
tbl
where date(created_at) =date(DATE_ADD(now(), INTERVAL -1 DAY))
order by id desc limit 0,1
)tmp
UNION
select * from tbl where date(created_at)=date(now())

Select entries by day over the last 7 days

I want to get the count of the registered users in the past 7 days, grouped.
+-----+------------+--------------+
| id | username | created |
+-----+------------+--------------+
| 1 | Vlad | 1360168194 |
+-----+------------+--------------+
| 2 | Test | 1360168194 |
+-----+------------+--------------+
This is my table. I want to have 7 rows of results with the date of the day, and count(id) as the result for the users that registered.
I tried different solutions and none of them really fitted my needings. Are there any ideas?
SELECT DATE(FROM_UNIXTIME(columName)), COUNT(ID) totalCOunt
FROM tableName
WHERE DATE(FROM_UNIXTIME(columName)) BETWEEN CURDATE() + INTERVAL -7 DAY AND CURDATE()
GROUP BY DATE(FROM_UNIXTIME(columName))
SQLFiddle Demo
Other Source(s)
MySQL Date and Time Functions

sql query with current day comparison

I have a mysql table with a due_date field which is simply an integer value.
dealID | due_day
1 | 15
2 | 25
3 | 10
4 | 9
5 | 31
6 | 20
I would like to query this table to only display the data that would be 14 days before the due_day. For example, today is 01/05/13, if I query this table it should only show me dealID 1, 3 and 9. How should I go about this condition?
You can do that simply using DATE_SUB to substract the number of days from current date and then DAYOFMONTH to get the day.
You can create the query using the mentioned functions.
So based on user1951544's answer this is what I came up with.
SELECT due_day
FROM deals
WHERE (due_day - DAYOFMONTH( NOW( ) ) ) <=14
Query:
SQLFIDDLEExample
SELECT
dealID,
due_day
FROM Table1
WHERE due_day < 14 + DAYOFMONTH( NOW( ) )
Result:
| DEALID | DUE_DAY |
--------------------
| 1 | 15 |
| 3 | 10 |
| 4 | 9 |