Timestamps should be rounded to every two days - aggregate error - snowflake-cloud-data-platform

We are testing this with a Snowflake Trial account by aggregating some of the sample data on a the date column on different time intervals. We used the documentation for reference.
USE DATABASE SNOWFLAKE_SAMPLE_DATA;
USE ROLE ACCOUNTADMIN;
SELECT
O_ORDERDATE,
TIME_SLICE(O_ORDERDATE, 2, 'Day', 'START') AS "START OF SLICE",
TIME_SLICE(O_ORDERDATE, 2, 'Day', 'END') AS "END OF SLICE",
count(*) as "every 2 day total"
FROM TPCH_SF001.ORDERS
GROUP BY "START OF SLICE","END OF SLICE";
We are running into this error:
SQL compilation error: error line 2 at position 7 'ORDERS.O_ORDERDATE' in select clause is neither an aggregate nor in the group by clause.
Where can we use Time_slice() to fix this?

The answer is actually in the error message. I believe this is what the user is looking for:
USE DATABASE SNOWFLAKE_SAMPLE_DATA;
USE ROLE ACCOUNTADMIN;
SELECT
TIME_SLICE(O_ORDERDATE, 2, 'Day', 'START') AS "START OF SLICE",
TIME_SLICE(O_ORDERDATE, 2, 'Day', 'END') AS "END OF SLICE",
count(*) as "every 2 day total"
FROM TPCH_SF001.ORDERS
GROUP BY "START OF SLICE","END OF SLICE";

the issue is simply that all non-aggregated columns need to be in the group by clause. I find that using the ordinal position is easier when working w/ computed columns.
SELECT
O_ORDERDATE,
TIME_SLICE(O_ORDERDATE, 2, 'Day', 'START') AS "START OF SLICE",
TIME_SLICE(O_ORDERDATE, 2, 'Day', 'END') AS "END OF SLICE",
count(*) as "every 2 day total"
FROM TPCH_SF100.ORDERS
GROUP BY 1,2,3;

Related

Generating date array from several start and end dates

I am trying to generate a dates array in BQ with dates that lie within several start and end dates.
For example, for days between one start and end date it looks like this:
SET DATES = GENERATE_DATE_ARRAY(DATE(2020,02,01), DATE(2022, 04, 25), INTERVAL 1 WEEK);
But how would I generate DATES if I want all these dates included: event_date BETWEEN "2020-02-01" AND "2020-04-25", event_date BETWEEN "2021-02-01" AND "2021-04-25", event_date BETWEEN "2022-02-01" AND "2022-04-25")
I didn't come across any easy fix.
Consider below
with dates_ranges as (
select "2020-02-01" start_date, "2020-04-25" end_date union all
select "2021-02-01", "2021-04-25" union all
select "2022-02-01", "2022-04-25"
)
select date
from dates_ranges,
unnest(generate_date_array(date(start_date), date(end_date), interval 1 week)) date
You can just create all those separate arrays and then concat_array() them, no?

Convert Date/Time to Date

I have a query which runs and I would like to return records where the date is greater than or equal to a particular date. The column I'm querying against is datetime format.
SELECT COUNT(RSO_ParentID), AssignedDateTime
FROM Task
WHERE OwnerTeam='2nd Line Support' AND AssignedDateTime>='2015-09-01 00:00:00.000'
GROUP BY AssignedDateTime
Is there a way of having filtering on the date part of AssignedDateTime, and searching relative to the current date (i.e. search for the previous 7 days)?
Thanks,
Matt
You could do it like this in MSSQL
SELECT COUNT(RSO_ParentID), AssignedDateTime
FROM Task
WHERE OwnerTeam='2nd Line Support' AND AssignedDateTime>=DATEADD(D,-7, GETDATE())
GROUP BY AssignedDateTime
Note: This question was not tagged SQL Server 2005 when I answered it. I am leaving the answer, because it is appropriate for SQL Server 2008+.
If you just care about the date and not the time, you need a combination of casting and datediff():
SELECT COUNT(RSO_ParentID), AssignedDateTime
FROM Task
WHERE OwnerTeam = '2nd Line Support' AND
AssignedDateTime >= dateadiff(day, -7, cast(getdate() as date))
GROUP BY AssignedDateTime;
Note that you can also express this using functions on AssignedDateTime. That is generally a bad idea because it often prevents the use of indexes for the query.
I also am guessing that you want the results by day:
SELECT COUNT(RSO_ParentID), cast(AssignedDateTime as date)
FROM Task
WHERE OwnerTeam = '2nd Line Support' AND
AssignedDateTime >= dateadiff(day, -7, cast(getdate() as date))
GROUP BY cast(AssignedDateTime as date);
or a total, in which you don't want a group by clause:
SELECT COUNT(RSO_ParentID)
FROM Task
WHERE OwnerTeam = '2nd Line Support' AND
AssignedDateTime >= dateadiff(day, -7, cast(getdate() as date));
If you are using MSSQL, use DATEDIFF.
SELECT COUNT(RSO_ParentID), AssignedDateTime
FROM Task
WHERE OwnerTeam='2nd Line Support' AND DATEDIFF(DAY,AssignedDateTime,GETDATE()) <=7
GROUP BY AssignedDateTime
Try this, it will check only date part, but not time part
SELECT COUNT(RSO_ParentID), AssignedDateTime
FROM Task
WHERE OwnerTeam='2nd Line Support' AND CAST(AssignedDateTime AS DATE) >=
DATEADD(D,-7, GETDATE())
GROUP BY AssignedDateTime

