Rank and date change case expression - sql-server

I am trying to show the second part below. If a person goes from high to low it is good but if they go from low to high it is bad. Any ideas on how I'd accomplish this? I have the SQL to return the top part but not sure how to get the second part.

you propably looking for lag function
select membno, rancs, date_rank
, case
when lag(rancs, 1, rancs) over (partition by membno order by date_rank) > rancs then 'GOOD'
when lag(rancs, 1, rancs) over (partition by membno order by date_rank) < rancs then 'BAD'
else 'i do''n know'
end second_part_for_current_row
from something
for global resoult use self join:
select curr.membno, prev.rancs, curr.rancs
, case
when prev.rancs > curr.rancs then 'GOOD'
when prev.rancs < curr.rancs then 'BAD'
else 'i do''n know'
end second_part
from something curr
left join something prev on curr.membno = prev.membno and curr.date_rank = prev.date_rank + 1
where not exists (select 1 from something pres where pres.membno = curr.membno and curr.date_rank + 1 = pres.date_rank)

Related

Fix 'Incorrect syntax near the keyword 'WHEN'' error in SQL Server?

I'm trying to implement this two when condition in the case expression but it is just not happening. Please help me fix this?
SELECT
BR, CID, TRNDATE,
CASE
WHEN TRNTYPE = '108' THEN -1 ELSE 1 * TrnAmt/100
WHEN TRNTYPE = '114' THEN (TrnIntAmt - TrnTaxAmt)/100
END as TransactionAmount
FROM
T_TRNHIST
Query Must be like that
SELECT BR, CID, TRNDATE,
CASE
WHEN TRNTYPE = '108' THEN -1
WHEN TRNTYPE = '114' THEN (TrnIntAmt - TrnTaxAmt)/100
ELSE 1 * TrnAmt/100
END as TransactionAmount
FROM T_TRNHIST
Else condition would come at last once all when done
just a little change, move the ELSE to before the END
SELECT BR, CID, TRNDATE,
CASE
WHEN TRNTYPE = '108' THEN -1
WHEN TRNTYPE = '114' THEN (TrnIntAmt - TrnTaxAmt)/100
else 1 * TrnAmt/100
END as TransactionAmount
FROM T_TRNHIST

sum(case When.. AND) with multiple conditions not working

I am trying to run this sum query to produce two columns of Turnover one for TY and another for LY. However, I want any transactions flagged as Cancelled to appear as negatives:
select [Location],BR.BranchName,
sum(case when (FX.TransactionDateKey between '20171101' and '20181031')
and ([Action] = 'Cancelled')
then FX.CustomerValue*-1 else [CustomerValue] end) as [CustmVal TY],
sum(case when (FX.TransactionDateKey between '20161101' and '20171031')
and ([Action] = 'Cancelled')
then FX.CustomerValue*-1 else FX.CustomerValue*1 end) AS [CustmVal LY]
from [dbo].[FRX_Transactions] FX
inner join DWX_Branch BR on BR.BranchID=FX.[Location]
where FX.TransactionDateKey between '20161101' and '20181031' and BR.BusinessDivision = 'Retail'
and FX.[Action] in ('Trade','cancelled') and FX.Reason in ('Public','BBG','Overridesupplyrate') and FX.Operation in ('Add','Del')
group by FX.[Location],BR.BranchName, BR.BranchOpenDate,BR.BranchCloseDate,BR.ActiveStatus
order by BR.BranchName
However, when I run it I get similar data in both columns - it seems to ignore the date conditions.
Please, what am I doing wrong? Is this case-when-statement with TWO conditions written wrong?
Any help would be HUGELY appreciated. Massive thanks!
I think what you actually want for your CASE expression is:
CASE WHEN FX.TransactionDateKey BETWEEN '20171101' AND '20181031' THEN [CustomerValue] *
CASE WHEN [Action] = 'Cancelled' THEN -1 ELSE 1 END
END

how to optimize my oracle query?

