SQL Month comparison to declared variable - sql

select
sc.locationid, --here to get a result
(
if month(date()) between 8 and 12 then #semTerm = 'S1'
else #semTerm = 'S2'
end if
)as #semTerm
from student_class sc
where #semTerm = sc.semester
;
In db2 student management system. Read only access. Desired outcome is If Jan thru June, S2 else if Aug thru Dec, S1. Trying to setup a variable based on the current date stamp where the month is segregated then assigned to a variable then compared against a column in student_class table.
Have tried case statements as well with no luck. Unable to declare #semTerm without error above select statement. Looked at where clause solution also. Am I out in left field? Seems simple but struggling with the syntax. Part of a larger statement with locationID as one column in student_class.

You can't really use an IF statement in a simple SELECT statement, you must use CASE:
select
sc.locationid, --here to get a result
case
when month(current date) between 8 and 12 then 'S1'
when month(current date) between 1 and 6 then 'S2'
else ''
end as semTerm
from
student_class sc
If you want to find only the students for the current semester, then you would want to move the CASE statement into the WHERE clause:
select
sc.locationid, --here to get a result
sc.semester,
...
from
student_class sc
where
sc.semester = case
when month(current date) between 8 and 12 then 'S1'
when month(current date) between 1 and 6 then 'S2'
end

A CASE expression is generally the way to implement conditional logic in a SELECT statement. However, it would be more efficient if you didn't have to recalculate it on every row, right?
One approach would be to "precalculate" it in a common table expression, and join to that as your selection criteria:
with v (semester) as
( values
case
when month(current date) > 7 then 'S1'
when month(current date) < 7 then 'S2'
else null
end
)
select
sc.locationid,
sc.semester,
...
from
student_class sc
join
v on sc.semester = v.semester;
OR
If you you find that this current semester value would be useful in many other places, another approach could be to create a 'global session variable' to hold the value. (except on z/OS)
create or replace variable
v_sememster char(2)
default
case
when month(current date) > 7
then 'S1'
when month(current date) < 7
then 'S2'
else null
end;
Then you can have a very simple query:
select
sc.locationid,
sc.semester,
...
from
student_class sc
where
sc.semester = v_semester;

Related

How to select data without using group?

