Get Distinct Column Count By Day - oracle

I'm using Oracle 12c and I need to get the count of unique username rows for each day. Currently the table below has multiple rows with the same username on the same day (date_created).
LOGIN_HISTORY
----------------
id (unique random generated long)
date_created (timestamp)
username (var char)

In the query below I group using the day, month, and year, which is required to uniquely identify each day your date_created column. I used COUNT(DISTINCT username) to identify the count of unique usernames for a given day.
SELECT TO_CHAR(date_created, 'DD') DAY,
TO_CHAR(date_created, 'MM') MONTH,
TO_CHAR(date_created, 'YYYY') YEAR,
COUNT(DISTINCT username) AS userCount
FROM LOGIN_HISTORY
GROUP BY TO_CHAR(date_created, 'DD'),
TO_CHAR(date_created, 'MM'),
TO_CHAR(date_created, 'YYYY')

Related

Select for max date of the Inserted dates on every month

I have a sales table It includes each sale date in the date format in the sales_day column. I need to find the maximum date for each month from these entered dates. I am using oracle db
You can group by month and use the max aggregation:
select extract(month from sale_day) as month, max(sale_day) maxdate
from sales
group by extract(month from sale_day);
Fiddle
Note that this will get dates from all the years, which might not be what you want.
If you want to limit the rows to a certain year:
select extract(month from sale_day) as month, max(sale_day) maxdate
from sales
where sale_day between TO_DATE('2021-01-01','YYYY-MM-DD') and
TO_DATE('2021-12-31','YYYY-MM-DD')
group by extract(month from sale_day);

Count of Records and Average of count of records Query - Oracle

Output like:
Year -> Month -> Product Name -> Total count of records for the year -> Average count of records for the year
My query returns the total and average for the whole year, I would like it to be broken down by month as well:
SELECT PRODUCT_ID,PRODUCT_NAME,EXTRACT(YEAR FROM DATE), COUNT(ID) AS TOTAL_COUNT,COUNT(ID)/COUNT(DISTINCT(EXTRACT(DATE))) AS AVG_NO_RECORDS
FROM TABLE
GROUP BY PRODUCT_ID,PRODUCT_NAME,EXTRACT(YEAR FROM DATE)
Apart from the fact that you used bunch of invalid things in this sample query (table is invalid table name, date is invalid column name, one of extracts is wrong), you'd use TO_CHAR on the date column with desired format mask - such as mm - and group by it as well. Something like this:
SELECT PRODUCT_ID,
PRODUCT_NAME,
EXTRACT(YEAR FROM DATE),
--
to_char(date, 'mm') as month, --> this ...
--
COUNT(ID) AS TOTAL_COUNT,
COUNT(ID)/COUNT(DISTINCT(EXTRACT(DATE))) AS AVG_NO_RECORDS
FROM TABLE
GROUP BY PRODUCT_ID,
PRODUCT_NAME,
EXTRACT(YEAR FROM DATE),
to_char(date, 'mm') --> ... and this
On the other hand, if you're already grouping by year and month, see if you can use a single column for that, e.g. to_char(date_column, 'mm.yyyy').

Oracle SQL display a different column depending on the date

I have a table that has 33 columns
Employee Month Day1 Day2 ...... etc. etc.
The day column represents the day of the month.
Is it possible to just display the Employee column and the Day of the month depending on today's date?
i.e.
12th May
Employee Day12
no idea where to start if it's possible. any help would be great
You get a record (here: month) with the WHERE clause. You get a certain column (here: day) with DECODE or CASE.
select
employee,
decode( extract(day from sysdate), 1, day1, 2, day2, 3, day3, ... ) as day
from mytable t
where t.month = extract(month from sysdate)
group by employee
order by employee;

using multiple conditions in one query in oracle

