SQLite Selecting Average By Day While Excluding Some Hours - sqlite

I have some code that selects the average by day of a list like this:
2015-11-09 09:45:34.038000 | 10
2015-11-09 10:00:34.039000 | 5
So, if those were the only two entries 11-09 would be 7.5. My SQLite query works, but I have another wrinkle, I would like to add. Here is what I have so far:
queryCurs.execute('''select strftime('%m-%d-%Y', date), round(Avg(number),2) from tableA join tableB on tableB.name = tableA.name where place like ? group by strftime('%m-%d-%Y', date)''', (list[i],))
And this works really well. However, I would like to only include the entries that occur between 8a and 8p. How would I go about excluding anything that does fall in that range into my average?

Extract the time from the timestamp with the time() function, and filter on it.
(And a simpler way of extracting the date is with the date() function.)
SELECT strftime('%m-%d-%Y', date),
round(Avg(number),2)
FROM tableA
JOIN tableB USING (name)
WHERE place LIKE ?
AND time(date) BETWEEN '08:00:00' AND '20:00:00'
GROUP BY date(date)

Related

Teradata - Get the 2nd most current date, from a table, and reference it

Lets say we have a table with entries and run dates. It might get updated on weekends or holidays, or it might just run M-F. And this check could run before all loads are done for the day. For this reason, I want to find the entry before the max date.
Run_Date Entry
2020-03-09 z
2020-03-06 x
2020-03-05 y
In this instance, I want to return 3/6/20. I would use this in a CTE or subquery.
This code returns the top two dates, and we see the 2nd date 3/6, but how do I single it out?
SELECT TOP 2
RUN_DATE
FROM DATABSE1.TABLEA
GROUP BY RUN_DATE
ORDER BY RUN_DATE DESC
SELECT
RUN_DATE
FROM DATABSE1.TABLEA
QALIFY
ROW_NUMBER()
OVER (ORDER BY RUN_DATE DESC) = 2 -- 2nd highest date
This assumes RUN_DATE is unique, otherwise switch to DENSE_RANK plus DISTINCT

Cognos Report Studio - For loop?

I have a COGNOS package for data on processes within my company. They all have a start date, and unfinished processes have no end date. A process is active on date x if the start date is before x, and the end date is after x, or is empty. The package doesn't have a time series.
The company needs a report with the number of active processes at the end of each month, for the past two years. With no time series to iterate, I had to be creative. I created 24 data items, each with the formula below:
IF (([Start Date] <= _last_of_month(_add_months(current_date;-1))) and
(([End Date] is missing) or
([End Date] > _last_of_month(_add_months(current_date;-1)))))
THEN (1) ELSE (0)
... subtracting 1 to 24 months. Then, I added each on a column on the report's crosstable.
Well, this solution is really ugly, and unmaintanable. Is there a way to iterate a variable on Report Studio, creating a line or column for each iteration?
Thanks!
You can simulate time series in Report Studio.
There are some options:
If you are allowed to SQL in RS. Create a Query Subject like:
select _last_of_month(_add_months(current_date;-1)) as Month
union all
select _last_of_month(_add_months(current_date;-2)) as Month
union all
....
Create a query subject from existing table with dates. Query item [Month]
_last_of_month([date_field])
Filter it by
[date_field] < _add_months(current_date;-24)
and check query property "Auto Group and Summarize" is set "Yes".
Be careful an choose small but dense table as a source.
Create Query subject based on any existing table with more than 24 rows. Add a Query Item with expression
1
Call it "1" as well. Add another QI, call it [Back], expression
running-total([1])
Filter it:
[Back] <= 24
Add another QI with expression
_last_of_month(_add_months(current_date;-[Back]))
This is your [Month] field
Than join this Query Subject with your process list by condition
[Time series].[Month] > [Process].[Start Date] and
([Time series].[Month] < [Process].[End Date] or [End Date] is missing)
Than just count rows for every [Month]

SQLite date function doesn't appear in SELECT results

