How to aggregate and make a ratio between two fields from a CTE - sql

I have a query which return a flag wheter a client who made a contract with my company this year is new or returning:
WITH Resultset AS(
SELECT
Cnt = COUNT(*)
,KliRC --personal identification number
FROM dbo.Smlouvy
WHERE VyplacenaCastka > 0
GROUP BY KliRC
)
SELECT
s.KliRC
,CASE WHEN Cnt > 1 THEN 1 ELSE 0 END AS Novy --new client
,CASE WHEN Cnt = 1 THEN 1 ELSE 0 END AS Stavajici --existing client
FROM Resultset JOIN dbo.Smlouvy s ON s.KliRC = resultset.KliRC
WHERE (YEAR(DatumZadosti) = YEAR(GETDATE())) AND (s.KliRC NOT LIKE '%x')
Now, I need to aggregate all the new and existing clients and make a ratio between them.
Any ideas? Thanks in advance.

I think this does what you want:
WITH Resultset AS (
SELECT COUNT(*) as cnt,
KliRC --personal identification number,
(CASE WHEN COUNT(*) > 1 THEN 1 ELSE 0 END) AS Novy --new client
(CASE WHEN COUNT(*) = 1 THEN 1 ELSE 0 END) AS Stavajici
FROM dbo.Smlouvy
WHERE VyplacenaCastka > 0
GROUP BY KliRC
)
SELECT SUM(Novy) / SUM(Stavajici)
FROM Resultset r JOIN
dbo.Smlouvy s
ON s.KliRC = r.KliRC
WHERE YEAR(DatumZadosti) = YEAR(GETDATE()) AND
s.KliRC NOT LIKE '%x';

Your query can be simplified to
SELECT SUM(Novy)*1.0/SUM(Stavajici)
FROM (
SELECT KliRC
,CASE WHEN COUNT(*) OVER(PARTITION BY KliRC) > 1 THEN 1 ELSE 0 END AS Novy --new client
,CASE WHEN COUNT(*) OVER(PARTITION BY KliRC) = 1 THEN 1 ELSE 0 END AS Stavajici --existing client
FROM dbo.Smlouvy
WHERE YEAR(DatumZadosti) = YEAR(GETDATE()) AND KliRC NOT LIKE '%x'
) T

Related

How to split data in SQL

