Oracle, count of distinct items by date - oracle

I need to get a count of items by date from field1 grouped by last update time. What I am looking for is how many times an item from field1 appears on a specific date for the last 30 days where field 2 = 0. This will be run every day so the date will roll. Field1 will be a number >0, field2 will be any number (negative and positive), last_upd_time will be a system time when the last update occurred. I don't need the time, only the date. My current query that returns all of the data is:
select field1, field2, trunc(last_upd_time)
from table
where field2 = '0' and last_upd_time >= SYSDATE - 30
I have attempted to use count, group by, and group by/having. Not saying I was using them correctly, but I did try.

Try this:
SELECT TO_CHAR(last_upd_time,'DD-MM-YYYY') last_upd_time, COUNT(DISTINCT field1)
FROM table WHERE field2='0' AND
last_upd_time>=SYSDATE - INTERVAL '30' DAY
GROUP BY TO_CHAR(last_upd_time,'DD-MM-YYYY');

Related

Why does my total session (aggregated using EXTRACT MONTH) is less than total session if I broke down by the date?

I'm trying to generate my total session by month. I've tried using two different ways.
I'm using date field for the first column
I'm using month field that is extracted from date field using EXTRACT(MONTH FROM date) AS month
I have tried using below code for the 1st one:
with
session1 as(
select date,
session_id
from table
where date >= '2019-05-20' AND date <= '2019-05-21')
SELECT date_key, COUNT(DISTINCT session_id) AS sessions from session1
GROUP BY 1
For the 2nd one I tried using this code:
with
session1 as(
select date,
session_id
from table
where date >= '2019-05-20' AND date <= '2019-05-21')
SELECT EXTRACT (MONTH FROM date_key) AS month, COUNT(DISTINCT session_id) AS sessions from session1
GROUP BY 1
For the result, I got the output as per below:
20 May: 1,548 Sessions; 21 May: 1,471 Sessions; Total: 3,019
May: 2,905
So, there's 114 session discrepancy and I'd like to know why.
Thank you in advance.
For simplicity sake - let's say there is only one session during two consecutive days. So if you will count by day and then sum result - you will get 2 sessions, while if you will count distinct sessions for whole two days - you will get just 1 session
Hope this shows you the reason why - you are counting some sessions twice on different days - maybe when they go over end of one and start of next day
The following query should show you which sessions_ids occur on both dates.
select session_id, count(distinct date) as num_dates
from table
where date >= '2019-05-20' AND date <= '2019-05-21'
group by 1
having num_dates > 1
This is either a data processing issue, or your session definition is allowed to span multiple days. Google Analytics, for example, traditionally ends a session and begins a new session at midnight. Other sessionization schemes might not impose this restriction.

time related function for epoch timestamp in bigquery

when querying a table which has a column "timestamp" (epoch timestamp, UTC, milliseconds, type integer in the bigquery table)
i want to be able to say:
timestamp between one_week_ago and now
without specifying the exact timestamps in each query.
i should add that i know the following working query:
WITH timerange AS
(SELECT *,
TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 * 24 HOUR) AS one_week_ago,
CURRENT_TIMESTAMP() AS now,
TIMESTAMP_SECONDS(timestamp) AS measurement_time
FROM table_name),
grouped AS
(SELECT field1, field2, count(*) count
FROM timerange
WHERE measurement_time BETWEEN one_week_ago AND now
GROUP BY field1, field2
)
SELECT * FROM timerange
WHERE field2 = "example"
but why am i not simply able to say:
timestamp between function_call1 and function_call2
?
these are examples of the timestamps: 1491544587, 1491422047, 1491882866, 1491881903 1491436515, 1491436771, 1491436593, 1491436621, 1491436390, 1491436334
https://cloud.google.com/bigquery/docs/reference/legacy-sql
https://cloud.google.com/bigquery/docs/reference/standard-sql/
You can certainly say in Standard SQL like you want:
SELECT *
FROM table
WHERE TIMESTAMP_SECONDS(timestamp) BETWEEN
TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 * 24 HOUR)
AND CURRENT_TIMESTAMP()

Coldfusion query of queries count by date

I'm trying to get an count based on two dates and I'm not sure how it should look in a query. I have two date fields; I want to get a count based on those dates.
<cfquery>
SELECT COUNT(*)
FROM Table1
Where month of date1 is one month less than month of date2
</cfquery>
Assuming Table1 is your original query, you can accomplish your goal as follows.
Step 1 - Use QueryAddColumn twice to add two empty columns.
Step 2 - Loop through your query and populate these two columns with numbers. One will represent date1 and the other will represent date2. It's not quite as simple as putting in the month numbers because you have to account for the year as well.
Step 3 - Write your Q of Q with a filter resembling this:
where NewColumn1 - NewColumn2 = 1

