php and mysql get data by year and date wise! table structure? - php

While making a sample details page, I just stuck upon a really confusing situation. What i actually want to do is like this:
+----------------------------------------------------+
+ Year | Month | Date | Total Gain +
+----------------------------------------------------+
+ 2003 | January | 26/01/2003 | +90 % +
+ 2003 | January | 27/01/2003 | +10 % +
+ 2003 | Feburary| 01/02/2003 | -29 % +
+ 2003 | Feburary| 15/02/2003 | +0.52 % +
+----------------------------------------------------+
What I actually want is that I can list the Month names and year wise like mysql_query('SELECT month FROM mytable WHERE year="2003"');
But the problem is it shows January two time. I want to display January one time and a link next to it which will carry to the next page. This will show the stats of January.

Maybe you should use a GROUP BY clause and calculates your Total gain as well.
(Since the table structure is not specified, I'll guess here)
SELECT `Year`, `Month`, SUM(gain) AS 'Total Gain +' FROM table GROUP BY month, year;

I think what youre looking for is DISTINCT query, ie
SELECT DISTINCT year, month FROM mytable

Related

This SQL cannot cross a 'year end' boundary

This SQL is called by a Smarty File designed to download an .xlsx of the output. It works well for all months EXCEPT the Dec. (end of year) report. Something is needed to get it to cross the year-end boundary but I can't figure what. ? Thanks.
SELECT user_id, cert_name, from_email, created_at, phone as role,
delivery, user_street, user_city, user_state, user_zip,
user_country_id, standard_fee, expedited_fee
FROM support_tickets
WHERE nature = 2
AND user_id IS NOT NULL
AND created_at BETWEEN '2012-12-05 04:00:01' and date(concat_ws('-', #year, #month + 1, 1))
ORDER BY created_at DESC
Use date arithmetic, not string concatenation.
If you try to add #month+1 when month is 12, you get month 13, not month 1 of the next year. There is no month 13 in calendars currently in use.
For your case I would recommend using the LAST_DAY() function that is built into MySQL. This returns the last date in the current month of its argument.
Example:
mysql> SELECT LAST_DAY('2020-12-05') AS last;
+------------+
| last |
+------------+
| 2020-12-31 |
+------------+
I suspect you want the last day of the same month.
If you really want the first day of the next month, use date arithmetic:
mysql> SELECT LAST_DAY('2020-12-05') + INTERVAL 1 DAY AS next;
+------------+
| next |
+------------+
| 2021-01-01 |
+------------+

convert timestamp to month in codeigniter [duplicate]

I have this certain problem about mysql date functions.
I'm trying to compare the value of THIS MONTH to the given timestamp in database.
For example, month today is june, and the timestamp is 1369967316
And I'm trying to determine if that timestamp is in month of june.
$query = db_query("SELECT * FROM users WHERE MONTH(FROM_UNIXTIME(CURDATE())) = MONTH(1369967316)");
//count total members this mont
$members_month = $query->rowCount();
so if I used the rowCount, the $members_month should have the value of 1.
Unfortunately it doesn't work.
Any help would be appreciated.
Well I saw some answers that some kind of relevant to mine but it doesn't hit the spot or I didn't applied it well.
mysql get month from timestamp not working
how to use curdate() in where clause against unixtimestamp (bigint) column
This works for me:
mysql> SELECT MONTH(FROM_UNIXTIME(1369967316));
+----------------------------------+
| MONTH(FROM_UNIXTIME(1369967316)) |
+----------------------------------+
| 5 |
+----------------------------------+
Your issue is likely coming from the fact that 1369967316 is May 30th, not June (as you expect), thus resulting in an inequality with MONTH(CURDATE()).
mysql> SELECT FROM_UNIXTIME(1369967316);
+---------------------------+
| FROM_UNIXTIME(1369967316) |
+---------------------------+
| 2013-05-30 22:28:36 |
+---------------------------+

age range for date of birth

Good day guys. i have here my code its in mysql format eventhough i know it's depreciated, so i'm only focusing on how to get total number of my data in database via age range.
my table structure for outputting
age range |Male |Female | Total
0-4 | | |
5-9 | | |
so on.. | | |
total | | |
my code
//for 0-4 age range
SELECT count(*) as total FROM data WHERE gender='male' and dob BETWEEN CURDATE() - INTERVAL 4 YEAR AND CURDATE() - INTERVAL 0 YEAR";
//for 5-9 age range
SELECT count(*) as total FROM data WHERE gender='male' and dob BETWEEN CURDATE() - INTERVAL 9 YEAR AND CURDATE() - INTERVAL 5 YEAR";
i manage to get all the total in every age range of both male and female but when i count it manually it is not exact from the total row below. Please
help me out of this problem, im just a newbie in php and mysql so i'm going to learn more . thanks a lot :)

PHP MYSQL - Impossible Query? - Find "currently showing"

I have a table with a kind of weird date format in a column as varchar - this is the format that the company has provided me with - the T in the middle seems to mess things up.
EVENTID | EVENT_DATE | EVENT_DURATION
1 | 2012-10-14T06:00 | 15
2 | 2012-10-14T06:15 | 11
3 | 2012-10-14T06:26 | 14
4 | 2012-10-14T06:40 | 10
ect...ect
I have php code to return the current time in the exact same format (with the weird 'T' in the middle'
$thisin = DateTime::createFromFormat('Y-m-d\TH:i', date('Y-m-d\TH:i'));
$thisin->setTimeZone(new DateTimeZone('UTC'));
$thisout= $thisin->format('Y-m-d\TH:i');
Assuming that today is the 14th and the current time is 06:21, how do i query the current row based on duration that matches "$thisout from php" and the next five rows (in the future).
Because the current time and date are returned from php as "2012-10-14T06:21" The query should output
2 | 2012-10-14T06:15 | 11 (Now SHowing)
3 | 2012-10-14T06:26 | 14
4 | 2012-10-14T06:40 | 10
ect ect
I have been scratching my head for hours, DATE_FORMAT() Doesn't seem to work, and I think it may be the T in the middle. I am aslo have to figure out how to use duration to determine if the current time applies to a specific row.
This does not work
SELECT DISTINCT EVENTID, EVENT DATE, EVENT_DURATION
FROM epg_event
WHERE DATE_FORMAT(EVENT_DATE, '%Y-%m-%dT%H:%i') >= DATE_FORMAT(NOW(), '%Y-%m-%dT%H:%i')
ORDER BY EVENT_DATE ASC LIMIT 5
Any Ideas?
You should load the date information into a Date column rather than a varchar column in the database. As previously noted this is the ISO format for dates.
Need to add in the interval.
where event_date + INTERVAL duration MINUTE >= NOW()
I'm not currently able to test it, but something like this might work:
SELECT DISTINCT EVENTID, EVENT_DATE, EVENT_DURATION
FROM epg_event
WHERE (event_date <= NOW()) AND (ADDTIME(event_date, INTERVAL event_duration MINUTE) >= NOW())
ORDER BY event_date ASC LIMIT 5
DATE_FORMAT() is meant for formatting a DATETIME field, not the other way around. And, as mentioned earlier, you event_date should be a DATETIME field and you should convert the time when you import the data to your database.

How to find exact seasons and days from a given date range?

I need this for rent a car price calculation. Cars prices are different according to seasons.
I have a season_dates table like this
id slug start end
1 low 2011-01-01 00:00:00 2011-04-30 00:00:00
2 mid 2011-05-01 00:00:00 2011-06-30 00:00:00
3 high 2011-07-01 00:00:00 2011-08-31 00:00:00
4 mid 2011-09-01 00:00:00 2011-10-31 00:00:00
5 low 2011-11-01 00:00:00 2011-12-31 00:00:00
Users selecting days, for example:
start_day 08/20 end_day 08/25
My query like that:
SELECT * from arac_donemler
where DATE_FORMAT(start, '%m/%d') <= '08/20'
and DATE_FORMAT(end, '%m/%d') >= '08/25'
This gives me high season that's correct.
But what I couldn't handle is: what if user selects a date range between 2 seasons?
For example from 20 August to 05 September.
This time I have to find that date ranges belongs to which seasons?
And I have to calculate how many days per each seasons?
For the example above,
high season ending at 31 August. So 31-20 = 11 days for high season, 5 days for mid season.
How can I provide this separation?
I hope I could explain it.
I tried so many things like join table inside but couldn't succeed it.
I'll let others chime in with the right way to do date comparisons in SQL (yours almost certainly kills indexing for the table), but for a start, you can get exactly the seasons that are relevant by
select * from arac_donemler
where end >= [arrival-date]
and start <= [departure-date]
Then you should do the rest of your processing (figure out how many days in each season and so forth) in the business logic instead of in the database query.
I would store all single days within a table.
This is a simple example.
create table dates (
id int not null auto_increment primary key,
pday date,
slug tinyint,
price int);
insert into dates (pday,slug,price)
values
('2011-01-01',1,10),
('2011-01-02',1,10),
('2011-01-03',2,20),
('2011-01-04',2,20),
('2011-01-05',2,20),
('2011-01-06',3,30),
('2011-01-07',3,30),
('2011-01-08',3,30);
select
concat(min(pday),'/',max(pday)) as period,
count(*) as days,
sum(price) as price_per_period
from dates
where pday between '2011-01-02' and '2011-01-07'
group by slug
+-----------------------+------+------------------+
| period | days | price_per_period |
+-----------------------+------+------------------+
| 2011-01-02/2011-01-02 | 1 | 10 |
| 2011-01-03/2011-01-05 | 3 | 60 |
| 2011-01-06/2011-01-07 | 2 | 60 |
+-----------------------+------+------------------+
3 rows in set (0.00 sec)
EDIT. Version with grandtotal
select
case
when slug is null then 'Total' else concat(min(pday),'/',max(pday)) end as period,
count(*) as days,
sum(price) as price_per_period
from dates
where pday between '2011-01-02' and '2011-01-07'
group by slug
with rollup;
+-----------------------+------+------------------+
| period | days | price_per_period |
+-----------------------+------+------------------+
| 2011-01-02/2011-01-02 | 1 | 10 |
| 2011-01-03/2011-01-05 | 3 | 60 |
| 2011-01-06/2011-01-07 | 2 | 60 |
| Total | 6 | 130 |
+-----------------------+------+------------------+
4 rows in set (0.00 sec)
edit. Stored procedure to populate table
delimiter $$
create procedure calendario(in anno int)
begin
declare i,ultimo int;
declare miadata date;
set i = 0;
select dayofyear(concat(anno,'-12-31')) into ultimo;
while i < ultimo do
select concat(anno,'-01-01') + interval i day into miadata;
insert into dates (pday) values (miadata);
set i = i + 1;
end while;
end $$
delimiter ;
call calendario(2011);
If you have a table RENTAL too (the real version would need a lot of other details in it):
CREATE TABLE Rental
(
start DATE NOT NULL,
end DATE NOT NULL
);
and you populate it with:
INSERT INTO rental VALUES('2011-08-20', '2011-09-05');
INSERT INTO rental VALUES('2011-08-20', '2011-08-25');
then this query produces a plausible result:
SELECT r.start AS r_start, r.end AS r_end,
s.start AS s_start, s.end AS s_end,
GREATEST(r.start, s.start) AS p_start,
LEAST(r.end, s.end) AS p_end,
DATEDIFF(LEAST(r.end, s.end), GREATEST(r.start, s.start)) + 1 AS days,
s.id, s.slug
FROM rental AS r
JOIN season_dates AS s ON r.start <= s.end AND r.end >= s.start;
It yields:
r_start r_end s_start s_end p_start p_end days id slug
2011-08-20 2011-09-05 2011-07-01 2011-08-31 2011-08-20 2011-08-31 12 3 high
2011-08-20 2011-09-05 2011-09-01 2011-10-31 2011-09-01 2011-09-05 5 4 mid
2011-08-20 2011-08-25 2011-07-01 2011-08-31 2011-08-20 2011-08-25 6 3 high
Note that I'm counting 12 days instead of 11; that's the +1 in the days expression. It gets tricky; you have to decide whether if the car is returned on the same day as it is rented, is that one day's rental? What if it is returned the next day? Maybe the time matters? But that gets into detailed business rules rather than general principles. Maybe the duration is the larger of the raw DATEDIFF() and 1? Also note that there is only the rental start and end dates in this schema to identify the rental; a real schema would have some sort of Rental Agreement Number in the rental table.
(Confession: simulated using IBM Informix 11.70.FC2 on MacOS X 10.7.1, but MySQL is documented as supporting LEAST, GREATEST, and DATEDIFF and I simulated those in Informix. The most noticeable difference might be that Informix has a DATE type without any time component, so there are no times needed or displayed.)
But [...] seasons period always same every year. So I thought to compare only days and months. 2011 isn't important. Next years just 2011 will be used. This time problem occurs. For example low season includes November, December and then go to January, February, March, April. If a user selects a date range 01.05.2011 to ...2011 There is no problem. I just compare month and day with DATE_FORMAT(end, '%m/%d'). But if he chooses a range from December to next year January, how am I gonna calculate days?
Notice that 5 entries per year in the Season_Dates table is not going to make an 8" floppy disk break sweat over storage capacity for a good few years, let alone a 500 GiB monster disk. So, by far the simplest thing is to define the entries for 2012 in 5 new rows in the Season_Dates table. That also allows you to handle the fact that in December, the powers-that-be decide the rules will be different (20th December to 4th January will be 'mid', not 'low' season, for example).

Categories