Join Two queries and find output: PostgresSql - postgresql

Want join the below two queries and want to give the output as following:
SELECT count(*) FROM trip_schedule_close ts
WHERE EXTRACT(MONTH FROM ts.schedule_date) = EXTRACT(MONTH FROM current_date)
AND EXTRACT(YEAR FROM ts.schedule_date) = EXTRACT(YEAR FROM current_date) AND ts.route_id='152'
This query will give_output as:
count
14
Next Query:
SELECT sum(ts.product_qty)AS Product_Quantity FROM trip_delivery_sales_lines ts
WHERE EXTRACT(MONTH FROM ts.order_date) = EXTRACT(MONTH FROM current_date)
AND EXTRACT(YEAR FROM ts.order_date) = EXTRACT(YEAR FROM current_date) AND ts.route_id='152' AND ts.product_id='432' AND ts.type='sales'
This query will output result as:
product Quantity
446565
N0w i want join these two queries and want to give result as :
446565/ 14

First rewrite your first query as :
SELECT count(*) AS nb FROM t...
Then , assuming sql1 & sql2 are your 2 queries
SELECT Product_Quantity || '/ ' || nb AS new_name FROM ( sql1 ) r1,( sql2 ) r2;

with
p(curr_month, route_id, product_id, type) as (values(
date_trunc('month', current_date),
152,
432,
'sales'::text))
select
(SELECT count(*)
FROM trip_schedule_close ts
WHERE
date_trunk('month', ts.schedule_date) = p.curr_month AND
ts.route_id = p.route_id) || '/' ||
(SELECT sum(ts.product_qty) AS Product_Quantity
FROM trip_delivery_sales_lines ts
WHERE
date_trunk('month', ts.schedule_date) = p.curr_month AND
ts.route_id = p.route_id AND
ts.product_id = p.product_id AND
ts.type = p.type)
FROM p;

Related

pySpark error Expression Referencing the outer Query

I want to recreate this query in spark sql
SELECT
[Id],
[Group],
[Name],
min([Date]) as MinDate,
max([Date]) as MaxDate
FROM recordTable
GROUP BY [Id],[Group],[Name]
)
SELECT
t.Id,
t.[Group],
t.[Name],
c.[Date],
(SELECT top 1 ScoreCount
from recordTable x
where x.[Date] <= c.[Days]
and x.[Group] = t.[Group]
and x.[Name] = t.[Name]
order by x.[Date] desc
) ScoreCount
FROM t
LEFT JOIN calendar c ON c.[Days] BETWEEN t.MinDate AND t.MaxDate
so I have
df = spark.sql("""
WITH t as (
SELECT
Id,
Group,
Name,
min(Date) as MinDate,
max(Date) as MaxDate
FROM recordTable
GROUP BY Id,Group,Name
)
SELECT
t.Id,
t.Group,
t.Name,
c.Date,
(SELECT ScoreCount
from recordTable x
where x.Date <= c.Days
and x.Group = t.Group
and x.Name = t.Name
order by x.Date desc LIMIT 1
) ScoreCount
FROM t
LEFT JOIN calendar c ON c.Days BETWEEN t.MinDate AND t.MaxDate
""")
But I'm getting an error when trying to limit 1 and using an order by clause. Any alternatives?
"Expressions referencing the outer query are not supported outside of where/having clauses"

How to divide a period in columns

I am trying to create a query where the first column shows the list of the companies and the other 3 columns their revenues per month. This is what I do:
WITH time_frame AS
(SELECT date_trunc('month',NOW())-interval '0 week'),
time_frame1 AS
(SELECT date_trunc('month',NOW())-interval '1 month'),
time_frame2 AS
(SELECT date_trunc('month',NOW())-interval '2 month')
select table1.company_name,
(CASE
WHEN table2.date_of_transaction = (SELECT * FROM time_frame2) THEN sum(table2.amount)
ELSE NULL
END) AS "current week - 2",
(CASE
WHEN table2.date_of_transaction = (SELECT * FROM time_frame1) THEN sum(table2.amount)
ELSE NULL
END) AS "current week - 1",
(CASE
WHEN table2.date_of_transaction = (SELECT * FROM time_frame2) THEN
sum(table2.amount)
ELSE NULL
END) AS "current week - 2"
from table1
join table2 on table2.table1_id = table.id
where table1.company_joined >= '04-20-2019'
group by 1
When I execute the table this comes out: Error running query: column "table2.date_of_transaction" must appear in the GROUP BY clause or be used in an aggregate function LINE 15: WHEN table2.date_of_transaction = (SELECT * FROM time_frame) TH... ^
Do you have any ideas on how to solve it? Thank you.
company name
month1
month2
name 1
£233
£343
name 2
£243
£34
name 3
£133
£43
you can simplify the statement by using the filter() operator
select t1.company_name,
sum(t2.amount) filter (where t2.date_of_transaction = date_trunc('month',NOW())-interval '2 month'),
sum(t2.amount) filter (where t2.date_of_transaction = date_trunc('month',NOW())-interval '1 month'),
sum(t2.amount) filter (where t2.date_of_transaction = date_trunc('month',NOW()))
from table1 t1
join table2 t2 on t2.table1_id = t1.id
where t1.company_joined >= date '2019-04-20'
group by t1.company_name;
If you really want to put the date ranges into a CTE, you only need one:
with dates (r1, r2, r3) as (
values
(date_trunc('month',NOW())-interval '2 month',
date_trunc('month',NOW())-interval '1 month',
date_trunc('month',NOW()))
)
select t1.company_name,
sum(t2.amount) filter (where t2.date_of_transaction = d.r1),
sum(t2.amount) filter (where t2.date_of_transaction = d.r2),
sum(t2.amount) filter (where t2.date_of_transaction = d.r3)
from table1 t1
cross join dates d
join table2 t2 on t2.table1_id = t1.id
where t1.company_joined >= date '2019-04-20'
group by t1.company_name
;
The CTE dates returns a single row with three columns and thus the cross join doesn't change the resulting number of rows.

