SELECT date( `captureTime` ) dateDay, DATE_FORMAT( `captureTime` , '%H' ) dateHour, DATE_FORMAT( `captureTime` , '%i' ) dateQuarter, max( channel1_Data ) , max( channel2_Data ) , max( channel3_Data ) , min( channel1_Data ) , min( channel2_Data ) , min( channel3_Data )
FROM `sensordata`
WHERE `Sensor_sensorSerialNo` =1
AND `captureTime` >= '2011-10-16 22:15:11'
AND `captureTime` <= '2011-10-17 23:59:59'
I want to get all data from 2011-10-16 22:15:11 to 2011-10-17 23:59:59 after running the select query. And the 'captureTime' column also need be divided into three columns(i.e. 'dateDay', 'dateHour' and 'dateQuater'). However, only get one row result after running the above query. I can't see anything wrong there.
Can anyone point out the errors? Thanks in advance!
min, max functions are aggregate functions and are usually used with Group By clause. However If you are not using Group By clause then Min or Max value will be returned after performing calculation on complete table data. So, only one row should be returned, that would be minimum or maximum. If you want other columns to be selected, then those columns must be present in Group By clause.
MySql allowed this query to execute, but other dbms such as SQLServer wont even allow this query to be executed.
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html
Try using like:
SELECT date( `captureTime` ) as "dateDay", DATE_FORMAT( `captureTime` , '%H' ) as "dateHour", DATE_FORMAT( `captureTime` , '%i' ) as "dateQuarter", max( channel1_Data ) , max( channel2_Data ) , max( channel3_Data ) , min( channel1_Data ) , min( channel2_Data ) , min( channel3_Data ) FROM `sensordata` WHERE `Sensor_sensorSerialNo` =1 AND `captureTime` >= '2011-10-16 22:15:11' AND `captureTime` <= '2011-10-17 23:59:59'
Related
SELECT COUNT( uid ) AS `Records` , DATE( FROM_UNIXTIME( 'since` ) ) AS `Date`
FROM `accounts` WHERE FROM_UNIXTIME(since) >= FROM_UNIXTIME($tstamp)
GROUP BY WEEK( FROM_UNIXTIME( `since` ) )
LIMIT 200
Was using this to try to get the New user signups daily from a specified date but its turning out to be incredibly inaccurate. Which means either my query is off or possibly there is some issue involving timezones?Below is a example result I got from a example data set I loaded in as well as a page worth of timestamps so you can see what the results should be.
It is suggested to use HAVING instead of WHERE with GROUP BY clause.
Also the backtick(`) operator is not used properly in this code.
So change this query:
SELECT COUNT( uid ) AS Records , DATE( FROM_UNIXTIME( 'since` ) ) AS `Date`
FROM `accounts` WHERE FROM_UNIXTIME(since) >= FROM_UNIXTIME($tstamp)
GROUP BY DATE( FROM_UNIXTIME( `since` ) )
LIMIT 200
to this one:
SELECT COUNT(`uid`) AS Records , DATE( FROM_UNIXTIME(`since`) ) AS Date
FROM accounts
GROUP BY DATE( FROM_UNIXTIME( `since` ) )
HAVING FROM_UNIXTIME(`since`) >= FROM_UNIXTIME($tstamp)
LIMIT 200
Alright I have tried alot and this looks just about right for me , but its def not:
SELECT COUNT( DISTINCT 'uid' ) AS `Records` , DATE( FROM_UNIXTIME( `epoch_timestamp` ) ) AS `Date`
FROM `log`
GROUP BY DATE( FROM_UNIXTIME( `epoch_timestamp` ) )
LIMIT 0 , 30
For w.e reason it returns a 1 next to each date. If I take out the distinct it appears to give a total records for that day count.
Seems like your sql is incorrect, try replacing the single quotation marks around 'uid' with `.
SELECT COUNT( DISTINCT `uid` ) AS `Records` , DATE( FROM_UNIXTIME( `epoch_timestamp` ) ) AS `Date`
FROM `log`
GROUP BY DATE( FROM_UNIXTIME( `epoch_timestamp` ) )
LIMIT 0 , 30
with this query i aim to retrieve data from another table in a subquery where arguments compare unixtime stamp. But the result in my third columne ('valid') remains empty?
SELECT COUNT( valid.call_id )FROM calls AS valid WHERE SECOND((
SELECT conf.cca_setvalidtime FROM user_conf AS conf
WHERE MONTH(FROM_UNIXTIME(conf.activ_date)) = MONTH(FROM_UNIXTIME(valid.last_call ))
)) < SECOND( valid.call_duration )
) AS 'valid'
FROM calls
GROUP BY EXTRACT(
YEAR_MONTH FROM last_call )
Here is the Solution for anyone who can need something alike ;-)
SELECT DATE_FORMAT( last_call, '%M' ) AS 'month', COUNT( call_id ) AS 'total', (
SELECT COUNT( valid.call_id )
FROM calls AS valid
WHERE TIME((
SELECT conf.cca_setvalidtime FROM user_conf AS conf
WHERE EXTRACT(YEAR_MONTH FROM conf.activ_date ) = EXTRACT(YEAR_MONTH FROM valid.last_call ) AND conf.for_role=1
)) < TIME( valid.call_duration )
AND EXTRACT(
YEAR_MONTH FROM valid.last_call ) = EXTRACT(
YEAR_MONTH FROM calls.last_call )
) AS 'valid'
FROM calls
GROUP BY EXTRACT(
YEAR_MONTH FROM last_call )
SELECT MAX( PRC_MIN_LENGTH ) PRC_MIN_LENGTH, MIN( PRC_MAX_LENGTH ) PRC_MAX_LENGTH, MAX( PRC_MIN_WIDTH ) PRC_MIN_WIDTH, MIN( PRC_MAX_WIDTH ) PRC_MAX_WIDTH
FROM (
SELECT PRDT_PRICE_CODE, MIN( PRC_MIN_LENGTH ) PRC_MIN_LENGTH, MAX( PRC_MAX_LENGTH ) PRC_MAX_LENGTH, MIN( PRC_MIN_WIDTH ) PRC_MIN_WIDTH, MAX( PRC_MAX_WIDTH ) PRC_MAX_WIDTH
FROM PRODUCT_PRICE_INFO
WHERE PRDT_PRICE_CODE
IN (
SELECT PRDT_PRICE_CODE
FROM PRODUCT
WHERE PRODUCT_ID =1
UNION SELECT PRDT_PRICE_CODE
FROM PRODUCT_OPTION
WHERE PROD_OPT_ID
IN (
'1', '101', '201', '303', '401'
)
)
AND CURDATE( )
BETWEEN DATE_SUB( CURDATE( ) , INTERVAL 1
DAY )
AND DATE_ADD( CURDATE( ) , INTERVAL 1
DAY )
GROUP BY PRDT_PRICE_CODE
)PRC_RANGE
This query is running in MySQL database but not in SQLite.
Where is the mistake and how can I fix this?
SQLite uses different date functions.
You would have to write the date comparison like this:
...
AND date('now') BETWEEN date('now', '-1 days')
AND date('now', '+1 days')
...
(This is a faithful translation, and will make the query run; but it's doubtful that this query does what you want in either MySQL or SQLite.)
My query is like this:
SELECT date_format( created_at, '%Y-%m-%d' ) AS the_date,
COUNT(s.id) AS total,
(SELECT COUNT(ks.id) FROM kc_shares ks WHERE site = 'facebook' AND date_format( created_at, '%Y-%m-%d' ) = the_date ) AS total_facebook,
(SELECT COUNT(ks.id) FROM kc_shares ks WHERE site = 'twitter' AND date_format( created_at, '%Y-%m-%d' ) = the_date ) AS total_twitter
FROM `kc_shares` s
GROUP BY `the_date`
What I want to get is the number of daily shares with the specification of total, total shares to facebook (thus site = 'facebook') and total shares to twitter. That's why I need the GROUP BY.
When it had, like, a few thousands rows, there's no problem. But the table currently has almost 200,000 rows, and the query is very slow, taking about 20-30 seconds, even more I guess.
I've tried adding indices to site and created_at fields but to no avail.
Thanks
I think the sub queries are eating up performace. So maybe you can do something like this:
SELECT
date_format( created_at, '%Y-%m-%d' ) AS the_date,
COUNT(s.id) AS total,
SUM(CASE WHEN s.site='facebook' THEN 1 ELSE 0 END) AS total_facebook,
SUM(CASE WHEN s.site='twitter' THEN 1 ELSE 0 END) AS total_twitter
FROM
`kc_shares` s
GROUP BY
`the_date
`
Move the subselects so you join against them, rather that doing a subselect for every returned row.
Something like this (untested):-
SELECT date_format( created_at, '%Y-%m-%d' ) AS the_date,
COUNT(s.id) AS total,
Sub1.total_facebook, Sub2.total_twitter
FROM `kc_shares` s
LEFT OUTER JOIN (SELECT date_format( created_at, '%Y-%m-%d' ) AS sub_date, COUNT(ks.id) AS total_facebook FROM kc_shares ks WHERE site = 'facebook' GROUP BY sub_date ) Sub1 ON date_format( created_at, '%Y-%m-%d' ) = Sub1.sub_date
LEFT OUTER JOIN (SELECT date_format( created_at, '%Y-%m-%d' ) AS sub_date, COUNT(ks.id) AS total_twitter FROM kc_shares ks WHERE site = 'twitter' GROUP BY sub_date ) Sub2 ON date_format( created_at, '%Y-%m-%d' ) = Sub2.sub_date
GROUP BY `the_date`
Although finding a way to do a join on a non derived column (ie the date part of the date / time) would also help. Possibly a good case here for a bit or denormalisation, adding a field for just the date in addtion to the date / time currently stored.
An alternative would be to change the way the query works. The following would provide rows for each day/site rather than having the two sites on the same row.
SELECT
date_format( created_at, '%Y-%m-%d' ) AS the_date,site,
count(id)
FROM
kc_shares s
where
(site="facebook" or site="twitter") )
group by
created_at, site
I'm assuming that created_at is a date field.
This should provide the same data (I think, I haven't tried it) but in a different format.
Try an index on (created_at,site).