My base data based on dealer code only but in one condition we need to select other field as well to matching the condition in other temp table how can i retrieve data only based on dealercode ith matching the condition on chassis no.
Below is the sample data:
This is how we have selected the data for the requirement:
---------------lastyrRenewalpolicy------------------
IF OBJECT_ID('TEMPDB..#LASTYRETEN') IS NOT NULL DROP TABLE #LASTYRETEN
select DEALERMASTERCODE , count(*) RENEWALEXPRPOLICY,SUM(NETOD_YEAR_PREM_PART_A) AS 'ACHIEVED-ODPREMIUM_RENEWAL' into #LASTYRETEN
from [dbo].[T_RE_POLICY_TRANSACTION]
where cast (InsPolicyCreatedDate as date) between #FirstDayC and #LastDayC
AND PolicyStatus= 'Renewal' AND (ltrim(rtrim(ISCANCELLEDSTATUS)) = 0 ) group by DEALERMASTERCODE
-----------------lastrollower------------------------
IF OBJECT_ID('TEMPDB..#LASTYROLWR') IS NOT NULL DROP TABLE #LASTYROLWR
select DEALERMASTERCODE , count(*) ROLLOWEEXPRPOLICY ,SUM(NETOD_YEAR_PREM_PART_A) AS 'ACHIEVED-ODPREMIUM_ROLLOVER'
into #LASTYROLWR from [dbo].[T_RE_POLICY_TRANSACTION] where cast (InsPolicyCreatedDate as date) between #FirstDayC and #LastDayC
AND PolicyStatus= 'ROLLOVER' AND (ltrim(rtrim(ISCANCELLEDSTATUS)) = 0 ) group by DEALERMASTERCODE
And continue with above flow Below is the other select statement which creating issue at the end due to grouping
:
-------------OTHERYRBASE(EXPIRYRENEWAL)--------------
IF OBJECT_ID('TEMPDB..#OTHERYRBASEEXPIRY') IS NOT NULL DROP TABLE #OTHERYRBASEEXPIRY
select DEALERMASTERCODE ,ChassisNo , count(*) RENEWALPOLICYEXPIRY
into #OTHERYRBASEEXPIRY
from [dbo].[T_RE_POLICY_TRANSACTION] where cast (PolicyExpiryDate as date) between '2020-08-01' and '2020-08-31'
and BASIC_PREM_TOTAL <> 0 AND PolicyStatus in ('Renewal','rollover') and BusinessType='jcb'
AND (ltrim(rtrim(ISCANCELLEDSTATUS)) = 0 ) group by DEALERMASTERCODE,ChassisNo
-------------OTHERYRBASE(EXPIRYRENEWAL)--------------
IF OBJECT_ID('TEMPDB..#OTHERYRCON') IS NOT NULL DROP TABLE #OTHERYRCON
select OTE.DEALERMASTERCODE ,OTE.ChassisNo , count(*) OTHERYRCON into #OTHERYRCON
from [dbo].[T_RE_POLICY_TRANSACTION] OTE INNER JOIN #OTHERYRBASEEXPIRY EXP
ON OTE.ChassisNo=EXP.ChassisNo
where cast(CREATED_DATE as date) between '2020-06-01' and '2020-12-31' and BusinessType='jcb'
and OTE.BASIC_PREM_TOTAL <> 0 AND OTE.PolicyStatus = 'Renewal'
AND (ltrim(rtrim(ISCANCELLEDSTATUS)) = 0 ) group by OTE.DEALERMASTERCODE,OTE.ChassisNo
Thanks a lot in advance for helping and giving a solution very quickly ///
After taking a look at this code it seems possible there was an omitted JOIN condition in the last SELECT statement. In the code provided the JOIN condition is only on ChassisNo. The GROUP BY in the prior queries which populates the temporary table also included the DEALERMASTERCODE column. I'm thinking DEALERMASTERCODE should be added to the JOIN condition. Something like this
select OTE.DEALERMASTERCODE ,OTE.ChassisNo , count(*) OTHERYRCON
into #OTHERYRCON
from [dbo].[T_RE_POLICY_TRANSACTION] OTE
INNER JOIN #OTHERYRBASEEXPIRY EXP ON OTE.DEALERMASTERCODE=EXP.DEALERMASTERCODE
and OTE.ChassisNo=EXP.ChassisNo
where cast(CREATED_DATE as date) between '2020-06-01' and '2020-12-31'
and BusinessType='jcb'
and OTE.BASIC_PREM_TOTAL <> 0
AND OTE.PolicyStatus = 'Renewal'
AND (ltrim(rtrim(ISCANCELLEDSTATUS)) = 0 )
group by OTE.DEALERMASTERCODE,OTE.ChassisNo;

Building Subquery to be a column/Field Name

I am unable to bundled groups of subqueries correctly in order to create column titled "Discharge_To"
I am using Teradata Studio Express. I was asked to create a column for field that is not inside a table we normally used. We want to know where a patient was discharged to from a previous place of service. In order to answer this, there has to be steps to determine that. So far, I can get it read correctly until line 94.
Select S.Member_ID, S.PAC_Sty_ID, S.Stay_Admit_Date, S.Stay_Discharge_Date, S.POS, S.LOS,
(
Select
S.Member_ID, S.PAC_Sty_ID,
Case
When S.Discharge_To is null
and H.POS is not null And S.POS <> '12' then 'Home With Care'
When S.Discharge_To is null then 'Home Without Care'
Else S.Discharge_To
End Discharge_To
From (
Select
S.Member_ID, S.PAC_Sty_ID, S.Stay_Admit_Date, S.Stay_Discharge_Date, S.POS,
Case trim(D.POS)
When '21' then 'Hospital' When '23' then 'ER' When '31' then 'SNF'
When '61' then 'IRF' When 'LTAC' then 'LTAC'
End Discharge_To
From ECONIMICS.PAC_02_MODEL_SUMMARY_Combined S
Left Join (
Select S.Member_ID, S.PAC_Sty_ID, S.POS, S.Stay_Admit_Date, S.Stay_Discharge_Date
From ECONIMICS.PAC_02_MODEL_SUMMARY_Combined S
Where PAC_Sty_ID is not null
And POS <> '12'
) D On D.Member_ID = S.Member_ID And D.PAC_Sty_ID <> S.PAC_Sty_ID
And D.Stay_Admit_Date Between S.Stay_Admit_Date and S.Stay_Discharge_Date + 1
Where S.PAC_Sty_ID is not null
Qualify Row_Number() Over (
Partition By S.PAC_Sty_ID Order By Case trim(D.POS)
When '21' then 1 When 'LTAC' then 2 when '61' then 3 When '31' then 4 end
) = 1
) S
Left Join (
Select *
From ECONIMICS.PAC_02_MODEL_SUMMARY_Combined
Where POS = '12'
) H On H.Member_ID = S.Member_ID
And H.From_Date Between S.Stay_Discharge_Date and S.Stay_Discharge_Date + 7
Qualify Row_Number() Over (Partition By S.PAC_Sty_ID Order By H.From_Date) = 1
) E On E.Member_ID = S.Member_ID And E.PAC_Sty_ID = S.PAC_Sty_ID
Where S.PAC_Sty_ID is not Null
AND S.STAY_DISCHARGE_DATE between '2017-01-01' and '2020-12-31'
AND S.LOB in ('CARE', 'DUAL')
AND S.ORPHAN_CLM_ID IS NULL
AND S.ORPHAN_CLM_LN IS NULL
Group By 1, 2, 3, 4, 5, 6
There should be 7 columns with the 7th column titled "Discharge_to" and values in the seventh column would be text (e.g., "Home without Care")
Posting here, since it's easier. Your query doesn't seem to be formatted correctly. It's of this form:
select S.Member_ID, ... ,
(
Select ... -- Sub-query trying to derive Discharge_To field
) E on E.Member_ID = S.Member_ID ...
where ...
A couple notes:
There is no FROM clause in the outer query yet you are trying to return S. fields
There is no S result set to join your E result to
The E result set is trying to be used as a sub-SELECT, but it also has an alias
Not knowing what your error message is, I'd suggest breaking apart the query into its sub-queries and running those individually to try to determine where the problem lies.

