I have an events table in my database, and each event can
have up to 5 different dates.
Date1 in the table is always before date2, date2 before date3 etc.
Given 2 dates in the search form, I'm trying to find the events between them.
My table is designed as follows:
id | name | date1 | date2 | date3 | date4 | date5
1 | test1 | 2013-05-24| 2013-05-25 | 0000-00-00| 0000-00-00| 0000-00-00
2 | test2 | 2013-06-01| 2013-06-08 | 2013-06-15| 2013-06-23| 2013-06-30
3 | test3 | 2013-03-15| 0000-00-00 | 0000-00-00| 0000-00-00| 0000-00-00
$datefrom , $dateto are the two variables from the search form.
Now the $datefrom for example, will always search in date1 of the table.
But $dateto has to search in date5, and if it is null to date4 and so on.
The best query I came up with so far is this:
SELECT * FROM events
WHERE
IF(date1 != '0000-00-00', IF(date1>='2012-12-19', 1, 0),0) = 1
AND CASE
WHEN date5!='0000-00-00' THEN IF(date5<='2012-12-31', 1, 0)
WHEN date4!='0000-00-00' THEN IF(date4<='2012-12-31', 1, 0)
WHEN date3!='0000-00-00' THEN IF(date3<='2012-12-31', 1, 0)
WHEN date2!='0000-00-00' THEN IF(date2<='2012-12-31', 1, 0)
END
But it is not working very well, for example this query returns rows with its oldest date being in 2013. I don't know if CASE is the right approach to begin with.
Any ideas?? Thanks for your time!
you can use it so simple with GREATEST
SELECT name , date1 date_start, GREATEST(date2,date3,date4,date5) date_end
FROM events
and will output like that
NAME DATE_START DATE_END
jack 2013-05-24 2013-05-25
peter 2013-06-01 2013-06-30
here THE DEMO SQLFIDDLE
Try this:
SELECT
id,
name
FROM
(
SELECT
id,
name,
MIN(EventDate) AS "FromDate",
MAX(EventDate) AS "ToDate"
FROM
(
SELECT id, name, date1 As "EventDate" FROM events
UNION ALL
SELECT id, name, date2 FROM events
UNION ALL
SELECT id, name, date3 FROM events
UNION ALL
SELECT id, name, date4 FROM events
UNION ALL
SELECT id, name, date5 FROM events
) t
GROUP BY id, name
) t
WHERE FromDate > #fromdate
AND ToDate < #todate;
SQL Fiddle Demo
However, if you want to get the data in the same way as it is in the events table, you can do this:
SELECT
e.*
FROM
(
SELECT
id,
name,
MIN(EventDate) AS "FromDate",
MAX(EventDate) AS "ToDate"
FROM
(
SELECT id, name, date1 As "EventDate" FROM events
UNION ALL
SELECT id, name, date2 FROM events
UNION ALL
SELECT id, name, date3 FROM events
UNION ALL
SELECT id, name, date4 FROM events
UNION ALL
SELECT id, name, date5 FROM events
) t
GROUP BY id, name
) t
INNER JOIN events e ON t.id = e.id
WHERE t.FromDate > #fromdate
AND t.ToDate < #todate;
For instance, for #fromdate = '2012-05-01' and #todate = '2012-06-15', this will give you:
| ID | NAME | DATE1 | DATE2 | DATE3 | DATE4 | DATE5 |
---------------------------------------------------------------------------------------------------
| 1 | test1 | May, 24 2013 00:00:00+0000 | May, 25 2013 00:00:00+0000 | (null) | (null) | (null) |
Related
I have two tables
orders_status_history
id | order_id | status | date
1 | 1201 | 2 | 2015-01-20
2 | 1124 | 4 | 2015-02-01
3 | 1245 | 1 | 2015-02-14
4 | 1365 | 2 | 2015-03-10
saved_shipping_invoices
id | order_id | product_id | date
1 | 1348 | 12541 | 2015-12-18
2 | 1298 | 11485 | 2016-01-02
3 | 1319 | 14521 | 2016-05-14
4 | 1441 | 10124 | 2016-05-14
and one year date range i.e.
$start_date = '2015-09-30';
$end_date = '2016-09-30';
Data in table "shipping_invoice_history" started from 2015-12-18. Now I want to break date interval on 2015-12-18. There will be two intervals now
$interval1_start = '2015-09-30';
$interval_end = '2015-12-17';
$interval2_start = '2015-12-18';
$interval2_end = '2016-09-30';
When it breaks the date interval, I want to get data from table "orders_status_history" on the first interval but on the second interval it gets data from "shipping_invoice_history" .Also I need to show the data in single table.
$week = '2015-09-30 ## 2016-09-30';
$week_ranges = explode('##', $week);
if ($week_ranges[0] > '2015-12-18' )
{
$invoices_shipped_qty = tep_db_query("SELECT * FROM `saved_shipping_invoices` WHERE `date_created` BETWEEN '".$week_ranges[0]."' AND '".$week_ranges[1]."'");
$invoices_shipped_arr = tep_db_fetch_array($invoices_shipped_qty);
$total_sent = $invoices_shipped_arr['shiped_qty'];
}
else {
$total_order_status_complete = tep_db_query("SELECT * FROM `orders_status_history` WHERE `orders_status_id` = '17' AND `date_added` BETWEEN '".$week_ranges[0]." 00:00:00' AND '".$week_ranges[1]." 23;59:59'");
$total_order_status_complete_arr = tep_db_fetch_array($total_order_status_complete);
Please suggest me how can i break date interval into two, get result from two tables and display in single run.
Probably this is what you want
select
'order_status_history' as table,
id,
order_id,
status,
null as product_id,
date from order_status_history
where
date between '2015-09-30' and '2015-12-17'
union all
select
'saved_shipping_invoices' as table,
id,
order_id,
null as status,
product_id,
date
from saved_shipping_invoices
where
date between '2015-12-18' and '2016-09-30'
Depending on how dynamic is your query, I like to do something like this instead of union.
I prefer this option:
select
if(date <='2015-12-17', 'Phase 1',
if(date >='2015-12-18', 'Phase 2',
'None')),
id,
order_id,
status,
null as product_id,
date from order_status_history
where
date between '2015-09-30' and '2016-09-30'
or
select
if(date between '2015-09-30' and '2015-12-17', 'Phase 1',
if(date between '2015-12-18' and '2016-09-30', 'Phase 2',
'None')),
id,
order_id,
status,
null as product_id,
date from order_status_history
where
date between '2015-09-30' and '2016-09-30'
i have database in which user device id and device registerd date (cr_date) stored i want to fetch list of total count of registerd devices on same day with date wise
Here below display table structure
device_ID | cr_date
--------------------
1 | 2016-06-02 18:02:13
2 | 2016-06-02 18:03:58
3 | 2016-06-02 18:04:11
4 | 2016-06-03 18:04:33
5 | 2016-06-03 18:04:33
6 | 2016-06-04 18:04:44
and i want below result
count | date
---------------------------------
3 | 2016-06-02
2 | 2016-06-03
1 | 2016-06-04
i used below query but dosent get success
SELECT device_type, count(*) AS duplicate_count
FROM (
SELECT device_type FROM tbl_app_deviceregister
GROUP BY device_type HAVING COUNT(device_type) > 0
) AS t
Did you want this;)
SELECT count(1) as `count`, date_format(cr_date, '%Y-%m-%d') as `date`
FROM tbl_app_deviceregister
GROUP BY `date`
ORDER BY `count` DESC
You should GROUP BY date value, not by device:
SELECT CAST(cr_date AS DATE) AS `date`, COUNT(device_id)
FROM tbl_app_deviceregister
GROUP BY CAST(cr_date AS DATE)
Your query doesn't seem to reference the same table structure that you've described, but from what I understand, would this work?
SELECT count(id), date_registered FROM (
SELECT
id,
DATE(FROM_UNIXTIME(cr_date)) as date_registered
FROM
tbl_app_deviceregister
) A GROUP BY date_registered
you group it by device_type which is wrong. try to group by date.
select COUNT(*) as count,CONVERT(date,cr_date) as date
from tbl_app_deviceregister
group by CONVERT(date,cr_date)
I want to compute some stats (with a MySQL backend) sorted by date and with dynamic intervals (week, month, year).
Here is a little example :
Mysql table :
tracker_click
| ID | SITE_ID | CREATED_AT |
| ---- |---------| --------------------|
| 153 | 2 | 2013-07-22 15:43:25 |
| 154 | 2 | 2013-07-25 16:45:46 |
| 2501 | 2 | 2013-09-15 17:45:48 |
I want to get the total click number by SITE_ID by week for the last month with one query
And the same thing by month for the last year.
An example of what I want by week for the last month is :
| click number | SITE_ID | BEGIN_DATE | END_DATE |
|----------------|---------|----------------------|---------------------|
| 25 | 2 | 2013-07-01 00:00:00 | 2013-07-08 00:00:00 |
| 19 | 2 | 2013-08-09 00:00:00 | 2013-08-16 00:00:00 |
| 53 | 2 | 2013-0717- 00:00:00 | 2013-08-24 00:00:00 |
I don’t know if there is a solution to get exaclty this array with only one query without any other processes.
Thank you
This should get you the counts for the last month (ie, last 4 weeks), including weeks where the count is 0 for each site id. If you have a table of sites to get the site id from it means the cross join to the sub query can be replaced with a simple cross join to a table.
This generates a range of numbers from 0 to 5 and subtracts that number of weeks from the current date, formats that to give the Sunday and Saturday of the resulting week and checks that the resuling week is a week between the current date and the current date minus 1 month (done this way rather that just subtracting 4 weeks to cope with variable length months).
SELECT Weeks.aWeek_start, Weeks.aWeek_end, all_site_id.site_id, COUNT(tracker_click.id)
FROM
(
SELECT STR_TO_DATE(DATE_FORMAT(DATE_SUB(NOW(), INTERVAL units.i WEEK), '%Y%U Sunday 00:00:00'), '%X%V %W %H:%i:%s') AS aWeek_start,
STR_TO_DATE(DATE_FORMAT(DATE_SUB(NOW(), INTERVAL units.i WEEK), '%Y%U Saturday 23:59:59'), '%X%V %W %H:%i:%s') AS aWeek_end
FROM (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5)units
WHERE DATE_FORMAT(DATE_SUB(NOW(), INTERVAL units.i WEEK), '%Y%U') BETWEEN DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y%U') AND DATE_FORMAT(NOW(), '%Y%U')
) Weeks
CROSS JOIN
(
SELECT DISTINCT site_id
FROM tracker_click
) AS all_site_id
LEFT OUTER JOIN tracker_click
ON tracker_click.CREATED_AT BETWEEN Weeks.aWeek_start AND Weeks.aWeek_end
AND tracker_click.site_id = all_site_id.site_id
GROUP BY Weeks.aWeek_start, Weeks.aWeek_end, all_site_id.site_id
A similar query could be done for months of the year
SELECT Months.aMonth_start, Months.aMonth_end, all_site_id.site_id, COUNT(tracker_click.id)
FROM
(
SELECT DATE_FORMAT(DATE_SUB(NOW(), INTERVAL units.i MONTH), '%Y/%m/01 00:00:00') AS aMonth_start,
DATE_FORMAT(LAST_DAY(DATE_SUB(NOW(), INTERVAL units.i MONTH)), '%Y/%m/%d 23:59:59') AS aMonth_end
FROM (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11)units
) Months
CROSS JOIN
(
SELECT DISTINCT site_id
FROM tracker_click
) AS all_site_id
LEFT OUTER JOIN tracker_click
ON tracker_click.CREATED_AT BETWEEN Months.aMonth_start AND Months.aMonth_end
AND tracker_click.site_id = all_site_id.site_id
GROUP BY Months.aMonth_start, Months.aMonth_end, all_site_id.site_id
SELECT count(*), site_id, extract(WEEK from created_at) as start_date,
date_add(extract(WEEK from created_at), 1, week) as end_date
FROM click_tracker
GROUP BY site_id, extract(WEEK from created_at)
and you can add where clause to filter results additionally.
I have these two tables that relate to each other with the column itemid.
I managed to make the sum of different itemid values as I show in the first example from data_table.
Now I want to relate this sum by specific dates in the other table but I can not. Please can anyone help me?
items_table
+--------+-----------+------------+
| itemid | published | publish_up |
+--------+-----------+------------+
| 1 | 1 | 02-01-2014 |
+--------+-----------+------------+
data_table
+--------+---------+------+
| itemid | fieldid | data |
+--------+---------+------+
| 1 | 27 | 5 |
| 1 | 28 | 10 |
| 1 | 29 | 5 |
+--------+---------+------+
This query is ok:
SELECT (SELECT SUM(data) FROM data_table WHERE fieldid='27')
+ (SELECT SUM(data) FROM data_table WHERE fieldid='28')
+ (SELECT SUM(data) FROM data_table WHERE fieldid='29')
But not between dates:
SELECT (SELECT SUM(data) FROM data_table WHERE fieldid='27')
+ (SELECT SUM(data) FROM data_table WHERE fieldid='28')
+ (SELECT SUM(data) FROM data_table WHERE fieldid='29')
WHERE (publish_up BETWEEN '2014-01-01 00:00:00' AND '2014-01-31 00:00:00')
FROM items_table
SELECT itemid, SUM(data)
FROM data_table JOIN items_table USING (itemid)
WHERE publish_up >= '2014-01-01'
AND publish_up < '2014-02-01'
GROUP BY itemid
I have a database with the following format:
myTable
productgroupID | productID | views | date
1 | 10 | 25 | 2013-05-23
4 | 105 | 15 | 2013-05-23
7 | 60 | 65 | 2013-05-23
7 | 60 | 55 | 2013-05-22
7 | 60 | 45 | 2013-05-21
Now I want to sum all views of a product in the moth May.
Result should be:
productgroupID | productID | viewed | month
7 | 60 | 165 | 2013-05-01
1 | 10 | 25 | 2013-05-01
4 | 105 | 15 | 2013-05-01
I tried the query below, but this gives me all views of a specific productgroupID. But I need the sum of the unique productgroupID & productID.
SELECT COUNT( views ) AS viewed, productgroupID FROM product_stats_daily GROUP BY productgroupID
If you want the views totaled, then you can use the sum() aggregate function and then you can group by the month and year for the date:
select productGroupId,
productId,
sum(views) viewed,
month(date) Month,
year(date) Year
from myTable
group by productGroupId, productId, month(date), year(date);
See SQL Fiddle with Demo
You could also use Date_Format to get the date in the format that you want:
select productGroupId,
productId,
sum(views) viewed,
DATE_FORMAT(date, '%Y-%m-01') date
from myTable
group by productGroupId, productId, DATE_FORMAT(date, '%Y-%m-01')
See SQL Fiddle with Demo
COUNT will count number of rows while SUM will sum up value of retrieved rows.
So your query becomes:
SELECT SUM( views ) AS viewed, productgroupID
FROM product_stats_daily
GROUP BY productgroupID
There's probably a more elegant way to force the date to the beginning of the month, but this should work:
SELECT
ProductGroupID,
ProductID,
SUM(views) AS viewed,
DATE_FORMAT(date, '%Y-%m-01') AS Month
FROM myTable
GROUP BY
ProductGroupID,
ProductID,
DATE_FORMAT(date, '%Y-%m-01')