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
Related
I have a function that takes product pricing data from today and yesterday and works out the difference, orders it by price_delta_percentage and then limits to 5. Now currently I order by price_delta_percentage DESC which returns the top 5 products that have increased in price since yesterday.
I would like to parse in a variable - sort - to change the function to either sort by DESC, or ASC. I have tried to use IF statements and get syntax errors and CASE statements which states that price_delta_percentage doesn't exist.
Script:
RETURNS TABLE(
product_id varchar,
name varchar,
price_today numeric,
price_yesterday numeric,
price_delta numeric,
price_delta_percentage numeric
)
LANGUAGE 'sql'
COST 100
STABLE STRICT PARALLEL SAFE
AS $BODY$
WITH cte AS (
SELECT
product_id,
name,
SUM(CASE WHEN rank = 1 THEN trend_price ELSE NULL END) price_today,
SUM(CASE WHEN rank = 2 THEN trend_price ELSE NULL END) price_yesterday,
SUM(CASE WHEN rank = 1 THEN trend_price ELSE 0 END) - SUM(CASE WHEN rank = 2 THEN trend_price ELSE 0 END) as price_delta,
ROUND(((SUM(CASE WHEN rank = 1 THEN trend_price ELSE NULL END) / SUM(CASE WHEN rank = 2 THEN trend_price ELSE NULL END) - 1) * 100), 2) as price_delta_percentage
FROM (
SELECT
magic_sets_cards.name,
pricing.product_id,
pricing.trend_price,
pricing.date,
RANK() OVER (PARTITION BY product_id ORDER BY date DESC) AS rank
FROM pricing
JOIN magic_sets_cards_identifiers ON magic_sets_cards_identifiers.mcm_id = pricing.product_id
JOIN magic_sets_cards ON magic_sets_cards.id = magic_sets_cards_identifiers.card_id
JOIN magic_sets ON magic_sets.id = magic_sets_cards.set_id
WHERE date BETWEEN CURRENT_DATE - days AND CURRENT_DATE
AND magic_sets.code = set_code
AND pricing.trend_price > 0.25) p
WHERE rank IN (1,2)
GROUP BY product_id, name
ORDER BY price_delta_percentage DESC)
SELECT * FROM cte WHERE (CASE WHEN price_today IS NULL OR price_yesterday IS NULL THEN 'NULL' ELSE 'VALID' END) !='NULL'
LIMIT 5;
$BODY$;sql
CASE Statement:
ORDER BY CASE WHEN sort = 'DESC' THEN price_delta_percentage END DESC, CASE WHEN sort = 'ASC' THEN price_delta_percentage END ASC)
Error:
ERROR: column "price_delta_percentage" does not exist
LINE 42: ORDER BY CASE WHEN sort = 'DESC' THEN price_delta_percenta...
You can't use CASE to decide between ASC and DESC like that. Those labels are not data, they are part of the SQL grammar. You would need to do it by combining the text into a string and then executing the string as a dynamic query, which means you would need to use pl/pgsql, not SQL
But since your column is numeric, you could just order by the product of the column and an indicator variable which is either 1 or -1.
How can i use alias column sisa to lag function in case statement
select i.item_name , i.item_code, DATE(ic.transaction_date), doc_no, qty,
case when count(item_name) over(partition by item_name) = 1
then sum(qty) over(partition by doc_no)
else
case when row_number() over(partition by item_code) = 1
then first_value(qty) over(partition by item_code)
else
qty + lag(sisa)over (partition by item_code)
end
end as sisa
from item_card_today ic
join item i on i.item_id = ic.item_id
where transaction_date
between '2019-03-31 00:11:42'::timestamp and '2019-04-02 08:17:35'::timestamp
and i.item_code = 'CLDXMZM3NTDGSHCKPRFHBHTM'
order by item_code asc, item_name asc
How i can use sisa in the code?
I have a query to find which v_address belonged to which v_group, and when was the creation date of v_address. However, each v_group was sometimes active and inactive and it has dates. So, I wrote query to find the period of those changes.
My problem is my query took too long time to run because it has multiple subqueries and joins.
Does anyone have a better idea to shorten to load data?
I attached my query below identifier = 81 is for smaller testing. For the final result, I will need to retrieve data for more than 100k ids.
I tried to change inner joins to left joins but it loses null values and still took too long time to retrieve data.
with v_address as (
select id, v_group_id, created_at
from prod.venue_address --different schema and table. v_address.v_group_id can have multiple v_address.id
group by 1,2,3
order by 3 asc
),
v_group as (
select identifier, final_status, created_at
from dwh.venue_address_archive
where identifier = 81
group by 1,2,3
order by 3 asc
),
filtering as (
select identifier, created_at,
case when sum(case when final_state = 'active' then 1 else 0 end) > 0 then 'active' else 'inactive' end as filtered_status --This filters either of active or inactive
from v_group
group by 1,2
order by 2 asc
),
prev as (
select identifier, created_at, filtered_status,
lag(case when filtered_status = 'active' then 'active' else 'inactive' end) over (partition by identifier order by created_at) = filtered_status as is_prev_status
from filtering
group by 1,2,3
),
periods as (
select identifier, filtered_status, created_at, is_prev_status,
sum(case when is_prev_status = true then 0 else 1 end) over (order by identifier, created_at) as period
from prev
group by 1,2,3,4
),
islands_gaps_start as (
select identifier, period, min(created_at) as start_at
from periods
group by 2,1
),
islands_gaps as (
select identifier, period, start_at,
lead(start_at) over (partition by identifier order by period) as end_at
from islands_gaps_start
)
select vg.identifier as "vg_id", p.created_at as "vg_created_at", p.filtered_status as "status", p.is_prev_status, p.period, va.id as "va_id", g.start_at, g.end_at
from v_address va
left join v_group vg
on va.venue_id = vg.identifier
inner join filtering f
on vg.identifier = f.identifier
inner join prev pr
on pr.filtered_status = f.filtered_status
inner join periods p
on p.filtered_status = pr.filtered_status
inner join islands_gaps_start gs
on p.period = gs.period
inner join islands_gaps g
on gs.start_at = g.start_at
group by 6,1,2,3,4,5,7,8
order by 2 asc
I already have the output with an example identifier = 81 but I have to run this query for more than 100k identifiers so, I'm looking for any advice that I can shorten my query.
I am looking to fetch records and I have come through a scenario in which i have to include additional where clauses between the select query using inner join.
select stp.sales_person as "Sales_Person",
max(case when stp.jan_month is null then 0 else stp.jan_month end) as "January",
select sum(so.amount_total) from sale_order so inner join res_users ru on ru.id=so.user_id
where date(so.confirmation_date) > '2017-01-01' and date(so.confirmation_date) < '2017-01-30',
max(case when stp.feb_month is null then 0 else stp.feb_month end) as "February",
max(case when stp.march_month is null then 0 else stp.march_month end) as "March",
max(case when stp.dec_month is null then 0 else stp.dec_month end) as "December"
from sales_target_record stp
inner join res_partner rp on rp.name=stp.sales_person inner join res_users ru on ru.partner_id = rp.id inner join crm_team ct on ru.sale_team_id = ct.id
where ct.name = 'Direct Sales' group by stp.sales_person
I have to insert columns like i tried with sum but is not working as its a join query
You have a syntax issue in your query if this is truly SQL Server
select
stp.sales_person as Sales_Person,
max(case
when stp.jan_month is null
then 0
else stp.jan_month
end) as January,
--This needed parenthese since it's a subquery. Though, it's uncorrelated
( select sum(so.amount_total)
from sale_order so
inner join res_users ru on ru.id=so.user_id
where cast(so.confirmation_date as date) > '2017-01-01' and cast(so.confirmation_date as date) < '2017-01-30'
--here you need to add something like stp.someColumn = so.SomeColumn to correlate it to the outer query
) as SomeNewColumnUnCorrelated,
max(case
when stp.feb_month is null
then 0
else stp.feb_month
end) as February,
max(case
when stp.march_month is null
then 0
else stp.march_month
end) as March,
max(case
when stp.dec_month is null
then 0
else stp.dec_month
end) as December
from
sales_target_record stp
inner join
res_partner rp on
rp.name=stp.sales_person
inner join
res_users ru on
ru.partner_id = rp.id
where
ct.name = 'Direct Sales'
group by
stp.sales_person
i wants to show rows data into columns. suppose if rows type increased then number of columns also increased. Information as follow:
Please see picture to get idea
You can use COUNT with CASE WHEN:
SELECT t.Name AS Type,
COUNT(*) AS NumberOfCase,
COUNT(CASE WHEN s.Name = 'Resolved' THEN 1 END) AS Resolved,
COUNT(CASE WHEN s.Name = 'Pending' THEN 1 END) AS Pending,
COUNT(CASE WHEN s.Name = 'Waiting' THEN 1 END) AS Waiting
FROM Type t
LEFT JOIN "Case" c
ON c.CaseType = t.TypeId
LEFT JOIN "Status" s
ON c.CaseStatus = s.StatusId
GROUP BY t.Name;
SqlFiddleDemo