I have this record.
id performer end_time
300135 testuser 15-OCT-13
300135 testuser 14-OCT-13
300135 testuser 12-OCT-13
300137 newuser 14-OCT-13
300137 newuser 18-OCT-13
Now I want to show distinct id's but it will show me all of the Id's because end_time is different .
So what i need is to shwo disticnt Id's with the latest dates.
So the result should be
id performer end_time
300135 testuser 15-OCT-13 (as 15OCT is the heightest date for 300135)
300137 newuser 18-OCT-13 (as 18OCT is the heightest date for 300137)
Currently what i have is
select distinct id, performer, END_TIME from workstep where workstep_name = 'Review' and status ='W_COMPLETED' ....?
but this gives me all the 5 records.where as it should be only 2 , as there are only 2 unique id'.
please suggest
Thanks
You need GROUP BY
select id, performer, max(END_TIME) from workstep where workstep_name = 'Review' and status ='W_COMPLETED' group by id,performer
When you ask for unique row of 3 columns (id, performer, END_TIME )
you will get rows where combination of all 3 columns is unique (your first data listing)
There is simply not enough conditions to get from your first listing to the second one.
I assume that you want distint IDs, and for that IDs, you want to select record where END_TIME is the latest one. Withing the same ID, performer never changes.
So, put just that in sql (query will return only 1 reqord per ID):
select ID, max(performer), max(END_TIME)
from workstep
where ID in
(select distinct ID from workstep where <conditions>)
group by ID
Above query will work if performer is the same for ID.
If performer could be different, but you want to display it from row with end_time = max(END_TIME), you will need more (query could return more than 1 record per ID if there is a tie on END_TIME):
select ID, performer, END_TIME from
from workstep
where (id, end_time) in
(
select ID, max(END_TIME)
from workstep
where ID in
(select distinct ID from workstep where <conditions>)
group by ID
)
So, for query above, there is an assumtion that END_TIME is different for every record with the same ID.
Here is a more advanced version that is free from that assumtion (exatly 1 record per ID):
select id, performer, end_time
from (
select ID, performer, END_TIME,
row_number() over (partition by id order by end_time desc, performer) as No
from workstep
where <conditions>
)
where No = 1
questions?

Unique rows in oracle 11g

I have a query which returns a set of records as like the one below:-
Date Dept commission
5-Apr Sales 20
4-Apr Sales 21
1-Jan Marketing 35
case 1: If i run a query between 1 Jan and 5 april I should get
Date Dept commission
5 April Sales 76
case 2: and when I run the query between jan 1 and jan 31 should get the output as
Date Dept commission
1 Jan Marketing 35
Case 2 is simple as when i put hte date range getting the required results , but not sure how to handle case 1 to show the max / latest date , the Dept for that date and a sum of the commission for that Dept , date for the selected date range . The output will be a single row with the latest date and department with a sum(commission) for the selected date range.
SELECT
MAX(Date) AS Date
, ( SELECT tt.Dept
FROM tableX tt
WHERE tt.Date = MAX(t.Date)
) AS Dept
, SUM(Commission) AS Commission
FROM
tableX t
WHERE
Date BETWEEN StartDate AND EndDate
The above works in SQL-Server, MySQL, Postgres as the sql-fiddle, test-1 shows, however it does NOT work in Oracle 11g R2 !
This works though (sql-fiddle, test-2):
SELECT
MAX(t.Date) AS Date
, MIN(tt.Dept) AS Dept --- MIN, MAX irrelevant
, SUM(t.Commission) AS Commission
FROM
( SELECT
MAX(Date) AS Date
, SUM(Commission) AS Commission
FROM
tableX
WHERE
Date BETWEEN StartDate AND EndDate
) t
JOIN
tableX tt
ON tt.Date = t.Date
The MIN(tt.Dept) is used to take care of the case you have more than row with the maximum date, say one row with Sales and one with Marketing, both in Apr-5
This works, too, using the LAST_VALUE analytic function (sql-fiddle, test-3):
SELECT
MAX(Date) AS Date
, MIN(Dept) AS Dept
, SUM(Commission) AS Commission
FROM
( SELECT
Date AS Date
, LAST_VALUE(Dept) OVER( ORDER BY Date
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS Dept
, Commission AS Commission
FROM
tableX
WHERE
Date BETWEEN StartDate AND EndDate
) t

Resources