Bring through a newly created calculated column in another query

I have 2 separate queries below which run correctly.Now I've created a calculated column to provide a count of working days by YMs and would like to bring this through to query1(the join would be query1.Period = query2.Yms)
please see the query and outputs below.
SELECT Client, ClientGroup, Type, Value, Period, PeriodName, PeriodNumber, ClientName
FROM metrics.dbo.vw_KPI_001_Invoice
select YMs,sum(case when IsWorkDay = 'X' then 1 else 0 end) from IESAONLINE.Dbo.DS_Dates
where Year > '2013'
group by YMs
Query 1
Client ClientGroup Type Value Period PeriodName PeriodNumber ClientName
0LG0 KarroFoods Stock 5691.68 201506 Week 06 2015 35 Karro Foods Scunthorpe
Query 2
YMs (No column name)
201401 23
Would the following work:
SELECT Client, ClientGroup, Type, Value, Period, PeriodName, PeriodNumber, ClientName, cnt
FROM metrics.dbo.vw_KPI_001_Invoice q1
INNER JOIN (select YMs,sum(case when IsWorkDay = 'X' then 1 else 0 end) as cnt from IESAONLINE.Dbo.DS_Dates
where Year > '2013'
group by YMs ) q2 ON q1.Period = q2.YMs
If a value isn't always available then you might consider changing the INNER JOIN to an OUTER JOIN.

Work Around for SQL Query 'NOT IN' that takes forever?

I am trying to run a query on an Oracle 10g DB to try and view 2 groups of transactions. I want to view basically anyone who has a transaction this year (2014) that also had a transaction in the previous 5 years. I then want to run a query for anyone who has a transaction this year (2014) that hasn't ordered from us in the last 5 years. I assumed I could do this with the 'IN' and 'NOT IN' features. The 'IN' query runs fine but the 'NOT IN' never completes. DB is fairly large which is probably why. Would love any suggestions from the experts!
*Notes, [TEXT] is a description of our Customer's Company name, sometimes the accounting department didn't tie this to our customer ID which left NULL values, so using TEXT as my primary grouping seemed to work although the name is obscure. CODE_D is a product line just to bring context to the name.
Below is my code:
SELECT CODE_D, sum(coalesce(credit_amount, 0) - coalesce(debet_amount,0)) as TOTAL
FROM
gen_led_voucher_row_tab
WHERE ACCOUNTING_YEAR like '2014'
and TEXT NOT IN
(select TEXT
from gen_led_voucher_row_tab
and voucher_date >= '01-JUN-09'
and voucher_date < '01-JUN-14'
and (credit_amount > '1' or debet_amount > '1')
)
GROUP BY CODE_D
ORDER BY TOTAL DESC
Try using a LEFT JOIN instead of NOT IN:
SELECT t1.CODE_D, sum(coalesce(t1.credit_amount, 0) - coalesce(t1.debet_amount,0)) as TOTAL
FROM gen_led_voucher_row_tab AS t1
LEFT JOIN gen_led_voucher_row_tab AS t2
ON t1.TEXT = t2.TEXT
AND t2.voucher_date >= '01-JUN-09'
AND t2.voucher_date < '01-JUN-14'
AND (credit_amount > '1' or debet_amount > '1')
WHERE t2.TEXT IS NULL
AND t1.ACCOUNTING_YEAR = '2014'
GROUP BY CODE_D
ORDER BY TOTAL DESC
ALso, make sure you have an index on the TEXT column.
You can increase your performance by changing the Not In clause to a Where Not Exists like as follows:
Where Not Exists
(
Select 1
From gen_led_voucher_row_tab b
Where voucher_date >= '01-JUN-09'
and voucher_date < '01-JUN-14'
and (credit_amount > '1' or debet_amount > '1')
And a.Text = b.Text
)
You'll need to alias the first table as well to a for this to work. Essentially, you're pulling back a ton of data to just discard it. Exists invokes a Semi Join which does not pull back any data at all, so you should see significant improvement.
Edit
Your query, as of the current update to the question should be this:
SELECT CODE_D,
sum(coalesce(credit_amount, 0) - coalesce(debet_amount,0)) as TOTAL
FROM gen_led_voucher_row_tab a
Where ACCOUNTING_YEAR like '2014'
And Not Exists
(
Select 1
From gen_led_voucher_row_tab b
Where voucher_date >= '01-JUN-09'
and voucher_date < '01-JUN-14'
and (credit_amount > '1' or debet_amount > '1')
And a.Text = b.Text
)
GROUP BY CODE_D
ORDER BY TOTAL DESC

