How to join two queries in SQL - sql

I have two SQL queries that I want to join.
First query:
SELECT
rp_date, key_code,
sum(case when rp_id=15102 then rp_value else null end) as users_completed,
sum(case when rp_id=15108 then rp_value else null end) as users_inProgress
FROM
te_rp_pc_rate
WHERE
abc_code = 'A204'
AND organisation_id = '444-4'
AND key_ code = '#KL0560'
GROUP BY
rp_date, key_code
ORDER BY
rp_date DESC, key_code
LIMIT 100;
Second query:
SELECT
cr_date
sum(case when rp_id=23101 then rp_value else null end) AS prim_kfc
FROM
te_emk_rate
WHERE
abc_code = 'A204'
AND organisation_id = '444-4'
AND ref_value = 0
GROUP BY
cr_date
ORDER BY
cr_date DESC
LIMIT 100;
The dates (cr_date, rp_date) should be used for joining. For the first query's rp_date for the second cr_date.
The goal is to get the columns in a row for the same date. I've tried, but the results are too high.

You can put your queries into subqueries and join them. Something like this:
SELECT *
FROM (
SELECT rp_date, key_code,
sum(case when rp_id=15102 then rp_value else null end) as users_completed,
sum(case when rp_id=15108 then rp_value else null end) as users_inProgress
from te_rp_pc_rate
WHERE abc_code = 'A204'
AND organisation_id = '444-4'
AND key_ code = '#KL0560'
group by rp_date, key_code
Order By rp_date DESC, key_code
LIMIT 100;
) as q1
LEFT JOIN (
SELECT cr_date, key_code
sum(case when rp_id=23101 then rp_value else null end) as prim_kfc
from te_emk_rate
WHERE abc_code = 'A204'
AND organisation_id = '444-4'
AND ref_value = 0
group by cr_date, key_code
Order By cr_date DESC, key_code
LIMIT 100;
) as q2
on q1.rp_date = q2.cr_date

Related

How to exclude 0 from count()? in sql?

I have a code as below where I want to count number of first purchases for a given period of time. I have a column in my sales table where if the buyer is not a first time buyer, then is_first_purchase = 0
For example:
buyer_id = 456391 is already an existing buyer who made purchases on 2 different dates.
Hence is_first_purchase column will show as 0 as per below.
If i do a count() on is_first_purchase for this buyer_id = 456391 then it should return 0 instead of 2.
My query is as follows:
with first_purchases as
(select *,
case when is_first_purchase = 1 then 'Yes' else 'No' end as first_purchase
from sales)
select
count(case when first_purchase = 'Yes' then 1 else 0 end) as no_of_first_purchases
from first_purchases
where buyer_id = 456391
and date_id between '2021-02-01' and '2021-03-01'
order by 1 desc;
It returned the below which is not an intended output
Appreciate if someone can help explain how to exclude is_first_purchase = 0 from the count, thanks.
Because COUNT function count when the value isn't NULL (include 0), if you don't want to count, need to let CASE WHEN return NULL
There are two ways you can count as your expectation, one is SUM other is COUNT but remove the part of else 0
SUM(case when first_purchase = 'Yes' then 1 else 0 end) as no_of_first_purchases
COUNT(case when first_purchase = 'Yes' then 1 end) as no_of_first_purchases
From your question, I would combine CTE and main query as below
select
COUNT(case when is_first_purchase = 1 then 1 end) as no_of_first_purchases
from sales
where buyer_id = 456391
and date_id between '2021-02-01' and '2021-03-01'
order by 1 desc;
I think that you are using COUNT() when you want SUM().
with first_purchases as
(select *,
case when is_first_purchase = 1 then 'Yes' else 'No' end as first_purchase
from sales)
select
SUM(case when first_purchase = 'Yes' then 1 else 0 end) as no_of_first_purchases
from first_purchases
where buyer_id = 456391
and date_id between '2021-02-01' and '2021-03-01'
order by 1 desc;
You could simplify your query as:
SELECT COUNT(*) AS
FROM sales no_of_first_purchases
WHERE is_first_purchase = 1
AND buyer_id = 456391
AND date_id BETWEEN '2021-02-01' AND '2021-03-01'
ORDER BY 1 DESC;
It is better to avoid the use of functions like IF and CASE when it can be done with WHERE.
The simplest approach for Trino (f.k.a. Presto SQL) is to use an aggregate with a filter:
count(name) FILTER (WHERE first_purchase = 'Yes') AS no_of_first_purchases