I have a query very slow and I want to optimize it. I've created index on fields for the joins. My query is this:
SELECT DISTINCT
--a.row_id FK_SERVIZIO,
--CLI_UNICO.FK_CLIENTE FK_CLIENTE,
CLI.CDC_FISCALE CDC_FISCALE,
--com.descrizione
--CASE WHEN conc.COMUNE IS NOT NULL THEN 1 ELSE 0 END FL_OFFERTABILITA_GAS
CASE WHEN exists (select 1 from STG.T_STG_NBA_DT_S_ASSET_G a where a.owner_accnt_id=CLI.IDC_CLIENTE_CRM_KEY and status_cd in ('ATTIVATO'))
THEN 'SI' ELSE 'NO' END FLC_COMUNE_TERR
FROM STG.T_STG_NBA_DT_S_ASSET_G A,
STG.T_STG_PSP_DT_LISTA_COMUNI_TERR terr,
STG.T_STG_NBA_DT_R2DG_COMUNI_G com,
STG.T_STG_NBA_DT_S_ADDR_PER_G ind_for,
--STG.V_DML_NBA_SITO q,
ODS.T_ODS_CRM_DT_CLIENTI_CRM CLI,--ODS.V_ODS_NBA_DT_ASS_CLI_CLIUNICO CLI_UNICO,
STG.T_STG_NBA_DT_S_ORG_EXT_G cforn
--STG.T_STG_NBA_DT_R2DG_CONCESS_G conc,
WHERE
--CLI.IDC_CLIENTE_CRM_KEY=A.OWNER_ACCNT_ID
terr.LDS_DESCRIZIONE_COMUNE=com.DESCRIZIONE
AND com.CODICE_ISTAT=ind_for.x_cod_istat
AND ind_for.row_id = cforn.PR_ADDR_ID
and cforn.row_id=A.serv_acct_id
i put index on this fields:
terr.LDS_DESCRIZIONE_COMUNE,com.DESCRIZIONE,com.CODICE_ISTAT,ind_for.x_cod_istat,ind_for.row_id,cforn.PR_ADDR_ID,cforn.row_id,A.serv_acct_id,a.owner_accnt_id,CLI.IDC_CLIENTE_CRM_KEY, a.status_cd.
any tips for me pls?
i can use PARALLEL? how?
THANKS
A sub select in the Select-Clause can hamper your performance badly. Just try to get rid of it.
You could do something like that
SELECT DISTINCT
--a.row_id FK_SERVIZIO,
--CLI_UNICO.FK_CLIENTE FK_CLIENTE,
CLI.CDC_FISCALE CDC_FISCALE,
--com.descrizione
--CASE WHEN conc.COMUNE IS NOT NULL THEN 1 ELSE 0 END FL_OFFERTABILITA_GAS
decode(test.cnt, 0 'NO', 'SI') FLC_COMUNE_TERR
FROM STG.T_STG_NBA_DT_S_ASSET_G A,
STG.T_STG_PSP_DT_LISTA_COMUNI_TERR terr,
STG.T_STG_NBA_DT_R2DG_COMUNI_G com,
STG.T_STG_NBA_DT_S_ADDR_PER_G ind_for,
--STG.V_DML_NBA_SITO q,
ODS.T_ODS_CRM_DT_CLIENTI_CRM CLI,--ODS.V_ODS_NBA_DT_ASS_CLI_CLIUNICO CLI_UNICO,
STG.T_STG_NBA_DT_S_ORG_EXT_G cforn,
--STG.T_STG_NBA_DT_R2DG_CONCESS_G conc,
(select count(*) cnt from STG.T_STG_NBA_DT_S_ASSET_G a where a.owner_accnt_id=CLI.IDC_CLIENTE_CRM_KEY and status_cd in ('ATTIVATO')) test
WHERE
--CLI.IDC_CLIENTE_CRM_KEY=A.OWNER_ACCNT_ID
terr.LDS_DESCRIZIONE_COMUNE=com.DESCRIZIONE
AND com.CODICE_ISTAT=ind_for.x_cod_istat
AND ind_for.row_id = cforn.PR_ADDR_ID
and cforn.row_id=A.serv_acct_id

Need to use information from one qry to dictate an action on another