I have the following code:
select
FeeEarnerID,
(
select
(select [name] from [User] AS u where u.userid=f.userid)
from
feeearner AS f
where
f.FeeEarnerID=aa.FeeEarnerID
) FeeEarner,
sum(aa.FEES) Fees,
sum(aa.DISB) Disbursements,
sum(aa.CREDITORS) Creditors
from
(
SELECT
FeeEarner.FeeEarnerID,
case when WIPTransaction.WIPTransactionTypeID IN (1,17,18,20,21,25) then WIPTransaction.Amount else 0 end 'FEES',
case when WIPTransaction.WIPTransactionTypeID IN (2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,26,27,28,29) then WIPTransaction.Amount else 0 end 'DISB',
case when WIPTransaction.WIPTransactionTypeID IN (24) then WIPTransaction.Amount else 0 end 'CREDITORS'
FROM
(
(
FeeEarner
JOIN
WIPTransaction ON FeeEarner.FeeEarnerID = WIPTransaction.FeeEarnerID
)
JOIN
WIPTransactionType ON WIPTransactionType.WIPTransactionTypeID = WIPTransaction.WIPTransactionTypeID
)
WHERE
(WIPTransaction.TransactionDate BETWEEN '2020-10-01' AND '2020-12-31')
)
AS aa
group by
FeeEarnerID
Used Table names: WIPtransaction, WIPtransactiontype, Feeearner
I want to display two more columns at the end of the output, namely: Invoiced and Uninvoiced.
The "Invoicenumber" field in the "WIPtransaction" database will be tested for this. If the "Invoicenumber" is NULL - the transaction amount will be added to a sum in the uninvoiced column and if "Invoicenumber" contains a number - the transaction amount will be added to a sum in the invoiced column.
What is the code that I would need to write and where would it be placed?
select
FeeEarnerID,
(
select
(select [name] from [User] AS u where u.userid=f.userid)
from
feeearner AS f
where
f.FeeEarnerID=aa.FeeEarnerID
) FeeEarner,
sum(aa.FEES) Fees,
sum(aa.DISB) Disbursements,
sum(aa.CREDITORS) Creditors,
----------
SUM( InvoicedAmount) AS InvoicedAmount,
SUM(UnInvoicedAmount) AS UnInvoicedAmount
----------
from
(
SELECT
FeeEarner.FeeEarnerID,
case when WIPTransaction.WIPTransactionTypeID IN (1,17,18,20,21,25) then WIPTransaction.Amount else 0 end 'FEES',
case when WIPTransaction.WIPTransactionTypeID IN (2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,26,27,28,29) then WIPTransaction.Amount else 0 end 'DISB',
case when WIPTransaction.WIPTransactionTypeID IN (24) then WIPTransaction.Amount else 0 end 'CREDITORS',
----------
CASE WHEN WIPTransaction.Invoicenumber IS NOT NULL THEN WIPTransaction.Amount END AS InvoicedAmount,
CASE WHEN WIPTransaction.Invoicenumber IS NULL THEN WIPTransaction.Amount END AS UnInvoicedAmount
----------
FROM
FeeEarner
JOIN
WIPTransaction ON FeeEarner.FeeEarnerID = WIPTransaction.FeeEarnerID
JOIN
WIPTransactionType ON WIPTransactionType.WIPTransactionTypeID = WIPTransaction.WIPTransactionTypeID
WHERE
WIPTransaction.TransactionDate BETWEEN '2020-10-01' AND '2020-12-31'
)
AS aa
group by
FeeEarnerID
You can remove your derived query and combine it all into one. The FeeEarner double sub-query can also be optimized:
select
FeeEarnerID,
(
select [name] from [User] AS u where u.userid=FeeEarner.userid
) FeeEarner,
sum(case when WIPTransaction.WIPTransactionTypeID IN (1,17,18,20,21,25) then WIPTransaction.Amount else 0 end) Fees,
sum(case when WIPTransaction.WIPTransactionTypeID IN (2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,26,27,28,29) then WIPTransaction.Amount else 0 end) Disbursements,
sum(case when WIPTransaction.WIPTransactionTypeID IN (24) then WIPTransaction.Amount else 0 end) Creditors,
SUM(CASE WHEN WIPTransaction.Invoicenumber IS NOT NULL THEN WIPTransaction.Amount END) AS InvoicedAmount,
SUM(CASE WHEN WIPTransaction.Invoicenumber IS NULL THEN WIPTransaction.Amount END) AS UnInvoicedAmount
FROM
FeeEarner
JOIN
WIPTransaction ON FeeEarner.FeeEarnerID = WIPTransaction.FeeEarnerID
JOIN
WIPTransactionType ON WIPTransactionType.WIPTransactionTypeID = WIPTransaction.WIPTransactionTypeID
WHERE
WIPTransaction.TransactionDate BETWEEN '2020-10-01' AND '2020-12-31'
group by
FeeEarnerID;

SQL CASE WHEN THEN logics of calculating the types of a column