Nested CASE statements in SQL

I am running the below SQL and I need to add a case statement for the svcState column.
I have a value defined for each number in that column which I need to have in my query. For instance 7 is OK, 4 is down etc. I tried adding this in the CASE statement as below and it seems, the syntax is incorrect. Any help will be greatly appreciated.
SELECT * FROM
(
SELECT
A.NodeName AS NodeName,
MAX(CASE WHEN Poller_Name='svcServiceName' THEN CAST(Status AS varchar) ELSE ''END) svcServiceName,
MAX(CASE (CASE WHEN Poller_Name='svcState' AND Status ='7' THEN 'OK'
WHEN Poller_Name='svcstate' AND Status ='4' THEN 'OUT OF SERVICE' END)
THEN CAST(Status AS bigint) ELSE '' END) svcState
FROM
(
SELECT
Nodes.Caption AS NodeName, CustomNodePollers_CustomPollers.UniqueName AS Poller_Name, CustomNodePollerStatus_CustomPollerStatus.Status AS Status, CustomNodePollerStatus_CustomPollerStatus.rowid as row, CustomNodePollerStatus_CustomPollerStatus.RawStatus as RawStatus
FROM
((Nodes INNER JOIN CustomPollerAssignment CustomNodePollerAssignment_CustomPollerAssignment ON (Nodes.NodeID = CustomNodePollerAssignment_CustomPollerAssignment.NodeID)) INNER JOIN CustomPollers CustomNodePollers_CustomPollers ON (CustomNodePollerAssignment_CustomPollerAssignment.CustomPollerID = CustomNodePollers_CustomPollers.CustomPollerID)) INNER JOIN CustomPollerStatus CustomNodePollerStatus_CustomPollerStatus ON (CustomNodePollerAssignment_CustomPollerAssignment.CustomPollerAssignmentID = CustomNodePollerStatus_CustomPollerStatus.CustomPollerAssignmentID)
WHERE
(
(CustomNodePollers_CustomPollers.UniqueName = 'svcServiceName') OR
(CustomNodePollers_CustomPollers.UniqueName = 'svcState')
)
AND
(
(CustomNodePollerAssignment_CustomPollerAssignment.InterfaceID = 0)
)
and Nodes.Caption = '101'
)A
GROUP BY NodeName, row
--ORDER BY svcServiceName
) B
Desired Output
MAX(CASE WHEN Poller_Name = 'svcState' THEN (CASE WHEN status = '7' THEN 'OK' ELSE 'DOWN' END) END)
Or...
MAX(CASE WHEN Poller_Name = 'svcState' AND status = '7' THEN 'OK'
WHEN Poller_Name = 'svcState' AND status = '4' THEN 'DOWN' END)
Or...
MAX(CASE WHEN Poller_Name != 'svcState' THEN NULL -- Assumes the poller_name is never NULL
WHEN status = '7' THEN 'OK'
WHEN status = '4' THEN 'DOWN'
END)
Where there is no ELSE specified, it is implicitly ELSE NULL, and NULL values are skipped by the MAX().

Trouble with SQL request