I've just started using SQLite, instead of SQL Server, and it doesn't seem to want to do ORDER BY, MAX() or MIN() on dates.
The Survey_Date column is a text field, so ordering it sorts it from January to December, instead of by the year. If I include date(Survey_Date) in my SELECT statement, it will sort the data by year -- but I can't override the DESC sort, and it doesn't actually display the date.
SELECT Survey_Date FROM Surveys WHERE Loc_ID = 32 ORDER BY Survey_Date;
yields results like:
01/10/2009
01/20/2013
02/05/2010
...
SELECT date(Survey_Date), Survey_Date FROM Surveys WHERE Loc_ID = 32 ORDER BY 1 ASC;
yields results like:
|01/20/2013
|02/05/2010
|01/10/2009
...
It's clearly sorting on the date correctly now, but it doesn't display the formatted date, and doesn't recognize the ASC command.
Can anyone explain what it's doing?
As already explained at least million times over this site, SQLite does not have date/timestamp type.
So if you want to sort by date, you must store them in format that sorts correctly either numerically, or lexicographically (asciibetically/unicodebetically).
The recommended format is ISO-8601, that is yyyy-mm-dd (yyyy-mm-ddTHH:MM:SS if you want a time too). This is what SQLite has some utility functions to work with, too.
Other possible formats are numeric, either number of seconds since some specific point, e.g. Unix time or number of days, e.g. (Modified) Julian day.
01/10/2009
01/20/2013
02/05/2010
They are strings, so this is correctly sorted.
SELECT date(Survey_Date), Survey_Date FROM Surveys WHERE Loc_ID = 32 ORDER BY 1 ASC;
The date function expects ISO-8601 format. It does not understand what you are giving it and returns NULL. Fully expected.
Sorting by all NULL values effectively does nothing. The rows came out sorted by accident.

Selecting Rows with based on Count (SQLite)

Hoping for some help with this:
1) I am trying to select all calls (rows) for CustomerIDs that show up 6 or more times within a 30 day rolling period, so if the CustomerID is within the file 6 or more times within 30 days, then it would provide me with all records for that CustomerID.
2) I also need to select all calls for CustomerIDs that show up 2 or more times within a 30 day rolling period but ONLY if two certain columns also match (CallType1 and CallType2). Very similar to the query with the 6 calls but we need to consider that the call types are exactly the same too.
SELECT * FROM tablename
WHERE CustomerID IN (SELECT CustomerID FROM tablename
WHERE "CustomerID"
IN ('MyProgram'));
The query above selects all of the CustomerIDs which reach my program. I need to add the logic to count >=6 CustomerIDs (item 1 above) and then a second query to get the >=2 with the same CallTypes.
The innermost subquery computes how many calls there are in the window beginning at First.
The middle subquery checks this value for every possible window in the table. (This is inefficient, but SQLite has no window functions.)
SELECT *
FROM TableName
WHERE CustomerID IN (SELECT CustomerID
FROM TableName AS First
WHERE (SELECT COUNT(*)
FROM TableName
WHERE Date BETWEEN First.Date
AND date(First.Date, '+30 days')
AND CustomerID = First.CustomerID
) >= 6)
This assumes that there is a column Date using the default date format (yyyy-mm-dd).

how to get a average of days with two different tables

There are two tables 1)HR_OrderRequest (column to be considered is HRdate) other columns are HRUID,UID
2)HR_Supplydetails(colmn to be considered is HRUID) other columns are createddttm,UID
by considering the date from HR_Supplydetails we should find the average days taken for that particular UID time taken to release of HRdate .I have a problem getting a average of days
Please do the need .
You can do a datediff:
SELECT AVG(DATEDIFF(day, createddttm,HRdate))
And then do your join on the two tables.
so the steps would be first getting the number of days for a order so you have like these tables:
order (id, date) # this date is the date the order was placed
supply (id, date) # this date is the date the order was filled
these might not be right but i think they are close
select avg(days)
from (select (supply.date-order.date) as days
from order join supply on order.id=supply.id)
but the sub query isn't needed as it can be written as:
select avg(supply.date-order.date)
from order join supply on order.id=supply.id;
now to map this to your tables:
HR_OrderRequest (HRUID, UID, HRdate)
HR_Supplydetails (HRUID, UID, createddttm)
select avg(HR_OrderRequest.HRdate-HR_Supplydetails.createddttm)
from HR_OrderRequest join HR_Supplydetails on HR_OrderRequest.HRUID=HR_Supplydetails.HRUID
where UID=?
clearly if you have date functions use them

Resources