Ok so this is going to sound a little complicated. I want to somehow put some kind of function that will divide a table value by two when its Policy number matches up with a policy number in another table.
Here is the query where I want that functions
SELECT
qryReinsuranceDPA1_izzy.POLICY_NO,
qryReinsuranceDPA1_izzy.PHASE_CODE,
qryReinsuranceDPA1_izzy.SUB_PHASE_CODE,
qryReinsuranceDPA1_izzy.SchedNP,
qryReinsuranceDPA1_izzy.ProdType,
Sum(qryReinsuranceDPA1_izzy.SumOfAMOUNT_INFORCE) AS SumOfSumOfAMOUNT_INFORCE,
Sum(qryReinsuranceDPA1_izzy.SumOfPUA_FACE) AS SumOfSumOfPUA_FACE,
Sum(qryReinsuranceDPA1_izzy.SumOfOYT_FACE) AS SumOfSumOfOYT_FACE, TotalDPA = sum(case when qryReinsuranceDPA1_izzy.[SumOfNetDefExtraAdj] Is Null then qryReinsuranceDPA1_izzy.[SumOfNetDefPremiumAdj] else qryReinsuranceDPA1_izzy.[SumOfNetDefPremiumAdj] +qryReinsuranceDPA1_izzy.[SumOfNetDefExtraAdj] end),
qryReinsuranceDPA1_izzy.SumOfGROSS_ANNLZD_PREM,
qryReinsuranceDPA1_izzy.SumOfStatNetPremium,
qryReinsuranceDPA1_izzy.[SumOfStatNetPremium]/qryReinsuranceDPA1_izzy.[SumOfGROSS_ANNLZD_PREM] AS NetToGrossRatio,
qryReinsuranceDPA1_izzy.NetvsGrossInd,
DPA_NetPrem = case when qryReinsuranceDPA1_izzy.[NetvsGrossInd]='Net' then sum(qryReinsuranceDPA1_izzy.[SumOfStatNetPremium]) else sum([qryReinsuranceDPA1_izzy].[SumOfGROSS_ANNLZD_PREM]) end,
qryPolicyListforNYDefPRemAsset_Re.ReinType AS ReinType,
Sum(qryPolicyListforNYDefPRemAsset_Re.ReinsAmount) AS SumOfReinsAmount,
qryPolicyListforNYDefPRemAsset_Re.[ReinsAmount]/(qryReinsuranceDPA1_izzy.[SumOfAMOUNT_INFORCE]+qryReinsuranceDPA1_izzy.[SumOfOYT_FACE]+qryReinsuranceDPA1_izzy.[SumOfPUA_FACE]) AS [Reins%],
qryPolicyListforNYDefPRemAsset_Re.ReinsStatRsv AS ReinsStatRsv,
Sum(qryPolicyListforNYDefPRemAsset_Re.SumOfGROSS_ANNLZD_PREM) AS ReinsPrem, qryReinsuranceDPA1_izzy.PAID_TO_DATE,
qryReinsuranceDPA1_izzy.VAL_DATE,
qryReinsuranceDPA1_izzy.ISSUE_DATE
FROM qryPolicyListforNYDefPRemAsset_Re RIGHT JOIN
qryReinsuranceDPA1_izzy
ON
qryReinsuranceDPA1_izzy.POLICY_NO = qryPolicyListforNYDefPRemAsset_Re.POLICY_NO
AND qryReinsuranceDPA1_izzy.PHASE_CODE = qryPolicyListforNYDefPRemAsset_Re.PHASE_CODE AND
qryReinsuranceDPA1_izzy.SUB_PHASE_CODE= qryPolicyListforNYDefPRemAsset_Re.SUB_PHASE_CODE
GROUP BY
qryReinsuranceDPA1_izzy.POLICY_NO,
qryReinsuranceDPA1_izzy.PHASE_CODE,
qryReinsuranceDPA1_izzy.SUB_PHASE_CODE,
qryReinsuranceDPA1_izzy.SchedNP,
qryReinsuranceDPA1_izzy.ProdType,
qryReinsuranceDPA1_izzy.SumOfGROSS_ANNLZD_PREM,
qryReinsuranceDPA1_izzy.SumOfStatNetPremium,
qryReinsuranceDPA1_izzy.[SumOfStatNetPremium]/qryReinsuranceDPA1_izzy.[SumOfGROSS_ANNLZD_PREM],
qryReinsuranceDPA1_izzy.NetvsGrossInd,
qryPolicyListforNYDefPRemAsset_Re.ReinType,
qryPolicyListforNYDefPRemAsset_Re.[ReinsAmount]/(qryReinsuranceDPA1_izzy.[SumOfAMOUNT_INFORCE]+qryReinsuranceDPA1_izzy.[SumOfOYT_FACE]+qryReinsuranceDPA1_izzy.[SumOfPUA_FACE]),
qryPolicyListforNYDefPRemAsset_Re.ReinsStatRsv,
qryReinsuranceDPA1_izzy.PAID_TO_DATE,
qryReinsuranceDPA1_izzy.VAL_DATE,
qryReinsuranceDPA1_izzy.ISSUE_DATE
GO
and this is the qry that contains the policy numbers that I want divided by 2 in the above qry.
SELECT
qryReinsuranceDPA1.POLICY_NO,
qryReinsuranceDPA1.PHASE_CODE,
qryReinsuranceDPA1.SUB_PHASE_CODE,
qryReinsuranceDPA1.ProdType,
TotalDPA = Sum(case when [SumOfNetDefExtraAdj] Is Null then [SumOfNetDefPremiumAdj] else [SumOfNetDefPremiumAdj] + SumOfNetDefExtraAdj end),
Sum(1) AS Expr1
FROM qryPolicyListforNYDefPRemAsset_Re RIGHT JOIN qryReinsuranceDPA1
ON
qryReinsuranceDPA1.POLICY_NO = qryPolicyListforNYDefPRemAsset_Re.POLICY_NO AND
qryReinsuranceDPA1.PHASE_CODE= qryPolicyListforNYDefPRemAsset_Re.PHASE_CODE AND
qryReinsuranceDPA1.SUB_PHASE_CODE = qryPolicyListforNYDefPRemAsset_Re.SUB_PHASE_CODE
GROUP BY qryReinsuranceDPA1.POLICY_NO,
qryReinsuranceDPA1.PHASE_CODE,
qryReinsuranceDPA1.SUB_PHASE_CODE,
qryReinsuranceDPA1.ProdType
HAVING (((Sum(1))<>1))
GO
quick example. Say that the Policy number 064543200 is located in the results of that second qry. I then want the number located in first qry in Total DPA assosciated with that Policy number to be divided by 2.
If this is still confusing please let me know and I will try to explain better. Both are views.