I just want to output only those records, that for the same name customer_name have cust_valid= 'I' and cust_valid='A'
I tried to do this, but the rezult for cust_valid have only records 'A' enter code here
SELECT c.cust_first_name ||' '|| c.cust_last_name AS CUSTOMER_NAME,
to_number(SUBSTR(c.cust_income_level, INSTR(c.cust_income_level, '-')+2), '999999') as UPPER_INCOME_LEVEL,
sum(s.amount_sold) as TOTAL_AMOUNT,
(CASE WHEN c.cust_credit_limit <= 1500 THEN 'Low_limit'
ELSE 'High_limit'
END) credit_limit_level,
c.cust_valid
FROM SH.customers c
JOIN sh.sales s on c.cust_id = s.cust_id
WHERE c.cust_valid = 'A' AND c.cust_income_level like '%-%'
GROUP BY c.cust_first_name, c.cust_last_name, c.cust_income_level, c.cust_credit_limit, c.cust_valid
HAVING SUM(s.amount_sold) > (c.cust_credit_limit * 50)
ORDER BY UPPER_INCOME_LEVEL DESC, CUSTOMER_NAME;
You need to use the EXISTS clause in WHERE condition as follows:
and exists (select 1
from sh.customers cin
where cin.cust_id = c.cust_id
and c.c.cust_valid = 'I'
)
If I followed you correctly, you can implement this filtering by modifying your having clause:
HAVING
SUM(s.amount_sold) > (c.cust_credit_limit * 50)
AND MAX(CASE WHEN cust_valid= 'I' THEN 1 ELSE 0 END) = 1
AND MAX(CASE WHEN cust_valid= 'A' THEN 1 ELSE 0 END) = 1
and cust_valid='A'
I tried, but no result.
I dont think I showed the condition correct.
I have to explain...
Modify the query to display the name of the client (CUSTOMER_NAME)
for which there are rows with CUST_VALID = ā€˜Aā€™ and rows with
CUST_VALID = ā€˜Iā€™ as a separate result.

SSRS: how to get top 3 in order Z to A

I try to get in my diagram the top 3 of the worst value in SSRS:
my Code:
SELECT *
FROM (
Select top 3
intervaldate as Datum
,Name
,teamname as Team
,SUM(case when CounterName = 'Blown away' then calculationUnits else 0 end) as Blown
,Sum(case when CounterName = 'Thrown away' then calculationUnits else 0 end) as Thrown
,Sum(case when CounterName = 'total' then calculationUnits else 0 end) as Total
from Counting
where IntervalDate >= dateadd(day,datediff(day,1,GETDATE()),0)
AND IntervalDate < dateadd(day,datediff(day,0,GETDATE()),0)
and Name in (Select SystemID from tSystemView where SystemViewID = 2)
group by intervaldate, teamName, Name
) c
Expression of the diagram:
=Sum(Fields!Blown.Value + Fields!Thrown.Value) / Sum(Fields!Total.Value) * 100
And I sorted it from highest to lowest
But it does not show me the right order.
If I choose every "Name" then it shows me other value then the top 3:
all Names with value:
top 3:
It's because your top 3 statement is in the SQL while your sort is in the report. Without an order by SQL picks the top 3 random records. Also, unless there is more SQL you are not showing, the outer select is unnecessary. Add an order by <column> desc below your group by.
with Calcs as
(
select intervaldate as Datum,
Name,
TeamName,
SUM(case when CounterName = 'Blown away' then calculationUnits else 0 end) as Blown,
Sum(case when CounterName = 'Thrown away' then calculationUnits else 0 end) as Thrown,
Sum(case when CounterName = 'total' then calculationUnits else 0 end) as Total
from Counting
where IntervalDate >= dateadd(day,datediff(day,1,GETDATE()),0)
AND IntervalDate < dateadd(day,datediff(day,0,GETDATE()),0)
and Name in (Select SystemID from tSystemView where SystemViewID = 2)
group by intervaldate, teamName, Name
)
select b.*
from
(
select a.*, row_number() over (order by (Blown + Thrown)/Total desc) as R_Ord -- Change between ASC/DESC depending on needs
from Calcs a
) b
where R_Ord <=3

Update a complex SQL query to add a new column with the sum of two columns