Oracle - Counting timestamps where difference between timestamps greater than 1 hour

I have a worklog table that contains the following fields:
worklog_id,
agent_name,
ticket_number,
timestamp,
worklog_notes.
I would like to be able to count the number of worklog entries made where if the agent_name, ticket_number and timestamp (date) are the same the worklog entry is only counted if the time between the two entries is greater than 1 hour.
Example: John Smith make three worklog entries on ticket 12345. The first timestamp is "10/11/2012 9:11:44 AM", the second timestamp is "10/11/2012 9:36:16 AM" and the third timestamp is "10/11/2012 11:18:20 AM". In this example I would only want to give the agent credit for two worklog entries as the first two were less than an hour apart.
I've tried getting the logic to work using a "where" sub-query, but cannot get it working. Would anyone have any example they could provide? Thanks! :)
Does this get what you want? The first entry by a given agent on a ticket should always be counted, and entries after that should only be counted if at least an hour has elapsed since the prior entry.
select agent_name, ticket_number, count(*) from (
select agent_name, ticket_number, timestamp,
lag(timestamp) over
(partition by agent_name, ticket_number order by timestamp) prev_timestamp
)
from worklog
where (prev_timestamp is null
or (timestamp - prev_timestamp) >= interval '1' hour
)
group by agent_name, ticket_number
I'm not sure this is exactly what you want -- if an agent keeps adding entries within an hour of the prior entry, none of them will be counted except the first. So someone who adds a lot of updates gets penalized.
Maybe what you really want is to count the number of distinct hours in which an update was made:
select agent_name, ticket_number, count(distinct to_char(timestamp,'DD-MON-YYYY HH24')
from worklog
group by agent_name, ticket_number

"BETWEEN" SQL Keyword for Oracle Dates -- Getting an error in Oracle

I have dates in this format in my database "01-APR-12" and the column is a DATE type.
My SQL statement looks like this:
SELECT DISTINCT c.customerno, c.lname, c.fname
FROM customer c, sales s
WHERE c.customerno = s.customerno AND s.salestype = 1
AND (s.salesdate BETWEEN '01-APR-12' AND '31-APR-12');
When I try to do it that way, I get this error -- ORA-01839: date not valid for month specified.
Can I even use the BETWEEN keyword with how the date is setup in the database?
If not, is there another way I can get the output of data that is in that date range without having to fix the data in the database?
Thanks!
April has 30 days not 31.
Change
SELECT DISTINCT c.customerno, c.lname, c.fname
FROM customer c, sales s
WHERE c.customerno = s.customerno AND s.salestype = 1
AND (s.salesdate BETWEEN '01-APR-12' AND '31-APR-12');
to
SELECT DISTINCT c.customerno, c.lname, c.fname
FROM customer c, sales s
WHERE c.customerno = s.customerno AND s.salestype = 1
AND (s.salesdate BETWEEN '01-APR-12' AND '30-APR-12');
and you should be good to go.
In case the dates you are checking for range from 1st day of a month to the last day of a month then you may modify the query to avoid the case where you have to explicitly check the LAST day of the month
SELECT DISTINCT c.customerno, c.lname, c.fname
FROM customer c, sales s
WHERE c.customerno = s.customerno
AND s.salestype = 1 AND (s.salesdate BETWEEN '01-APR-12' AND LAST_DAY(TO_DATE('APR-12', 'MON-YY'));
The LAST_DAY function will provide the last day of the month.
The other answers are missing out on something important and will not return the correct results. Dates have date and time components. If your salesdate column is in fact a date that includes time, you will miss out on any sales that happened on April 30 unless they occurred exactly at midnight.
Here's an example:
create table date_temp (temp date);
insert into date_temp values(to_date('01-APR-2014 15:12:00', 'DD-MON-YYYY HH24:MI:SS'));
insert into date_temp values(to_date('30-APR-2014 15:12:00', 'DD-MON-YYYY HH24:MI:SS'));
table DATE_TEMP created.
1 rows inserted.
1 rows inserted.
select * from date_temp where temp between '01-APR-2014' and '30-APR-2014';
Query Result: 01-APR-14
If you want to get all records from April that includes those with time-components in the date fields, you should use the first day of the next month as the second side of the between clause:
select * from date_temp where temp between '01-APR-2014' and '01-MAY-2014';
01-APR-14
30-APR-14

Resources