We have the following query that runs perfectly in MSSQL but fails to run in MySQL:
select CONVERT(datetime, dateVal) as DateOccurred, itemID, COUNT(*) as Hits from (
select itemID, CONVERT(datetime, DateClickUTC) as dateVal
from tb_items
where DateClickUTC >= '2008-06-03 22:00:28.893' and DateClickUTC <= '2013-06-03 22:00:28.893'
group by CONVERT(datetime, DateClickUTC), UserID, itemID) as a
group by a.dateVal, itemID
The error we get from MySQL says:
syntax error, unexpected IDENT_QUOTED
This error occurs on the dateVal variable on the first line: "Select CONVERT(datetime, dateVal)."
If we remove the first CONVERT the error then moves to the next CONVERT on the following line. So, obviously, there seems to be an error with our datetime conversion. Not sure what we're doing the wrong though, any ideas out there? Thanks all.
I prefer to use CAST, but as others have said, you need to specify the type after the field like this:
convert(DateClickUTC,datetime)
Here is a working example using CAST:
select a.dateVal as DateOccurred, itemID, COUNT(*) as Hits
from (
select itemID, cast(DateClickUTC as datetime) as dateVal
from tb_items
where DateClickUTC >= '2008-06-03 22:00:28.893' and DateClickUTC <= '2013-06-03 22:00:28.893'
group by cast(DateClickUTC as datetime), UserID, itemID
) as a
group by a.dateVal, itemID
SQL Fiddle Demo
BTW -- You actually don't need the subquery in this case -- this should work as well:
select cast(DateClickUTC as datetime) as DateOccurred,
itemID,
COUNT(*) as Hits
from tb_items
where DateClickUTC >= '2008-06-03 22:00:28.893' and DateClickUTC <= '2013-06-03 22:00:28.893'
group by cast(DateClickUTC as datetime), itemID
Related
I am trying to determine the average difference between the events in days, within a column in mysql workbench.
sample data looks something like this :
I want to determine the average of duration between events grouped by organizer. any suggestions please?
If you are running MySQL 8.0, you can use lag() for this:
select avg(datediff(event_date, lag_event_date)) avg_diff
from (
select
t.*,
lag(event_date) over(partition by nid order by event_date) lag_event_date
from mytable t
) t
In earlier versions, a typical workaround is a correlated subquery:
select nid, avg(datediff(event_date, lag_event_date)) avg_diff
from (
select
t.*,
(
select max(t1.event_date)
from mytable t1
where t1.nid = t.nid and t1.event_date < t.event_date
) lag_event_date
from mytable t
) t
group by nid
The simplest method is to take the largest date minus the smallest date and divide by one less than the count:
select organizer,
datediff(day, min(date), max(date)) * 1.0 / nullif(count(*) - 1, 0) as avg_day_diff
from t
group by organizer;
Try the following:
LAG([EVENT DATE],1) OVER ( ORDER BY [EVENT DATE]) AS PREV_EVENT_DATE,
DATEDIFF(DD, LAG([EVENT DATE],1) OVER ( ORDER BY [EVENT DATE]), [EVENT DATE]) AS DAYS_BETWEEN_EVENTS
DAYS_BETWEEN_EVENT Can then be used to calculate your average days difference.
The key piece of SQL to use in these instances is the LAG function because it allows you to return a value from the previous row. Documentation here
Whats wrong with my query:
SELECT minDate, deviceType, COUNT(*)
FROM (SELECT visitorId, deviceType,
MIN(sessionDate) as minDate
FROM sessions
GROUP BY visitorId)
WHERE minDate > DATE_SUB(NOW(), INTERVAL 14 DAY)
GROUP BY minDate, deviceId
I've got this message:
Query Error: Error: ER_DERIVED_MUST_HAVE_ALIAS: Every derived table must have its own alias
The error message is clear enough. You must alias the derived table that is generated by your sub-select. So, give it an alias.
Another issue is that, in the subquery, non-aggregated column deviceType should be included in the GROUP BY clause. This change might, or might not produce the results that you do expect: if it doesn't, then you would need to provide sample data, expected results and an explanation of what you are trying to accomplish so one can help fixing the query.
SELECT minDate, deviceType, COUNT(*)
FROM (
SELECT visitorId, deviceType, MIN(sessionDate) as minDate
FROM sessions
GROUP BY visitorId, deviceType -- all non-aggregated columns in the GROUP BY clause
) t -- alias here
WHERE minDate > DATE_SUB(NOW(), INTERVAL 14 DAY)
GROUP BY minDate, deviceId
When I run this query I have this error message on phpmydamin: Unknown column 'timestamp' in 'having clause'
My column name is timestamp
SELECT DISTINCT (
hash
) AS total
FROM behaviour
HAVING total =1 and date(timestamp) = curdate()
How to get the number of hash for today?
Use where. And parentheses are not appropriate for select distinct (distinct is not a function). I suspect that you intend:
SELECT COUNT(DISTINCT hash) AS total
FROM behaviour
WHERE date(timestamp) = curdate();
It is better to write the WHERE clause without using a function on the column:
SELECT COUNT(DISTINCT hash) AS total
FROM behaviour
WHERE timestamp >= curdate() AND timestamp < date_add(curdate, interval 1 day);
Although more complicated, it allows the database engine to use an index on behaviour(timestamp) (or better yet, on behaviour(timestamp, hash).
EDIT:
If you want the hash that only appear once, one method is a subquery:
select count(*)
from (select hash
from behaviour
where timestamp >= curdate() AND timestamp < date_add(curdate, interval 1 day)
group by hash
having count(*) = 1
);
To count the hash values only existing once:
select count(*)
from
(
select hash
from behavior
where date(timestamp) = curdate()
group by hash
having count(*) = 1
) dt
The inner select (derived table) will return the hash values only existing once. The outer select will count those rows.
Thereis a good answer to the main question here: MySQL: Count the distinct rows per day
I need it with the days with values also included but the query
SELECT DATE(timestamp) Date, COUNT(DISTINCT ipNum) totalCOunt
FROM tableName
WHERE totalCOunt < 1
GROUP BY DATE(timestamp)
gives an error ( #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE totalCOunt < 1
LIMIT 0, 25' at line 3 ). Where did I go wrong?
Sample data here: http://sqlfiddle.com/#!2/11aa6/146
It is throwing Unknown column 'totalCOunt' in 'where clause' error:
Please try the below query(replaced WHERE clause with HAVING clause):
SELECT DATE(timestamp) Date, COUNT(DISTINCT ipNum) totalCOunt
FROM tableName
GROUP BY DATE(timestamp)
HAVING totalCOunt<1
You have a few errors:
Date should be escaped, as it is a keyword in MySQL.
The syntax is wrong. You forgot AS.
So the corrected one is:
SELECT CAST(`timestamp` AS Date) AS `Date`, COUNT(DISTINCT(`ipNum`)) AS totalCOunt
FROM `tableName`
GROUP BY CAST(`timestamp` AS Date)
Fiddle: http://sqlfiddle.com/#!2/809838/8
You can't use an alias in the WHERE clause
SELECT DATE(timestamp) Date, COUNT(DISTINCT ipNum) totalCOunt
FROM tableName
WHERE totalCOunt < 1
GROUP BY DATE(timestamp)
Use HAVING instead:
SELECT DATE(timestamp) Date, COUNT(DISTINCT ipNum) totalCOunt
FROM tableName
GROUP BY DATE(timestamp)
HAVING totalCOunt =1
I have a working mysql query, but I can not get it work with postgres. This is the query (I already changed date format to to_char
SELECT country as grouper, date(users.created_at) as date,
to_char(users.created_at, '%Y-%m') as date_group,
count(id) as total_count
FROM "users"
WHERE (users.created_at >= '2011-12-01')
AND (users.created_at <= '2014-02-11')
GROUP BY grouper, date_group
ORDER BY date ASC
I am getting the error:
PG::Error: ERROR: column "users.created_at" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT country as grouper, date(users.created_at) as date, t...
Thank for your help.
SELECT country as grouper, date(MIN(users.created_at)) as date,
to_char(MIN(users.created_at), '%Y-%m') as date_group,
count(id) as total_count
FROM "users"
HAVING (users.created_at >= '2011-12-01')
AND (users.created_at <= '2014-02-11')
GROUP BY grouper, date_group
ORDER BY date ASC
MySQL is not very strict. In standard conform SQL all column values have to use an aggrate function (SUM, COUNT, MAX, MIN) on non-grouping fields - when using GROUP BY.
Honestly said, I am not entirely sure about data_group in the GROUP BY; can it be dropped?
Also note that I have switched WHERE with a HAVING.
You should use every selected column in GROUP BY section.
SELECT country as grouper, to_char(created_at, '%Y-%u') as date_group, count(id) as total_count
FROM "users"
WHERE created_at >= '2013-10-01'
AND created_at <= '2014-02-11'
GROUP BY grouper, date_group
ORDER BY date_group ASC