Return 0 value of SUM function for all rows in left table

forgive the probably inane question.
I am using the following where I want to return a value for every salesman even if the spend is zero. How do I achieve this ?
SELECT
CAST(coalesce(customer.salesman, '0') AS integer) as Salesman,
Sum(sophead.order_value) AS "Quote Value"
FROM
customer
INNER JOIN sophead ON sophead.inv_account = customer.account
WHERE
customer.company = 2 AND
Extract(MONTH FROM sophead.order_date) = Extract(MONTH FROM Now()) AND
Extract(YEAR FROM sophead.order_date) = Extract(YEAR FROM Now()) AND
sophead.order_type = 'Q' AND
sophead.salesman IN ('21','22','25','28','29','76')
GROUP BY
customer.salesman
ORDER BY
customer.salesman
You just need to use LEFT JOIN and COALESCE to ensure you show 0 if no sales:
SELECT
CAST(coalesce(customer.salesman, '0') AS integer) as Salesman,
COALESCE(Sum(sophead.order_value), 0) AS "Quote Value"
FROM customer
LEFT JOIN sophead
ON sophead.inv_account = customer.account
AND Extract(MONTH FROM sophead.order_date) = Extract(MONTH FROM Now())
AND Extract(YEAR FROM sophead.order_date) = Extract(YEAR FROM Now())
AND sophead.salesman IN ('21','22','25','28','29','76')
WHERE customer.company = 2
AND sophead.order_type = 'Q'
GROUP BY
customer.salesman
ORDER BY
customer.salesman

How do I avoid joining multiple times when using union all statement?

I was working on a query where I hit a point:
SELECT tpd.timestamp::Date,'Mon' AS Label,
count(tpd.aggregated)
FROM tap.deving AS tpd INNER JOIN
(select DATE_TRUNC('week', timestamp), MAX(timestamp) AS max_timestamp
from tap.deving
group by DATE_TRUNC('week', timestamp)
) b
on tpd.timestamp = b.max_timestamp
left JOIN ca.hardware AS ch ON tpd.dev = ch.name
left JOIN ca.sites AS css ON css.id = ch.id
WHERE (tpd.aggregated=TRUE)
AND (css.country='USA') and (tpd.timestamp::date=now()::Date - interval '1 day') group by tpd.timestamp
UNION ALL
SELECT tpd.timestamp::date,'Tap but not' AS Label,
count(tpd.tap)
FROM tap.deving AS tpd INNER JOIN
(select DATE_TRUNC('week', timestamp), MAX(timestamp) AS max_timestamp
from tap.deving
group by DATE_TRUNC('week', timestamp)
) b
on tpd.timestamp = b.max_timestamp
left JOIN ca.hardware AS ch ON tpd.dev = ch.name
left JOIN ca.sites AS css ON css.id = ch.id
WHERE (tpd.tap=true)
AND (tpd.aggregated=false) and (tpd.needs_to_be=true)
AND (css.country='USA') and (tpd.timestamp::date=now()::Date - interval '1 day') group by tpd.timestamp
I wrote this query with the help of many SO posts and it has gone quite messy and super slow. I could not get my head on how to optimize this query.
Can you please try this query.
SELECT tpd.timestamp::Date,CASE tpd.aggregated
WHEN false THEN 'Tap but not'
WHEN true THEN 'Mon' as Label,
count(tpd.aggregated)
FROM tap.deving AS tpd INNER JOIN
(select DATE_TRUNC('week', timestamp), MAX(timestamp) AS max_timestamp
from tap.deving
group by DATE_TRUNC('week', timestamp)
) b
on tpd.timestamp = b.max_timestamp
left JOIN ca.hardware AS ch ON tpd.dev = ch.name
left JOIN ca.sites AS css ON css.id = ch.id
WHERE ((tpd.aggregated=TRUE) or ((tpd.tap=true) AND (tpd.aggregated=false) and (tpd.needs_to_be=true)))
AND (css.country='USA') and (tpd.timestamp::date=now()::Date - interval '1 day') group by tpd.timestamp;

How to PIVOT this query and display only TOP 10 records filtered by SUM(NetWrittenPremium) DESC