Can a IF Statement be used in a Pivot function?

I finally figured out how to obatin this through a pivot via some online articles. However I still have a two issue, the code posted below works fine and returns my results for the span of a year. Issue that i'm still encountering however is, theres a parmeter being sent into this sproc call 'DateType' and it can be 'M' or 'Y'. if it's 'M' I need it to follow the logic below. If its 'Y', need it to follow same logic but populate the 'YTD' field. I'm not sure how to integrate a 'IF' statement into the use of this Pivot, or if its even possible. Any help with this would be greatly appreicated.
The 2nd issue thats not represented in the code below, is currently the logic shows the results for a span of a year. However I also need to add next to the result field the rating field. Example: 'JAN_Result | Jan_Rating | Feb_Result | Feb_Rating...' Can two fields be pivoted like this?
UPDATED Current Logic:
'code'
Select EmployeeID
,Employee
,EmpGroupID
,PA
,EmpLevel
,ObjectiveName as Objective
,Objectiveid AS Objectiveid
,Weighting
,ReportingYear
,[1] as JAN_Result
,[2] as FEB_Result
,[3] as MAR_Result
,[4] as APR_Result
,[5] as MAY_Result
,[6] as JUN_Result
,[7] as JUL_Result
,[8] as AUG_Result
,[9] as SEP_Result
,[10] as OCT_Result
,[11] as NOV_Result
,[12] as DEC_Result
,[13] as YTD
From
(
Select
EmployeeID
,Employee
,EmpGroupID
,PA
,EmpLevel
,ObjectiveName
,Objectiveid
,Weighting
,ReportingYear
,Result
,Rating
,Max(CASE WHEN r.datetype = 'M' THEN Month(startdate) WHEN r.datetype = 'Y' THEN 13 END) as StartMonth
From #tblResults R
INNER JOIN #Emphist h
ON r.Empgroupid = h.Groupid
LEFT OUTER JOIN Config.tblRatingDescription rt
ON r.Rating = rt.RatingID
LEFT OUTER JOIN Config.tblRatingDescription rtovr
ON r.RatingOverride = rtovr.RatingID
WHERE r.datetype IN ('M','Y')
and r.startdate BETWEEN '2012-01-01' AND '2012-04-01'
Group By
EmployeeID,
Employee,
EmpGroupID,
PA,
EmpLevel,
ObjectiveName,
Objectiveid,
ReportingYear,
Weighting,
h.sortorder,
Result,
Rating
)ps
PIVOT
(
max(result)
FOR StartMonth IN([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13])
) as pvt
'code'
Example Data:
EmployeeID Employee EmpGroupID PA EmpLevel Objective Jan_Result Feb_Result
1010101 TestUser 111 NE CustService Equip_Res 94.44 9.92
Your statement is very big. I will not repeat it. Basically, all you need to do is to replace this line:
,Month(startdate) as StartMonth
with a:
,CASE WHEN r.datetype = 'M' THEN Month(startdate) ELSE 13 END as StartMonth
If other values come on board, you can just continue the statement:
,CASE WHEN r.datetype = 'M' THEN Month(startdate) WHEN r.datetype = 'Q' THEN 14 ELSE 13 END as StartMonth