Order By Clause take too much time in SQL

SELECT dteRun,
CASE WHEN coalesce(nPriorityCode,0) <= 0 THEN 3
ELSE nPriorityCode
END AS nPriorityCode,
CASE WHEN sCommand IN ('DiaryWF','XC_Reminder') THEN '*'
ELSE ''
END as Alert,
sParentRef,
nWorkflowTypeCode,
sSubjectName,
sDescription,
sUniqueRef,
sUserInfo,
sUserInfo2
FROM AuroraTasksDiaryView ad
INNER JOIN UserAuthority
ON UserAuthority.UserName = ad.sOwningUser
AND ad.sOwningUser = 'ammonsd' AND ad. nErrorCode = -1
AND ad.sExcludedUser <> ad.sOwningUser
AND UserAuthority.FunctionCode = ad.sFunctionCode
AND ( (UserAuthority.LowerBound <= ad.nTaskValue
AND UserAuthority.UpperBound >= ad.nTaskValue)
OR ad.sFunctionCode = 'RTS')
AND RowNum <= 100
ORDER BY dteRun
When I omit "Order By dteRun" query runs in milliseconds however with Order By Clause it take more than minute. Whats problem with Order By Clause ?
There's presumably no index on the dteRun column. If you want to do fast ORDER BY on a column, it needs an index.
It needs an Index on columns in your Order By clause preferably in the same order.

Resources