Have a tableA like this:
I wanna receive a tableИ like this (group by startTime and endTime, count of Severity in cnt column and count of every type of Severity in a distinct column):
The simple count (cnt column) works fine. But with the other I tired CASE WHEN THEN logics and it seems not working (line 10 for example). Can you please assist me with SQL query in this case.
You need conditional aggregation :
select starttime, endtime, count(*),
sum(case when severity = 'low' then 1 else 0 end),
sum(case when severity = 'med' then 1 else 0 end),
sum(case when severity = 'high' then 1 else 0 end)
from table t
group by starttime, endtime;
Try below query: with case when
select starttime, endtime, count(severity) as cnt, count(case when severity='LOW' then 1 end) cnt_low,count(case when severity='MED' then 1 end) cnt_med,count(case when severity='HIGH' then 1 end) as cnt_high
from tablename
group by starttime, endtime
use case when and aggregate function sum
select startTime , endTime,count(*) as Cnt,
sum( case when Severity='MED' then 1 else 0 end) as cntMed,
sum( case when Severity='LOW' then 1 else 0 end) as cntLow,
sum( case when Severity='HIGH' then 1 else 0 end) as cntHIGH from yourtable
group by startTime , endTime

Sql Query to Compare Same Field having differnet values because of Group Clause

I Have Query where I need to compare a amount field which has grouped by debit credit, I want to get the out put where the amount of credit is not equal to amount of debit the query is
select t_vocno,
sum(t_amt),
dc_type
from accotran
where f_yr = '1718'
and comp_cd = 'skl'
group by t_vocno,
dc_type
order by t_vocno
which gives output
1 215452.1600 D
1 215452.1600 C
2 207586.0000 D
2 207586.0000 C
3 248789.0000 D
3 248789.0000 C
I have very bid data so I want to put a having condition and get the data where debit <> credit
I have tried
select t_vocno,
sum(t_amt),
dc_type
from accotran
where f_yr = '1718'
and comp_cd = 'skl'
group by t_vocno,
dc_type
having case when dc_type= 'c' and t_vocno = t_vocno then sum(t_amt) end <>
case when dc_type= 'd' and t_vocno = t_vocno then sum(t_amt) end
order by t_vocno
You can GROUP BY just t_vocno and use conditional aggregation to calculate credit / debit sums:
select t_vocno,
sum(case when dc_type= 'c' then t_amt else 0 end) as c_sum,
sum(case when dc_type= 'd' then t_amt else 0 end) as d_sum
from accotran
where f_yr = '1718'
and comp_cd = 'skl'
group by t_vocno
having sum(case when dc_type= 'c' then t_amt else 0 end) <>
sum(case when dc_type= 'd' then t_amt else 0 end)
order by t_vocno

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

Is it possible to use 'case' with and in 'count'?

Is it possible to use case with and in count
SELECT branches.NAME AS agence,
count(
CASE loanstatus
WHEN '1'
AND Datepart(month,loanaccount.issuedate)= 2 THEN 1
ELSE NULL
END )AS nombre_de_credits_demande ,
count(
CASE loanstatus
WHEN '2' datepart(month,loanaccount.chargeoffdate)= 2 THEN 1
ELSE NULL
END )AS nombre_de_credits_approuve
please help me
You can use it with count(). I prefer sum():
select Branches.Name as Agence,
sum(case when LoanStatus = '1' and
datepart(MONTH, LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Demandé ,
sum(case when LoanStatus = '2' and
datepart(MONTH, LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Approuvé
The issue with your code was not the count() versus sum() it is the mixing of two different case syntaxes. When you use case <var> when <val>, you cannot include any other conditions. Just use when with the full conditions that you want.
And, if you like, you can use count() instead of sum().
And, for conciseness, I prefer the month() function:
select Branches.Name as Agence,
sum(case when LoanStatus = '1' and MONTH(LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Demandé ,
sum(case when LoanStatus = '2' and MONTH(LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Approuvé
you can achieve your goal through this query.
select
branches.name as agence
,(select COUNT(1) from <table_name> where loginstatus=1 and Datepart(month,loanaccount.issuedate)= 2) as nombre_de_credits_demande
,(select COUNT(1) from <table_name> where loginstatus=2 and Datepart(month,loanaccount.issuedate)= 2) as AS nombre_de_credits_approuve
from <Table_name>