The below SQL query creates a table with n number of columns named in the next line.
...., curr_amount, tax_amount, ....
I am having a very tough time updating the below query to create a new column called total and position it exactly after tax_amount column and the total column should contain the values that are obtained after sum of curr_amount & tax_amount.
I have been working on this from more than one day but couldn't figure it out.
P.S. Still a noob here. Thanks alot for your time.
.
SELECT Isnull(t.total_month, 'Total') total_month,
t.tax_amount,
t.curr_amount,
t.usage_qty,
t.kh_qty,
t.bill_cnt
FROM (SELECT dbo.Sigmadf(bm.posted_date, 'YYYY-MM') total_month,
Sum(CASE
WHEN rr.usage_qty IS NULL THEN 0
ELSE Cast (rr.usage_qty AS NUMERIC(18, 2))
END) usage_qty,
Sum(CASE
WHEN bm.curr_amount IS NULL THEN 0
ELSE bm.curr_amount
END) curr_amount,
Sum(CASE
WHEN bm.adj_amount IS NULL THEN 0
ELSE bm.adj_amount
END) adj_amount,
Sum(CASE
WHEN bm.bal_fwd_amount IS NULL THEN 0
ELSE bm.bal_fwd_amount
END) bal_forward,
Sum(CASE
WHEN bm.tax_amount IS NULL THEN 0
ELSE bm.tax_amount
END) tax_amount,
Sum(CASE
WHEN bm.due_amount IS NULL THEN 0
ELSE bm.due_amount
END) due_amount,
Sum(CASE
WHEN bm.last_total_paid_amount IS NULL THEN 0
ELSE bm.last_total_paid_amount * -1
END) paid_amount,
Sum(CASE
WHEN bm.bill_print = 'Y' THEN 1
ELSE 0
END) pdf_cnt,
Sum(CASE
WHEN Isnull(bm.bill_handling_code, '0') = '0' THEN 1
ELSE 0
END) reg_cnt,
Sum(CASE
WHEN Isnull(bm.bill_handling_code, '0') = '1' THEN 1
ELSE 0
END) ftime_cnt,
Sum(CASE
WHEN Isnull(bm.bill_handling_code, '0') = '9999' THEN 1
ELSE 0
END) ltime_cnt,
Count(*) bill_cnt,
Sum(CASE
WHEN bill_status = '01' THEN 1
ELSE 0
END) canc_cnt,
Sum(CASE
WHEN bill_status = '01' THEN
CASE
WHEN rr.usage_qty IS NULL THEN 0
ELSE Cast (rr.usage_qty AS NUMERIC(18, 2))
END
ELSE 0
END) canc_usg,
Sum(CASE
WHEN vis.kh_qty IS NULL THEN 0
ELSE Cast(vis.kh_qty AS NUMERIC(18, 2))
END) kh_qty
FROM bill_master bm WITH (nolock)
INNER JOIN (SELECT bill_no,
Sum(CASE
WHEN vpb.recurr_charge_type IN ( 'T4',
'SLF' )
THEN
CASE
WHEN vpb.print_qty = 'Y'
AND vpb.usage_qty IS NOT NULL
THEN
Cast (vpb.usage_qty AS
NUMERIC(18, 2))
ELSE 0
END
ELSE 0
END) usage_qty
FROM v_print_bills_all vpb
GROUP BY bill_no) rr
ON rr.bill_no = bm.bill_no
LEFT OUTER JOIN vis_bill_master_cr vis WITH (nolock)
ON bm.bill_no = vis.bill_no
WHERE 1 = 1
AND dbo.Trunc(bm.posted_date) >= '20150101'
AND dbo.Trunc(bm.posted_date) <= '20151124'
AND bm.posted_date IS NOT NULL
AND bm.cust_id NOT IN (SELECT cc.code_type cust_id
FROM code_table cc WITH (nolock)
WHERE cc.code_tabname = 'RptExclCust'
AND cc.code_value = 'cust_id')
GROUP BY dbo.Sigmadf(bm.posted_date, 'YYYY-MM') WITH rollup)t
I must say that the explanation is not so clear.
From my understanding, you want the total of two columns.
So, wrap all your query between parenthesis, call it subQuery, and make the sum of the two columns on top:
SELECT subQuery.total_month as bill_date,
subQuery.curr_amount as amount,
subQuery.tax_amount tax,
subQuery.curr_amount + subQuery.tax_amount as [total],
...
FROM
(..your entire query here..) as subQuery