i have the following working code to return every combination of location, state, and monthyear.
select *
from openquery (jw,'
select distinct a.location, a.state, a.monthyear
from (
select clm.location, clm.state,
case
when EFDT>=''2017-09-01'' and EFDT<=''2017-09-30'' Then ''Sept 2017''
when EFDT>=''2017-10-01'' and EFDT<=''2017-10-31'' Then ''Oct 2017''
when EFDT>=''2017-11-01'' and EFDT<=''2017-11-30'' Then ''Nov 2017''
when EFDT>=''2017-12-01'' and EFDT<=''2017-12-31'' Then ''Dec 2017''
when EFDT>=''2018-01-01'' and EFDT<=''2018-01-31'' Then ''Jan 2018''
when EFDT>=''2018-02-01'' and EFDT<=''2018-02-28'' Then ''Feb 2018''
when EFDT>=''2018-03-01'' and EFDT<=''2018-03-31'' Then ''March 2018''
when EFDT>=''2018-04-01'' and EFDT<=''2018-04-30'' Then ''April 2018''
when EFDT>=''2018-05-01'' and EFDT<=''2018-05-31'' Then ''May 2018''
when EFDT>=''2018-06-01'' and EFDT<=''2018-06-30'' Then ''June 2018''
when EFDT>=''2018-07-01'' and EFDT<=''2018-07-31'' Then ''July 2018''
when EFDT>=''2018-08-01'' and EFDT<=''2018-08-31'' Then ''Aug 2018''
when EFDT>=''2018-09-01'' and EFDT<=''2018-09-30'' Then ''Sept 2018''
when EFDT>=''2018-10-01'' and EFDT<=''2018-10-31'' Then ''Oct 2018''
when EFDT>=''2018-11-01'' and EFDT<=''2018-11-30'' Then ''Nov 2018''
when EFDT>=''2018-12-01'' and EFDT<=''2018-12-31'' Then ''Dec 2018''
ELSE ''null''
END as monthyear
from alias.table1 clm
where ....
) a
group by location, state, monthyear
order by monthyear
with ur')
now i'm struggling on adding in the AVG to get the average time for each combination, the code would be:
avg(days(LSDT)-days(EFDT))
how can i use avg in combination with group by and case? any advice is appreciated. i need to show the average time between these two dates for each combination of channel, state, and monthyear
Try this:
select location, state, monthyear, avg(days(LSDT)-days(EFDT)) as days
from (
select clm.location, clm.state, clm.lsdt, clm.efdt
, case
when EFDT between date('2017-09-01') and date('2018-12-31') then to_char(EFDT, 'Mon')||' '||year(EFDT)
else 'null'
end monthyear
from alias.table1 clm
)
group by location, state, monthyear
order by monthyear;
Related
I work with PostgreSQL integrated into Redash, and am currently needing to do the following report:
generate active_month for each subscription in the database, following the rule: for each month in the last 12, if that month falls in between the subscription's creation and cancelation date, create a line with that month as 'active_month'
report should contain count of subscriptions on each active_month, filtered by unit
My current code uses a nested select and looks like the following:
select
unit,
active_month,
subscriptions
from
(
select
unit_id unit,
to_char(
date_trunc('month', created_at) :: timestamp :: date,
'YYYY-MM'
) active_month,
count(id) subscriptions
from
[DATABASE HERE]
where
created_at >= (timestamp '{{ today }}' - interval '12 months')
group by
created_at,
unit
order by
active_month,
unit_id
) inner_query
group by
active_month,
unit,
subscriptions
order by
active_month,
unit
However, this doesn't work, as:
It only takes into consideration the creation month, and not every month for which the subscription was active
It seems to be counting different dates from the same month as different fields, since there are multiple lines with the same unit and month on them
Any suggestions about how can I fix this?
Generate the Date Range for the months you are interested in (With CTE or sub-select) then use the element contained operator for appropriate date selection. See example, of course I just generated random data and it is dependent on my actually understanding what you are asking. Which is questionable!
with calendar (date_range) as
( select daterange ( (current_date-interval '12 months')::date
, current_date
, '[]'
)
) --select * calendar;
select
unit,
active_month,
subscriptions
from
(
select
unit_id unit,
to_char(
date_trunc('month', created_at) :: timestamp :: date,
'YYYY-MM'
) active_month,
count(id) subscriptions
from
DATABASE_HERE
where
created_at::date <# (select date_range from calendar) --<<<< change
group by
created_at,
unit
order by
active_month,
unit_id
) inner_query
group by
active_month,
unit,
subscriptions
order by
active_month,
unit;
I have a table with:
ID (id client), date_start (subscription of SaaS), date_end (could be a date value or be NULL).
So I need a cumulative count of active clients month by month.
any idea on how to write that in Postgres and achieve this result?
Starting from this, but I don't know how to proceed
select
date_trunc('month', c.date_start)::date,
count(*)
from customer
Please check next solution:
select
subscrubed_date,
subscrubed_customers,
unsubscrubed_customers,
coalesce(subscrubed_customers, 0) - coalesce(unsubscrubed_customers, 0) cumulative
from (
select distinct
date_trunc('month', c.date_start)::date subscrubed_date,
sum(1) over (order by date_trunc('month', c.date_start)) subscrubed_customers
from customer c
order by subscrubed_date
) subscribed
left join (
select distinct
date_trunc('month', c.date_end)::date unsubscrubed_date,
sum(1) over (order by date_trunc('month', c.date_end)) unsubscrubed_customers
from customer c
where date_end is not null
order by unsubscrubed_date
) unsubscribed on subscribed.subscrubed_date = unsubscribed.unsubscrubed_date;
share SQL query
You have a table of customers. With a start date and sometimes an end date. As you want to group by date, but there are two dates in the table, you need to split these first.
Then, you may have months where only customers came and others where only customers left. So, you'll want a full outer join of the two sets.
For a cumulative sum (also called a running total), use SUM OVER.
with came as
(
select date_trunc('month', date_start) as month, count(*) as cnt
from customer
group by date_trunc('month', date_start)
)
, went as
(
select date_trunc('month', date_end) as month, count(*) as cnt
from customer
where date_end is not null
group by date_trunc('month', date_end)
)
select
month,
came.cnt as cust_new,
went.cnt as cust_gone,
sum(came.cnt - went.cnt) over (order by month) as cust_active
from came full outer join went using (month)
order by month;
Hi i am getting the error as GROUP BY and WITH BY CLAUSE MAY NOT CONATIN AGGREGATE FUNCTIONS for below query.
SELECT
distinct CC.CASE_ID as CASE_ID,
/*FIRST_VALUE(CC.CASE_OWN_NM) OVER(PARTITION BY CC.CASE_ID )as FST_AGNT_CASE_OWN_NM,
FIRST_VALUE(CC.LSTMOD_BY_AGNT_PRFL_NM) OVER(PARTITION BY CC.CASE_ID)as FST_AGNT_PRFL_NM,
LAST_VALUE(CC.CASE_OWN_NM) OVER(PARTITION BY CC.CASE_ID) as LST_AGNT_CASE_OWN_NM,
LAST_VALUE(CC.LSTMOD_BY_AGNT_PRFL_NM) OVER(PARTITION BY CC.CASE_ID) as LST_AGNT_PRFL_NM,*/
case when CC.CASE_OWN_NM is not null then MIN(CC.REC_DTTM_PST) end as FST_AGNT_EDIT_DTTM,
case when CC.CASE_OWN_NM is not null then MAX(CC.REC_DTTM_PST) end as LST_AGNT_EDIT_DTTM,
case when CC.CASE_STS_CD='Open' then MIN(CC.REC_DTTM_PST) end as CASE_OPEN_DTTM,
case when CC.CASE_STS_CD in ( 'Closed', 'Auto Closed') then MIN(CC.REC_DTTM_PST) end as CASE_CLSE_OR_AUTO_CLSE_DTTM
--CC.PU_DTTM as LMI_PU_DTTM,
--CC.CLS_DTTM as LMI_CLS_DTTM
FROM EDW_KATAMARI_T.CNTCT_CASE CC
INNER JOIN EDW_KATAMARI_T.CNTCT_CASE_EXTN CCE
ON CC.CNTCT_CASE_APND_KEY = CCE.CNTCT_CASE_APND_KEY
INNER JOIN EDW_STAGE_COMN_SRC.STG_CNTCT_CASE_DELTA DELTA
on CC.CASE_ID = DELTA.CASE_ID
where CC.CASE_ID='23268760'
group by 1,2,3,4,5
when i used only group 1 still it is giving non-aggregate function must be part of group by.
You need to move the CASEs into the aggregate:
MIN(CASE WHEN CC.CASE_OWN_NM IS NOT NULL THEN CC.REC_DTTM_PST END) AS FST_AGNT_EDIT_DTTM,
MAX(CASE WHEN CC.CASE_OWN_NM IS NOT NULL THEN CC.REC_DTTM_PST END) AS LST_AGNT_EDIT_DTTM,
MIN(CASE WHEN CC.CASE_STS_CD='Open' THEN CC.REC_DTTM_PST END) AS CASE_OPEN_DTTM,
MIN(CASE WHEN CC.CASE_STS_CD IN ( 'Closed', 'Auto Closed') THEN CC.REC_DTTM_PST END) AS CASE_CLSE_OR_AUTO_CLSE_DTTM
Then GROUP BY 1 will work
When I run the following :
DELETE FROM db2Name.MyTable
WHERE (NBR, CATEGORY, SALES_DATE) IN
(
SELECT NBR, CATEGORY, SALES_DATE, RN
FROM
(
SELECT
NBR, CATEGORY, SALES_DATE,
rownumber() over(PARTITION BY NBR, CATEGORY, SALES_DATE) RN
FROM db2Name.DELI_DATA
WHERE NBR = 10 AND SALES_DATE = CURRENT_DATE - 7 DAYS
) A
WHERE RN > 1
GROUP BY NBR, CATEGORY, SALES_DATE, RN
)
I get error SQL0216N
I'm trying to delete duplicate records leaving one in the table when I experiment with similar queries, they're removing all records matching and leaving none
the table def looks like this
NBR int
addr string
market int
category string
sales decimal
Sales_last_month decimal
sales_date date
I can see that mostly likely the issue is in this clause not having the RN (that's why it is not matching the group by)
WHERE (NBR, CATEGORY, SALES_DATE) IN
but if I add it, it does not recognize it .... and it fails
This could be simply
DELETE FROM (
SELECT * FROM
(
SELECT
rownumber() over (PARTITION BY NBR, CATEGORY, SALES_DATE) RN
FROM db2Name.DELI_DATA
WHERE NBR = 10 AND SALES_DATE = CURRENT_DATE - 7 DAYS
) A
WHERE RN > 1
)
I have some T-SQL that generates a nice report giving a summary some stuff by month.
I have 2 questions, is there a way to get the to sort the months by calendar order, not by alpha? And, what i would like to do is add a total line for each year, and a total line for the whole report?
SELECT
CASE WHEN tmpActivity.Year IS NULL THEN
CASE WHEN tmpCreated.Year IS NULL THEN
CASE WHEN tmpContactsCreated.Year IS NULL THEN
null
ELSE tmpContactsCreated.Year END
ELSE tmpCreated.Year END
ELSE tmpActivity.Year END As Year,
CASE WHEN tmpActivity.Month IS NULL THEN
CASE WHEN tmpCreated.Month IS NULL THEN
CASE WHEN tmpContactsCreated.Month IS NULL THEN
null
ELSE DateName(month, DateAdd(month, tmpContactsCreated.Month - 1, '1900-01-01' )) END
ELSE DateName(month, DateAdd(month, tmpCreated.Month - 1, '1900-01-01' )) END
ELSE DateName(month, DateAdd(month, tmpActivity.Month - 1, '1900-01-01' )) END As Month,
CASE WHEN tmpActivity.ActiveAccounts IS NULL THEN 0 ELSE tmpActivity.ActiveAccounts END AS ActiveAccounts,
CASE WHEN tmpCreated.NewAccounts IS NULL THEN 0 ELSE tmpCreated.NewAccounts END AS NewAccounts,
CASE WHEN tmpContactsCreated.NewContacts IS NULL THEN 0 ELSE tmpContactsCreated.NewContacts END AS NewContacts
FROM
(
SELECT YEAR(LastLogon) As Year, MONTH(LastLogon) As Month, COUNT(*) As ActiveAccounts
FROM Users
WHERE LastLogon >= '1/1/1800'
GROUP BY YEAR(LastLogon), MONTH(LastLogon)
) as tmpActivity
FULL JOIN
(
SELECT YEAR(Created) As Year, MONTH(Created) As Month, COUNT(*) As NewAccounts
FROM Users
WHERE Created >= '1/1/1800'
GROUP BY YEAR(Created), MONTH(Created)
) as tmpCreated ON tmpCreated.Year = tmpActivity.Year AND tmpCreated.Month = tmpActivity.Month
FULL JOIN
(
SELECT YEAR(Created) As Year, MONTH(Created) As Month, COUNT(*) As NewContacts
FROM Contacts
WHERE Created >= '1/1/1800'
GROUP BY YEAR(Created), MONTH(Created)
) as tmpContactsCreated ON tmpContactsCreated.Year = tmpCreated.Year AND tmpContactsCreated.Month = tmpCreated.Month
Order By Year DESC, Month DESC
To order by the month use the following:
ORDER BY DATEPART(Month,Created) ASC
DatePart() returns an integer for the part specified 1 for January, 2 for Febuary etc.
You're SQL could be helped with the COALESCE() and ISNULL() functions. This is the same as your first select:
SELECT
COALESCE(tmpActivity.Year,tmpCreated.Year,tmpContactsCreated.Year) as Year,
COALESCE(tmpActivity.Month,tmpCreated.Month,tmpContactsCreated.Month) as Month,
ISNULL(tmpActivity.ActiveAccounts,0) AS ActiveAccounts,
ISNULL(tmpCreated.NewAccounts,0) AS NewAccounts,
ISNULL(tmpContactsCreated.NewContacts,0) AS NewContacts
I think there is a bug in your select, I believe your last line has to be this:
) as tmpContactsCreated ON (tmpContactsCreated.Year = tmpCreated.Year AND tmpContactsCreated.Month = tmpCreated.Month) OR
(tmpContactsCreated.Year = tmpActivity.Year AND tmpContactsCreated.Month = tmpActivity.Month)
But I would have to test this to be sure.
Adding in rollups is hard to do -- typically this is done externally to the SQL in the control or whatever displays the results. You could do something like this (contrived example):
SELECT 1 as reportOrder, date, amount, null as total
FROM invoices
UNION ALL
SELECT 2 , null, null, sum(amount)
FROM invoices
ORDER BY reportOrder, date
or you could not have the "extra" total column and put it in the amount column.