Complex Queries range dates - php

mySQL dateTime range Query Issue
how get count of proceser in 2017 by same date like 2017-08-07
date | name
-----------------------
2017-08-31 | amr
-----------------------
2017-08-05 | ahmed
----------------- -----
2018-08-08 | moh
how get 2017-01-01 BETWEEN 2017-12-31
------------------------
count | date
-----------------------
2 | 2017
-----------------------
1 | 2018
SELECT count(*)
FROM item WHERE
date IN
( SELECT date
FROM item WHERE
(BETWEEN '2017-03-15' AND '2017-09-31'))

I couldn't find a duplicate for you, but I am sure there is one somewhere.
If you use GROUP BY and the DATE_FORMAT() function, you can COUNT() the occurrences in each group.
SELECT COUNT(*),DATE_FORMAT(`date`,'%Y') FROM `item` GROUP BY DATE_FORMAT(`date`,'%Y');
You can include a WHERE clause before GROUP BY if you need to omit certain ranges of time.

1, date is a reserved MySQL word. It would be best to name your column something else, but you can use it if you also specify the table name like table.date
2, there is no need for a sub-query. MySQL can do this in one query
SELECT count(`table.name`) as NUMBER, YEAR(`table.date`) as YR FROM item WHERE DATE(`table.date`) BETWEEN '2017-01-01' AND '2017-12-31'

BETWEEN is kind of a "ternary" operator, of the form x BETWEEN y AND z
You want:
`date` BETWEEN '2017-03-15' AND '2017-09-31'

Related

How to order DATETIME rows with [] in MySQL

I have a mysql "users" table like this example:
id | user | created
100 | user001 | [27-01-2016 04:30 PM]
101 | user005 | [19-05-2017 09:28 AM]
102 | user019 | [09-10-2015 03:29 PM]
103 | user029 | [18-11-2017 05:40 PM]
And I want to get this table in descending order by created row like this:
id | user | created
103 | user029 | [18-11-2017 05:40 PM]
101 | user005 | [19-05-2017 09:28 AM]
100 | user001 | [27-01-2016 04:30 PM]
102 | user019 | [09-10-2015 03:29 PM]
I tried with DATE_FORMAT:
SELECT id,user,DATE_FORMAT(created,"%d %m %Y") AS created FROM users ORDER by created desc
But it shows nothing, how can I get it?
I'd like some help.
This works:
SELECT `id`, `user`, DATE_FORMAT(STR_TO_DATE(MID(`created`, 2, 19), '%d-%m-%Y %h:%i %p'), '%d-%m-%Y %h:%i %p')
AS `created:` FROM `users` ORDER BY STR_TO_DATE(`created:`,'%d-%m-%Y %h:%i %p') DESC
Here is a working SQL Fiddle.
Explanation:
The MID() MySQL function returns the middle part of a string, so we easily stripped out the []. After that, the STR_TO_DATE() function parses the returned string into DATETIME format (the %p is for AM/PM). The returning value is not properly formatted, at least not in the way you would wish to have it. So we then use DATE_FORMAT() to format the output. In the end, we use STR_TO_DATE() once again for the ordering since created: is returned as string.
I also changed your created output column to created: since it will not work if they are all the same name.
Your created date format isn't correct, you should alter the table and change the field from varchar/char(string) to timestamp type. I have already tried converting your string dates with 'STR_TO_DATE()' but it returns null because the format doesn't match either timestamp, date or time formats. Its always best practice to store dates/datetime as either date or timestamp data types. You can always apply formatting functions later in query to output dates to any desired format.

Get only one record from a same date records in the collection - Laravel

Is there a way I could retrieve only one record from date records with the same value in the collection?
My records goes like this,
id | date | event_name | type
----------------------------------------
1 | 2016-01-23 | event 1 | event 1
2 | 2016-01-23 | event 1 | event 2
3 | 2016-03-15 | event 2 | event 1
4 | 2016-03-15 | event 2 | event 2
So as you can see, there are records with same date and I want to fetch only one on that same date records. So I expect to get,
2016-01-23, event 1
2016-03-15, event 2
I tried,
$events = events::select( events.*',
DB::raw('(select date from events where date = events.date) as events'))
->get();
but unfortunately its not working. It gives me an empty array from
dd(var_dump($events->toArray()));
Any ideas, help please?
The actual query:
SELECT * FROM events GROUP BY date
For Laravel:
$events = DB::table('events')->groupBy('date')->get();
If you simply want to get one result for every redundant date value in your table, then use the DISTINCT keyword in your query.
Try this if you are using MySql:
select DISTINCT date from events where date IS NOT NULL
Note: DISTINCT considers null value also as a distinct candidate. So, it's advisable to check for null on your where clause.
Also, DISTNCT is faster than Group By.
If using Eloqunt, you can use the built in groupBy method:
Events::groupBy('browser')->get();