In this query I cant understand what would be the proper syntax to PIVOT it by month and also display just top 10 records based on SUM(NetWrittenPremium).
;with cte_TopClasses
AS (
select
b.YearNum,
b.MonthNum,
REPLACE(ClassCode,'+','') + ' - '+ QLL.Description as Description,
SUM( Premium) as NetWrittenPremium
FROM tblCalendar b
LEFT JOIN ProductionReportMetrics prm ON b.MonthNum=Month(prm.EffectiveDate) AND b.YearNum = YEAR(EffectiveDate)
AND prm.EffectiveDate >=DateAdd(yy, -1, DATEADD(d, 1, EOMONTH(GETDATE()))) AND prm.EffectiveDate <= EOMONTH(GETDATE()) AND CompanyLine = 'Ironshore Insurance Company'
LEFT JOIN NetRate_Quote_Insur_Quote Q ON prm.NetRate_QuoteID = Q.QuoteID
LEFT JOIN NetRate_Quote_Insur_Quote_Locat QL ON Q.QuoteID = QL.QuoteID
LEFT JOIN (SELECT * FROM NetRate_Quote_Insur_Quote_Locat_Liabi nqI
JOIN ( SELECT LocationID as LocID, MAX(ClassCode) as ClCode
FROM NetRate_Quote_Insur_Quote_Locat_Liabi GROUP BY LocationID ) nqA
ON nqA.LocID = nqI.LocationID AND nqA.ClCode = nqI.ClassCode ) QLL
ON QLL.LocationID = QL.LocationID
WHERE ( b.YearNum = YEAR(GETDATE())-1 and b.MonthNum >= MONTH(GETDATE())+1 ) OR
( b.YearNum = YEAR(GETDATE()) and b.MonthNum <= MONTH(GETDATE()) )
GROUP BY b.YearNum,b.MonthNum,ClassCode, QLL.Description
)
SELECT
--TOP 10
RANK() OVER (ORDER BY NetWrittenPremium DESC) AS Rank, *
FROM cte_TopClasses
WHERE Description IS NOT NULL
ORDER BY NetWrittenPremium DESC,YearNum,MonthNum
The result should look something like that:
If I use the query below and then using matrics in SSRS to PIVOT it - then after grouping by Description it only displays me 2 Description.
;with cte_TopClasses
AS (
select
b.YearNum,
b.MonthNum,
REPLACE(ClassCode,'+','') + ' - '+ QLL.Description as Description,
SUM( Premium) as NetWrittenPremium
FROM tblCalendar b
LEFT JOIN ProductionReportMetrics prm ON b.MonthNum=Month(prm.EffectiveDate) AND b.YearNum = YEAR(EffectiveDate)
AND prm.EffectiveDate >=DateAdd(yy, -1, DATEADD(d, 1, EOMONTH(GETDATE()))) AND prm.EffectiveDate <= EOMONTH(GETDATE()) AND CompanyLine = 'Ironshore Insurance Company'
LEFT JOIN NetRate_Quote_Insur_Quote Q ON prm.NetRate_QuoteID = Q.QuoteID
LEFT JOIN NetRate_Quote_Insur_Quote_Locat QL ON Q.QuoteID = QL.QuoteID
LEFT JOIN (SELECT * FROM NetRate_Quote_Insur_Quote_Locat_Liabi nqI
JOIN ( SELECT LocationID as LocID, MAX(ClassCode) as ClCode
FROM NetRate_Quote_Insur_Quote_Locat_Liabi GROUP BY LocationID ) nqA
ON nqA.LocID = nqI.LocationID AND nqA.ClCode = nqI.ClassCode ) QLL
ON QLL.LocationID = QL.LocationID
WHERE ( b.YearNum = YEAR(GETDATE())-1 and b.MonthNum >= MONTH(GETDATE())+1 ) OR
( b.YearNum = YEAR(GETDATE()) and b.MonthNum <= MONTH(GETDATE()) )
GROUP BY b.YearNum,b.MonthNum,ClassCode, QLL.Description
)
SELECT *
FROM (SELECT RANK() OVER (ORDER BY NetWrittenPremium DESC) AS Rank, *
FROM cte_TopClasses
WHERE Description IS NOT NULL) AA
WHERE AA.Rank <= 10
ORDER BY AA.NetWrittenPremium DESC, AA.YearNum, AA.MonthNum
And the result of it in SSRS matrics :
You could try something like this at the end of the query, rather than what is there now:
SELECT *
FROM (SELECT RANK() OVER (ORDER BY [Description] DESC) AS Rank, *
FROM cte_TopClasses
WHERE Description IN (SELECT [Description]
FROM (SELECT RANK() OVER (ORDER BY SUM(NetWrittenPremium) DESC) AS [Rank], [Description], SUM(NetWrittenPremium) AS total
FROM cte_TopClasses
WHERE [Description] IS NOT NULL
GROUP BY [Description]) BB
WHERE [Rank] <= 10)) AA
ORDER BY YearNum, MonthNum
This wraps the query in a SELECT, and filters the ranked results to the 10 you want.
Then use a matrix in the report to pivot the results.