I have a data table with three columns -
Date, Order Amount, Branch id
Date Format in the date column - yyyy-mm-dd 00:00:00
I want the information to be aggregated in MM.YY format.
I tried format_date and group by functions, but unable to run the code. Any help would be highly appreciated.
Try this one assuming that Date column has a date-formatted string.
WITH sample AS (
SELECT '2022-05-22 00:00:00' AS `Date`, 100 AS OrderAmount, 1 AS BranchID
UNION ALL
SELECT '2022-05-21 00:00:00' AS `Date`, 200 AS OrderAmount, 1 AS BranchID
UNION ALL
SELECT '2022-04-22 00:00:00' AS `Date`, 150 AS OrderAmount, 2 AS BranchID
UNION ALL
SELECT '2022-04-21 00:00:00' AS `Date`, 250 AS OrderAmount, 2 AS BranchID
)
SELECT BranchID, FORMAT_DATE('%m.%y', DATE(LEFT(`Date`, 10))) AS mmyy, SUM(OrderAmount) OrderAmounts
FROM sample
GROUP BY 1, 2
;
output:
Consider below option/example
SELECT BranchID,
FORMAT_DATE('%m.%y', DATE(Date)) AS mmyy,
SUM(OrderAmount) AS OrderAmounts
FROM sample
GROUP BY 1, 2
Related
I have a process that occur every 30 days but can take few days.
How can I differentiate between each iteration in order to sum the output of the process?
for Example
the output I except is
Name
Date
amount
iteration (optional)
Sophia Liu
2016-01-01
4
1
Sophia Liu
2016-02-01
5
2
Nikki Leith
2016-01-02
5
1
Nikki Leith
2016-02-01
10
2
I tried using lag function on the date filed and using the difference between that column and the date column.
WITH base AS
(SELECT 'Sophia Liu' as name, DATE '2016-01-01' as date, 3 as amount
UNION ALL SELECT 'Sophia Liu', DATE '2016-01-02', 1
UNION ALL SELECT 'Sophia Liu', DATE '2016-02-01', 3
UNION ALL SELECT 'Sophia Liu', DATE '2016-02-02', 2
UNION ALL SELECT 'Nikki Leith', DATE '2016-01-02', 5
UNION ALL SELECT 'Nikki Leith', DATE '2016-02-01', 5
UNION ALL SELECT 'Nikki Leith', DATE '2016-02-02', 3
UNION ALL SELECT 'Nikki Leith', DATE '2016-02-03', 1
UNION ALL SELECT 'Nikki Leith', DATE '2016-02-04', 1)
select
name
,date
,lag(date) over (partition by name order by date) as lag_func
,date_diff(date,lag(date) over (partition by name order by date),day) date_differacne
,case when date_diff(date,lag(date) over (partition by name order by date),day) >= 10
or date_diff(date,lag(date) over (partition by name order by date),day) is null then true else false end as new_iteration
,amount
from base
Edited answer
After your clarification and looking at what's actually in your SQL code. I'm guessing you are looking for a solution to what's called a gaps and islands problem. That is, you want to identify the "islands" of activity and sum the amount for each iteration or island. Taking your example you can first identify the start of a new session (or "gap") and then use that to create a unique iteration ("island") identifier for each user. You can then use that identifier to perform a SUM().
gaps as (
select
name,
date,
amount,
if(date_diff(date, lag(date,1) over(partition by name order by date), DAY) >= 10, 1, 0) new_iteration
from base
),
islands as (
select
*,
1 + sum(new_iteration) over(partition by name order by date) iteration_id
from gaps
)
select
*,
sum(amount) over(partition by name, iteration_id) iteration_amount
from islands
Previous answer
Sounds like you just need a RANK() to count the iterations in your window functions. Depending on your need you can then sum cumulative or total amounts in a similar window function. Something like this:
select
name
,date
,rank() over (partition by name order by date) as iteration
,sum(amount) over (partition by name order by date) as cumulative_amount
,sum(amount) over (partition by name) as total_amount
,amount
from base
I have the following situation:
ID DATE_TIME AMOUNT
23 14-MAY-2021 10:47:01 5
23 14-MAY-2021 11:49:52 3
23 14-MAY-2021 12:03:18 4
How can get the sum of the amount and take the DATE by day not hourly?
Example:
ID DATE_TIME TOTAL
23 20210514 12
I tried this way but i got error:
SELECT DISTINCT ID, TO_CHAR(DATE_TIME, 'YYYYMMDD'), SUM(AMOUNT) AS TOTAL FROM MY_TABLE
WHERE ID ='23' AND DATE_TIME > SYSDATE-1
GROUP BY TOTAL, DATE_TIME
You don't need DISTINCT if you use GROUP BY - anything that is grouped must be distinct unless it joined to something else later on that caused it to repeat again
You were almost there too
SELECT ID, TO_CHAR(DATE_TIME, 'YYYYMMDD') AS DATE_TIME, SUM(AMOUNT) AS TOTAL
FROM MY_TABLE
WHERE ID ='23' AND DATE_TIME > SYSDATE-1
GROUP BY ID, TO_CHAR(DATE_TIME, 'YYYYMMDD')
You need to group by the output of the function, not the input. Not every database can GROUP BY aliases used in the select (technically the SELECT hasn't been done by the time the GROUP is done so the aliases don't exist yet, and you wouldnt group by the total because that's an aggregate (the result of summing up every various value in the group)
If you need to do further work with that date, don't convert it to a string.. Cut the time off using TRUNC:
SELECT ID, TRUNC(DATE_TIME) as DATE_TIME, SUM(AMOUNT) AS TOTAL
FROM MY_TABLE
WHERE ID ='23' AND DATE_TIME > SYSDATE-1
GROUP BY ID, TRUNC(DATE_TIME)
TRUNC can cut a date down to other parts, for example TRUNC(DATE_TIME, 'HH24') will remove the minutes and seconds but leave the hours
Convert the DATE column to a string with the required accuracy and then group on that:
SELECT ID,
TO_CHAR("DATE", 'YYYY-MM-DD'),
SUM(AMOUNT) AS TOTAL FROM MY_TABLE
WHERE ID ='23'
AND "DATE" > SYSDATE-1
GROUP BY ID, TO_CHAR("DATE", 'YYYY-MM-DD')
or truncate the value so that the time component is set to midnight for each date:
SELECT ID,
TRUNC("DATE"),
SUM(AMOUNT) AS TOTAL FROM MY_TABLE
WHERE ID ='23'
AND "DATE" > SYSDATE-1
GROUP BY ID, TRUNC("DATE")
(Note: DATE is a keyword and cannot be used as an identifier unless you use a quoted-identifier; and you would need to use the quotes, and the exact case, everytime you refer to the column. You would be better to rename the column to something else that is not a keyword.)
Need Suggestion to make it dynamic On Dates.
Expected:
Date, Total Sellers, Sellers From Previous Date
Currently:
Data in table(active_seller_codes): date, seller_code
Queries:
-- Date Wise Sellers Count
select date,count(distinct seller_code) as Sellers_COunt
from active_seller_codes where date between '2016-12-15' AND '2016-12-15'
-- Sellers from previous Days
select date,count(distinct seller_code) as Last_Day_Seller
from active_seller_codes
where date between '2016-12-15' AND '2016-12-15'
and seller_code IN(
select seller_code from active_seller_codes
where date between '2016-12-14' AND '2016-12-14'
)
group by 1
Database Using: Vertica
Reading attentively, you seem to want one row in the report, with the data from the search date in the first two columns and the data of the day before the search date in the third and fourth column, like so:
sales_date|sellers_count|prev_date |prev_sellers_count
2016-12-15| 8|2016-12-14| 5
The solution could be something like this (without the first Common Table Expression, which, in my case, contains the data, but in your case, the data would be in your active_seller_codes table.
WITH
-- initial input
(sales_date,seller_code) AS (
SELECT DATE '2016-12-15',42
UNION ALL SELECT DATE '2016-12-15',43
UNION ALL SELECT DATE '2016-12-15',44
UNION ALL SELECT DATE '2016-12-15',45
UNION ALL SELECT DATE '2016-12-15',46
UNION ALL SELECT DATE '2016-12-15',47
UNION ALL SELECT DATE '2016-12-15',48
UNION ALL SELECT DATE '2016-12-15',49
UNION ALL SELECT DATE '2016-12-14',42
UNION ALL SELECT DATE '2016-12-14',44
UNION ALL SELECT DATE '2016-12-14',46
UNION ALL SELECT DATE '2016-12-14',48
UNION ALL SELECT DATE '2016-12-14',50
UNION ALL SELECT DATE '2016-12-13',42
UNION ALL SELECT DATE '2016-12-13',43
UNION ALL SELECT DATE '2016-12-13',44
UNION ALL SELECT DATE '2016-12-13',45
UNION ALL SELECT DATE '2016-12-13',46
UNION ALL SELECT DATE '2016-12-13',47
UNION ALL SELECT DATE '2016-12-13',48
UNION ALL SELECT DATE '2016-12-13',49
)
,
-- search argument this, in the real query, would come just after the WITH keyword
-- as the above would be the source table
search_dt(search_dt) AS (SELECT DATE '2016-12-15')
,
-- the two days we're interested in, de-duped
distinct_two_days AS (
SELECT DISTINCT
sales_date
, seller_code
FROM active_seller_codes
WHERE sales_date IN (
SELECT search_dt FROM search_dt -- the search date
UNION ALL SELECT search_dt - 1 FROM search_dt -- the day before
)
)
,
-- the two days we want one above the other,
-- with index for the final pivot
vertical AS (
SELECT
ROW_NUMBER() OVER (ORDER BY sales_date DESC) AS idx
, sales_date
, count(DISTINCT seller_code) AS seller_count
FROM distinct_two_days
GROUP BY 2
)
SELECT
MAX(CASE idx WHEN 1 THEN sales_date END) AS sales_date
, SUM(CASE idx WHEN 1 THEN seller_count END) AS sellers_count
, MAX(CASE idx WHEN 2 THEN sales_date END) AS prev_date
, SUM(CASE idx WHEN 2 THEN seller_count END) AS prev_sellers_count
FROM vertical
;
sales_date|sellers_count|prev_date |prev_sellers_count
2016-12-15| 8|2016-12-14| 5
I have a order details table and I want to find the sum of price by each date and display them as
For Ex
count sum date
5 619.95 2015-11-19
3 334.97 2015-11-18
4 734.96 2015-11-18
5 1129.95 2015-11-18
I have written the query for getting the count and sum as
select count(id), sum([price])
from [OrderDetails]
where [date]between '2015-10-29 05:15:00' and '2015-11-09 00:01:00'
group by datepart(day,[date])
But not able to achieve with date. How can it be done?
You need to include what you are grouping on in the SELECT portion of your query:
select count(id), sum([price]), datepart(day,[date]) as [date]
from [OrderDetails]
where [date] between '2015-10-29 05:15:00' and '2015-11-09 00:01:00'
group by datepart(day,[date]);
It seems like your column called date has both a date and time component. I would suggest converting it to a date, for both the select and group by:
select count(id), sum(price), cast([date] as date) as thedate
from OrderDetails
where [date] between '2015-10-29 05:15:00' and '2015-11-09 00:01:00'
group by cast([date] as date)
order by thedate;
Note: date is a poor name for a column, because it is the name of a built-in type.
I have a table that contain some Inspection Data. Every commodity needs to be inspected every month. The goal here is to find the last inspected record for each month.
Table Inspection:
INSPECTION_I--------INSPECTION_TS
200--------------------------- 10/20/2011
201----------------------------10/24/2011
202----------------------------10/26/2011
Table Product_Inspection:
INSPECTION_I------------------ASSET_I
200------------------------------------1000
201------------------------------------2000
Table Box_Inspection
INSPECTION_I--------ASSET_I
202------------------------3000
Table Product
ASSET_I------------ASSOCIATED_BOX_ASSET_I
1000---------------------------3000
Table BOX:
ASSET_I------------OTHER_STUFF
3000--------------------#####
Now in this case what I want is 201 and not 200. I tried to do MAX(to_char(inspection_ts, 'mm/yyyy')) but that is not helping. There is one more issue. For some reason, I keep getting the Cartesian in a case where a Product or a Box is inspected twice or more in a month. All I want is one inspection every month and it should be the last inspection for each month. I am really close to getting it but if someone can help, I would really appreciate it. I was able to get it done through a nested cursor but I don't want that.
I tend to use analytic functions to do this kind of query. Something like:
with data as
(
select 1 product_id, 100 inspection_id, to_date('09/04/2011', 'MM/DD/YYYY') inspection_date from dual union all
select 1 product_id, 101 inspection_id, to_date('09/14/2011', 'MM/DD/YYYY') inspection_date from dual union all
select 1 product_id, 103 inspection_id, to_date('10/04/2011', 'MM/DD/YYYY') inspection_date from dual union all
select 1 product_id, 105 inspection_id, to_date('11/01/2011', 'MM/DD/YYYY') inspection_date from dual union all
select 2 product_id, 102 inspection_id, to_date('09/24/2011', 'MM/DD/YYYY') inspection_date from dual union all
select 2 product_id, 104 inspection_id, to_date('10/05/2011', 'MM/DD/YYYY') inspection_date from dual
)
select *
from
(
select
product_id,
inspection_id,
inspection_date,
row_number() over (
partition by
product_id,
trunc(inspection_date, 'MM') -- Month
order by
inspection_date desc
) rn
from
data
)
where rn = 1 -- indicates last inspection date of the month for each product
use a subquery
Select [ColName List]
From TableName a
Where DateTimeColumname
= (Select Max(DateTimeColumnName)
From TableName
Where DateTimeColumnName < 1+Last_Day(a.DateTimeColumnName))