How do I add to the date in a select query in SQL Server?

Apologies for the unclear question I was unsure of how to title this. I am new to SQL Server. I have two columns in my table, one called datetimeRented and one called datetimeReturned. I want to have a select query which calculates movies that are overdue (+48hrs) so that it will be something along the lines of:
select *
from ----
[where datetimeReturned is datetimeRented + 2 DAYS] --- something which essentially does something like this.
I just want to know what I would need to do to work this out, thank you :)
Use DATEADD (Transact-SQL)
For example:
WHERE datetimeReturned > DATEADD(day, 2, datetimeRented)
DATEADD function is useful for this tasks.
DATEADD (dd, 2, GETDATE()) will add days (dd), 2, to the given date (in this case the current date)
So your where clause could be like this
where datetimeReturned > DATEADD(dd, 2, datetimeRented)

How do I modify my SQL query to output data only for Saturdays and Sundays within a specific period?

I am running SQL Server 2014 and I have the following query that runs fine. However, I need to modify it so that it outputs only StayDates that are Saturdays and Sundays for the period specified in the query.
I searched for a few solutions but I cam across some complex solutions that were hard to understand. Some mentioned using the INTERVAL DAYOFWEEK codes but with no clear explanation that would allow me to test the codes.
Here is how my query stands currently:
SELECT ResID, MIN(STAYDATE) AS 'Start Date',MAX(STAYDATE) AS 'End Date'
FROM RStayDate
WHERE StayDate BETWEEN '2014-10-01' AND '2014-12-31'
GROUP BY ResID
Instead of giving me all records that related to the specific period mentioned in the query, I need to modify the codes so that ONLY records which relate to week-ends (Saturdays and Sundays) are tabulated.
With DATEPART function:
SELECT ResID, MIN(STAYDATE) AS 'Start Date',MAX(STAYDATE) AS 'End Date'
FROM RStayDate
WHERE StayDate BETWEEN '2014-10-01' AND '2014-12-31' AND DATEPART(dw, STAYDATE) IN(7, 1)
GROUP BY ResID
#Richard has mentioned that it depends on settings, so you should check for it here:
https://msdn.microsoft.com/en-us/library/ms174420.aspx
When datepart is week (wk, ww) or weekday (dw), the return value
depends on the value that is set by using SET DATEFIRST.

Query user logins using distinct and reprot back daily, weekly and monthly usage

I have a SQL Query, that I'm looking to report back site usage hourly, daily, weekly and monthly.
I require the query to use Distinct as the nature of the application will create several entries to the table upon a each new login to the site.
Here is what I have so far:
SELECT DISTINCT OPRID,
CONVERT(varchar(12), LOGINDTTM, 112) 'Date'
from PSACCESSLOG_HIST
where OPRID NOT IN ('AUTOPROC', 'PSAPPS', 'PHSADBA', 'PTWEBSERVER')
ORDER BY Date
This will give the following:
OPRID LOGIPADDRESS LOGINDTTM LOGOUTDTTM
dadams 10.1.1.5 20130612 20130612
jblake 10.1.1.5 20130614 20130614
First I do need to group the data as mentioned above by day. This is what I'm looking for, for this part:
LOGINDATE-TIME TOTAL-LOGINS
20130612 25
20130613 35
20130614 45
SELECT CONVERT(varchar(12), LOGINDTTM, 112) 'Date', count(*) as TOTAL-LOGINS
from PSACCESSLOG_HIST
where OPRID NOT IN ('AUTOPROC', 'PSAPPS', 'PHSADBA', 'PTWEBSERVER')
GROUP BY Date
ORDER BY Date
It is unclear to me how your query results in the table you produce. Your query does not mention logoutdttm. In any case, you can do what you want by grouping by date and counting the distinct "OPRID"s on each date (if I understand your request correctly):
SELECT CONVERT(varchar(12), LOGINDTTM, 112) as "Date", count(distinct OPRID) as NumOPRs
from PSACCESSLOG_HIST
where OPRID NOT IN ('AUTOPROC', 'PSAPPS', 'PHSADBA', 'PTWEBSERVER')
group by CONVERT(varchar(12), LOGINDTTM, 112)
ORDER BY Date
(As a side note, SQL Server doesn't allow you to use an alias in the group by column.)
Instead of the convert(), I prefer converting the date time to a date data type:
SELECT cast(LOGINDTTM as date) as "Date", count(distinct OPRID) as NumOPRs
from PSACCESSLOG_HIST
where OPRID NOT IN ('AUTOPROC', 'PSAPPS', 'PHSADBA', 'PTWEBSERVER')
group by cast(LOGINDTTM as date)
ORDER BY "Date"
Also, although SQL Server may allow you to put the aliases for columns in single quotes, you should use double quotes or square brackets. Single quotes have a strong meaning as a constant string in a SQL statement, and not as the name of a column or table.

Resources