Date format in SQL query

i have table:
Birthday
id | name | date
1 | aaa | 1990-03-02
2 | bbb | 1990-03-12
3 | ccc | 1990-03-25
4 | ddd | 1990-04-25
5 | eee | 1990-04-23
6 | fff | 1990-04-26
7 | ggg | 1990-04-12
How is the best way to SELECT all names where date is 1990-04-xx?
SELECT name FROM table WHERE date LIKE '1990-04%'
Some other answers here are assuming you're storing the date in a datefield, but I assumed by the way it was laid out in your question that it was just a string. Going on that assumption, I knew that using the LIKE operator would let me use a wildcard (the % sign) to search for anything with that year and month. That said, this query will match anything that starts with 1990-04 so there is a possibility with malformed data that you could get some incorrect data (e.g. a date is entered into the database like '1990-041-12')
If it's a DATE value I'd suggest checking if it's between the beginning and the end of the month. If you chop up the date using DATE_FORMAT or some other function you'll lose any chance of optimization:
SELECT name FROM myTable WHERE `date` BETWEEN '1990-04-01' AND '1990-04-30'
If it's a DATETIME value, do this instead to account for values like 4/30/1990 at 9PM:
SELECT name FROM myTable WHERE `date` >= '1990-04-01' AND `date` < '1990-05-01'
If date is a DATE or DATETIME or TIMESTAMP column and you want an index to have chances to be used:
SELECT name
FROM tableX
WHERE date >= '1990-04-01'
AND date < '1990-05-01' ;
An index on (date) would be good. Even better, an index on (date, name).

SQL getting monthly totals from table

I have a table with prices, date as a timestamp, the month of entry and the year of entry.
+++++++++++++++++++++++++++++
Price | Date | Month | Year |
+++++++++++++++++++++++++++++
9.00 |343345| 2 | 2013 |
3.00 |343445| 2 | 2013 |
4.00 |343245| 1 | 2013 |
1.00 |342245| 1 | 2013 |
5.00 |333355| 12 | 2012 |
So far I have this to list the monthly price totals, the problem is GROUP BY re-sorts the results so that it goes month 1, month 12 then month 2 where as I need the results to descend from the current month, month-by-month.
"SELECT month,SUM(price), FROM table GROUP BY month ORDER BY date DESC "
I'm using PHP if that helps.
It's treating your month as text instead of numeric. Cast it as an integer and it'll sort properly.
SELECT CAST(Month as int) as Month, SUM(PRICE), FROM table Group by month ORDER BY CAST(MONTH as int) desc
The problem is your date field is not stored as a datetime. Instead of ordering by it, order by your year and month fields instead (I presume you want to group by both of those fields).
SELECT year,month,SUM(price)
FROM table
GROUP BY year,month
ORDER BY year DESC, month DESC
If the year and/or month are stored as varchar, then cast them -- I suspect those are stored as integers though:
Cast your month to INT data type:
SELECT month,SUM(price), SUM(price), FROM table GROUP BY month ORDER BY cast(month as UNSIGNED) DESC
More: CAST
I had similar problem. I solved it by adding another column with 'date' type and convert all the different fields in dates. Then you can make selects within time range.

compare between two dates

i have a course table and a course due dates table like this
course_id | course_name
1 A
2 B
due_id | start_date | end_date course_id
1 2011-02-01 2011-02-28 1
2 2011-03-01 2011-03-15 1
now what i am trying to do from last tow day that write a query or code that will show a course name with current date session.for example if current date is betwen start and end date course should come like this and if its in next date session it should come with next due_id
course_id | course_name | due_id
1 A | 1
if this database structure is wrong for this please let me know
thanks for help
SELECT course.course_name, due_dates.course_id, due_id
FROM course
INNER JOIN due_dates ON course.course_id = due_dates.course_id
WHERE now() BETWEEN start_date and end_date;

Categories