I am using SQL Server 2012.
Here is my query, I want the ordering in this order and not alphabetical.
Here is the order I want them in :
Foreign,
Out of State,
Texas,
Unknown,
Total Enrollment
I used order by cases, but I am getting an error:
Incorrect syntax near '5'
How do I fix it?
Query :
declare #Term int = 20172;
select
[Category], [Last_Term], [Current_Term], [#Change], [%Change]
from
(select
[Category],
cast(round(((cast(y.Last_Term as float)) * 1), 2) as varchar(10)) as 'Last_Term',
cast(round(((cast(y.Current_Term as float)) * 1), 2) as varchar(10)) as 'Current_Term',
cast(round(((cast(y.Current_Term as float) -
cast(y.Last_Term as float)) * 1), 2) as varchar(10)) as '#Change',
cast(round((((cast(y.Current_Term as float) -
cast(y.Last_Term as float)) /
(cast(y.Last_Term as float))) * 100), 2) as varchar(10)) + '%' as '%Change'
from
(select
Category,
Case
when year = substring(CAST (#Term- 10 as Varchar(10)),1,4)
then 'Current_Term'
when year = substring(CAST (#Term - 20 as Varchar(10)),1,4)
then 'Last_Term'
End As ACAD_YEAR,
a.enroll
from
(select
case
when dh.HOME = 'F'
then 'Foreign'
when dh.HOME = 'O'
then 'Out of State'
when dh.Home = 'I'
then 'texas'
when dh.Home = 'U'
then 'UnKnown'
end as Category,
(CONVERT(INT, SUBSTRING(ACADEMIC_PERIOD, 1, 4))) - 1 as year,
count(*) as enroll
from
[IR_DW].[dbo].[dw_enrollment_F] d
inner join
dim_Time t on d.TIME_KEY = t.TIME_KEY
inner join
dim_Home dh on d.HOME_KEY = dh.HOME_KEY
inner join
dim_Student_Level sl on d.STUDENT_LEVEL_KEY = sl.STUDENT_LEVEL_KEY
where
ACADEMIC_PERIOD_ALL = #Term - 10
or ACADEMIC_PERIOD_ALL = #Term
group by
dh.HOME, (CONVERT(INT,SUBSTRING(ACADEMIC_PERIOD,1,4))) - 1) a
) src
PIVOT
(SUM(Enroll) FOR ACAD_YEAR in ([Current_Term] , [Last_Term])) y
) a
order by
case
when a.[Category] = 'Foreign' then 1
when a.[Category] = 'Out of State' then 2
when a.[Category] = 'Texas' then 3
when a.[Category] = 'Unknown' then 4
You are missing and END though you are missing the 5 case as well...
when a.[Category] = 'Total Enrollment' then 5
ORDER BY
case when a.[Category] = 'Foreign' then 1
when a.[Category] = 'Out of State' then 2
when a.[Category] = 'Texas' then 3
when a.[Category] = 'Unknown' then 4
when a.[Category] = 'Total Enrollment' then 5 --added this
else 6 --catch all to make anything that fell outside of these categories unsorted afterwards
end --added here
Related
I am trying to add a case expression in my query but it is inside of a select from statement. SQL Server returns multiple errors when I try to execute it.
UNION all
SELECT 'Min WA APR for Canada MPL Receivables' AS [Text], ISNULL([Value],0.0) AS [Value], 'percent' AS [ValueType], [Limit], CASE WHEN [Excess] > 0 THEN 0 ELSE ABS(ISNULL([Excess],0.0)) END AS [Excess]
FROM (
--SELECT [part1]/[part2] AS [Value], [Limit], ([part1] - [Limit]*[part2])/(49.00 - [Limit]) AS [Excess]
SELECT [part1]/[part2] AS [Value], [Limit], ([part1] - [Limit]*[part2])/100.0 AS [Excess]
FROM (
CASE isLPP WHEN 1 THEN
SELECT SUM(RateLPP * OutstandingPrincipal * FAEligibility)
ELSE
SELECT SUM(APR * OutstandingPrincipal * FAEligibility)
END AS [part1]
FROM [dfc_BorrowingBaseRecords] WITH (NOLOCK)
WHERE FAEligibility = 1
AND Region = 'Canada'
AND LoanType = 'MPL'
) first
, (
SELECT 44.90 AS [Limit], SUM(OutstandingPrincipal * FAEligibility) AS [part2]
FROM [dfc_BorrowingBaseRecords] WITH (NOLOCK)
WHERE FAEligibility = 1
AND Region = 'Canada'
AND LoanType = 'MPL'
) second
) third
I need to do one calculation if a flag is set and another if it is not.
I think the following is what you are looking for.
The key point is to use the case expression inside the sum to conditionally determine what value you are summing.
SELECT 'Min WA APR for Canada MPL Receivables' AS [Text], ISNULL([Value],0.0) AS [Value]
, 'percent' AS [ValueType], [Limit]
, CASE WHEN [Excess] > 0 THEN 0 ELSE ABS(ISNULL([Excess],0.0)) END AS [Excess]
FROM (
SELECT [part1]/[part2] AS [Value], [Limit], ([part1] - [Limit]*[part2])/100.0 AS [Excess]
FROM (
SELECT 44.90 AS [Limit]
, SUM(CASE isLPP WHEN 1 THEN RateLPP ELSE APR END * OutstandingPrincipal * FAEligibility) [part1]
, SUM(OutstandingPrincipal * FAEligibility) [part2]
FROM [dfc_BorrowingBaseRecords]
WHERE FAEligibility = 1
AND Region = 'Canada'
AND LoanType = 'MPL'
) X
) Y
I have a query as below:
SELECT activity_code,
activity_name,
Count(*)
Total_Response,
yearnumber,
Cast(Avg(Cast(Isnull([response], 0) AS NUMERIC)) AS DECIMAL(10, 2))
[Ratings]
FROM (SELECT code [Activity_Code],
activityname [Activity_Name],
enddt.yearnumber,
CASE
WHEN Isnumeric(asmt.userresponse) = 1 THEN asmt.userresponse
ELSE 0
END [Response]
FROM (SELECT userid,
questionid,
activityid,
attemptenddateid,
CASE
WHEN Isnumeric(userresponse) = 1 THEN userresponse
ELSE '0'
END AS UserResponse
FROM factassessment) asmt
INNER JOIN dimuser usr
ON usr.id = asmt.userid
INNER JOIN (SELECT
id,
Cast(questionidentifier AS VARCHAR(1000)) AS
QuestionIdentifier
FROM dimquestion) ques
ON ques.id = asmt.questionid
INNER JOIN dimactivity act
ON act.id = asmt.activityid
INNER JOIN dimdate enddt
ON enddt.dateid = asmt.attemptenddateid
WHERE ( act.code LIKE 'U-%'
OR act.code LIKE 'CC-%' )
AND usr.empcntry <> 'administrator'
AND enddt.yearnumber IN ( 2015, 2016, 2017, 2018,
2019, 2020, 2021, 2021, 2022 )
AND ques.questionidentifier = 'course_content'
AND asmt.userresponse NOT IN ( '0', '-1' )) tab
GROUP BY activity_code,
activity_name,
yearnumber
ORDER BY activity_code
On executing the above code, I am getting the below error:
[SQLServer]Conversion failed when converting the varchar value '.' to
data type int.
I tried fixing it as below, but still getting the same error:
SELECT activity_code,
activity_name,
Count(*)
Total_Response,
yearnumber,
Cast(Avg(Cast(Isnull([response], 0) AS NUMERIC)) AS DECIMAL(10, 2))
[Ratings]
FROM (SELECT code [Activity_Code],
activityname [Activity_Name],
enddt.yearnumber,
CASE
WHEN Isnumeric(asmt.userresponse + 'e0') = 1 THEN
asmt.userresponse
ELSE 0
END [Response]
FROM (SELECT userid,
questionid,
activityid,
attemptenddateid,
CASE
WHEN Isnumeric(userresponse + 'e0') = 1 THEN
userresponse
ELSE '0'
END AS UserResponse
FROM factassessment) asmt
INNER JOIN dimuser usr
ON usr.id = asmt.userid
INNER JOIN (SELECT
id,
Cast(questionidentifier AS VARCHAR(1000)) AS
QuestionIdentifier
FROM dimquestion) ques
ON ques.id = asmt.questionid
INNER JOIN dimactivity act
ON act.id = asmt.activityid
INNER JOIN dimdate enddt
ON enddt.dateid = asmt.attemptenddateid
WHERE ( act.code LIKE 'U-%'
OR act.code LIKE 'CC-%' )
AND usr.empcntry <> 'administrator'
AND enddt.yearnumber IN ( 2015, 2016, 2017, 2018,
2019, 2020, 2021, 2021, 2022 )
AND ques.questionidentifier = 'course_content'
AND asmt.userresponse NOT IN ( '0', '-1' )) tab
GROUP BY activity_code,
activity_name,
yearnumber
ORDER BY activity_code
I am still getting the same error. Help to resolve this conversion error.
If I understand this question correctly, the reason for this error can be simplified to the following statement, which returns Conversion failed when converting the varchar value '.' to data type int. error:
SELECT CASE WHEN ISNUMERIC(asmt.UserResponse) = 1 THEN asmt.UserResponse else 0 END [Response]
FROM (
SELECT CASE WHEN ISNUMERIC('.') = 1 THEN '.' ELSE '0' END AS UserResponse
) asmt
It's good to consider the following:
The result from ISNUMERIC('.') is 1 and the result from the inner CASE is the text .. But, the outer CASE fails, because the return type from the CASE statement is the highest precedence type from the set of types in result expressions, so in this case . is implicitly converted to int.
Do not trust the ISNUMERIC() function. Use TRY_CONVERT() instead
You may try to use the next approach to solve this error:
SELECT
CASE
WHEN TRY_CONVERT(int, asmt.UserResponse) IS NOT NULL THEN TRY_CONVERT(int, asmt.UserResponse)
ELSE 0
END [Response]
FROM (
SELECT
CASE
WHEN TRY_CONVERT(int, '.') IS NOT NULL THEN TRY_CONVERT(int, '.')
ELSE 0
END AS UserResponse
) asmt
i have a query like this:
SELECT
MIN(F_Exhibition_Name) AS F_Site_name,
(SELECT
SUM(F_Quantity)
FROM T_assets
WHERE T_assets.F_ref_code = T_Item_movement.ItemCode
AND F_State = 'A')
AS openingqty,
CASE
WHEN dbo.T_Item_Movement.F_Status = 1 AND
dbo.T_Item_Movement.F_Site_Code <> dbo.T_Item_Movement.F_Frm_Site_Code THEN SUM(dbo.T_Item_Movement.F_Quantity)
ELSE 0
END,
CASE
WHEN dbo.T_Item_Movement.F_Status = 2 AND
dbo.T_Item_Movement.F_Site_Code <> dbo.T_Item_Movement.F_Frm_Site_Code THEN SUM(dbo.T_Item_Movement.F_Quantity)
ELSE 0
END
FROM T_Item_movement
LEFT OUTER JOIN T_L2Category
ON T_L2Category.F_ItemCode = T_Item_movement.ItemCode
LEFT OUTER JOIN T_Exhibition
ON T_Exhibition.F_Exhibition_Code = T_Item_movement.F_Site_Code
WHERE F_Cat_code = 'FN'
--AND F_Cat_code IN ('EC', 'EL', 'FL', 'FN', 'GR', 'MX', 'OT', 'SH')
AND F_L1Cat_code = 'TT'
AND itemcode = 'TT015-BLK'
AND CONVERT(varchar(10), F_datetime, 112) >= '20130915'
AND CONVERT(varchar(10), F_datetime, 112) <= '20150915'
AND F_Exhibition_Name IS NOT NULL
GROUP BY ItemCode,
dbo.T_Item_Movement.F_Status,
dbo.T_Item_Movement.F_Site_Code,
dbo.T_Item_Movement.F_Frm_Site_Code
i am getting out put like this:
I am getting gulf glass 2015 in two column. I want to get in column and show the result in same column only.
Expected output :
Gulf class 2015 6 5
ATM 2015 0 3
It's the GROUP BY columns that are causing it.
You could change your CASE Statement to SUM the result, and therefore remove some of the columns in the GROUP BY:
...
SUM(CASE WHEN dbo.T_Item_Movement.F_Status = 1 AND ...
THEN dbo.T_Item_Movement.F_Quantity
ELSE 0
END),
...
GROUP BY ItemCode
SELECT F_Site_name, openingqty,
SUM(col1) AS col1, SUM(col2) AS col2
FROM
(
SELECT
MIN(F_Exhibition_Name) AS F_Site_name,
(SELECT
SUM(F_Quantity)
FROM T_assets
WHERE T_assets.F_ref_code = T_Item_movement.ItemCode
AND F_State = 'A')
AS openingqty,
CASE
WHEN dbo.T_Item_Movement.F_Status = 1 AND
dbo.T_Item_Movement.F_Site_Code <> dbo.T_Item_Movement.F_Frm_Site_Code THEN SUM(dbo.T_Item_Movement.F_Quantity)
ELSE 0
END AS col1,
CASE
WHEN dbo.T_Item_Movement.F_Status = 2 AND
dbo.T_Item_Movement.F_Site_Code <> dbo.T_Item_Movement.F_Frm_Site_Code THEN SUM(dbo.T_Item_Movement.F_Quantity)
ELSE 0
END AS col2
FROM T_Item_movement
LEFT OUTER JOIN T_L2Category
ON T_L2Category.F_ItemCode = T_Item_movement.ItemCode
LEFT OUTER JOIN T_Exhibition
ON T_Exhibition.F_Exhibition_Code = T_Item_movement.F_Site_Code
WHERE F_Cat_code = 'FN'
--AND F_Cat_code IN ('EC', 'EL', 'FL', 'FN', 'GR', 'MX', 'OT', 'SH')
AND F_L1Cat_code = 'TT'
AND itemcode = 'TT015-BLK'
AND CONVERT(varchar(10), F_datetime, 112) >= '20130915'
AND CONVERT(varchar(10), F_datetime, 112) <= '20150915'
AND F_Exhibition_Name IS NOT NULL
GROUP BY ItemCode,
dbo.T_Item_Movement.F_Status,
dbo.T_Item_Movement.F_Site_Code,
dbo.T_Item_Movement.F_Frm_Site_Code
) AS t
GROUP BY F_Site_name, openingqty
I'm trying to do a calculation on a what-if basis, so I assumed I could've done this using the case when function. Such as:
SELECT
TRIM(EXTRACT(YEAR FROM business_date))||'Q'||TRIM((EXTRACT(MONTH FROM business_date)+2)/3) as year_qtr,
case when orr_txt = '1' then (sum(cast (rr9m as float)) / (sum(cast (total_observations as float)) - 0.5*sum(cast (lft as float)) )) end as DR_1,
case when orr_txt = '2' then (sum(cast (rr9m as float)) / (sum(cast (total_observations as float)) - 0.5*sum(cast (lft as float)) )) end as DR_2,
case when orr_txt = '3' then (sum(cast (rr9m as float)) / (sum(cast (total_observations as float)) - 0.5*sum(cast (lft as float)) )) end as DR_3,
avg(cast (dp as float)) as Pred_PD
FROM
raroc.pd_matrixRR a,
raroc.ccc_dp_sc b,
raroc.ratings_convert c
WHERE
start_orr_code in (1)
and case when a.scorecard_group = 'BB' then 'Business Banking' else a.scorecard_group end= b.rating_sys
and a.orr_txt = b.bacrr
and a.orr_txt = c.bacrr_text
and orr_txt not in ('9-', '10', '11', '12', 'NR')
and rating_sys_grp = 'Scorecard'
--and a.orr_txt = '1'
--and scorecard_group = 'Large Corporation'
--and scorecard_group = 'Large Corporation_FI'
--and scorecard_group = 'Middle Market'
--and scorecard_group = 'BB'
--and scorecard_group = 'GCSBB'
--and scorecard_group = 'Real Estate'
and scorecard_group = 'Individuals'
and scorecard_group not like 'Sove%'
and scorecard_group not like 'Lega%'
--and year_qtr < '2014Q2'
group by 1,2,3,4
ORDER BY 2,1
It apparently didn't compile and laughed at my logic. However, I'll get an error 3604 if I don't group it. The question is, how would I get about this in order to calculate the rate for category 1, 2, and 3.
Much appreciated!
SP
You need to move the CASE inside the aggregate function like this:
(sum(case when orr_txt = '1' then cast (rr9m as float) end)
/ (sum(case when orr_txt = '1' then cast (total_observations as float) end)
- 0.5*sum(case when orr_txt = '1' then cast (lft end as float) end ) )) end as DR_1,
I think you just want conditional aggregation. The conditions go inside the aggregation functions. I think this is the expression that you want (repeated 3 times of course for each value:
SELECT . . .
(sum(case when orr_txt = '1' then cast(rr9m as float) end) /
sum(case when orr_txt = '1' then cast(total_observations as float) end) -
0.5 * sum(case when orr_txt = '1' then cast(lft as float) end)
) as DR_1, . . .
You can then change the GROUP BY to GROUP BY 1.
You have to group by
group by
TRIM(EXTRACT(YEAR FROM business_date))||'Q'||TRIM((EXTRACT(MONTH FROM business_date)+2)/3)
, orr_txt
A workmate has given me this stored procedure and asked for help to create an sql INSERT statement based on its results, but am a little confused to some of the methods. For example, I've never seen a CASE statement in sql. I looked it up but the useage is different from what I was given.
Here is the stored procedure
if #ScheduleType Is Null
SELECT Lu_Schedule_Types.ScheduleType,
SUM(CASE WHEN InductionProduction = 1 THEN CASE WHEN (LEFT(DATENAME(Month,
3)) = 'JAN' THEN ItemQty END END) AS I01,
SUM(CASE WHEN InductionProduction = 1 THEN CASE WHEN (LEFT(DATENAME(Month,
Item_Schedule.ItemScheduleDate), 3))
= 'FEB' THEN ItemQty END END) AS I02,
SUM(CASE WHEN InductionProduction = 2 THEN ItemQty ELSE 0 END) AS PRD,
LmpProjectInfo.PlannedQty,
LmpProjectInfo.AuthorizedQty,
LmpProjectInfo.WbsElementID
FROM Item_Schedule
INNER JOIN Lu_Schedule_Types
ON Item_Schedule.ItemScheduleType = Lu_Schedule_Types.ScheduleTypeId
RIGHT OUTER JOIN LmpProjectInfo
ON Item_Schedule.ItemWbsElement = LmpProjectInfo.WbsElementID
WHERE
(Item_Schedule.IsActive = 1)
AND (Item_Schedule.ItemWbsElement = #WbsElement)
AND (Item_Schedule.ItemScheduleDate < DATEADD(d, 1, #EndDate)) AND
(Item_Schedule.ItemScheduleDate >= #StartDate)
GROUP BY Lu_Schedule_Types.ScheduleType
, Lu_Schedule_Types.ScheduleTypeId
, LmpProjectInfo.PlannedQty
, LmpProjectInfo.AuthorizedQty
, LmpProjectInfo.WbsElementID
ORDER BY Lu_Schedule_Types.ScheduleTypeId
I am supposed to be helping him out but I'm by far a database wizard, and am a little out of my depth here. I'd really appreciate the help/advice/direction.
Thanks much!
This is quick sample that might work for you. This assumes that the table you want to insert data into takes all of the values return from the SELECT statement and that they are of the same type.
As a side note, the reason you might have got a bit confused about the CASE statements is possibly due to the fact there are two main ways to use them in SQL. CASE WHEN... like you have here and CASE #value# WHEN #result# THEN.... A little more searching on the web will lead you to some nice examples. For example this one.
INSERT INTO TABLE_NAME
(
ScheduleType,
I01,
I02,
PRD,
PlannedQty,
AuthorizedQty,
WbsElementID
)
SELECT
Lu_Schedule_Types.ScheduleType,
SUM(CASE WHEN InductionProduction = 1 THEN CASE WHEN (LEFT(DATENAME(Month,
3)) = 'JAN' THEN ItemQty END END) AS I01,
SUM(CASE WHEN InductionProduction = 1 THEN CASE WHEN (LEFT(DATENAME(Month, Item_Schedule.ItemScheduleDate), 3))
= 'FEB' THEN ItemQty END END) AS I02,
SUM(CASE WHEN InductionProduction = 2 THEN ItemQty ELSE 0 END) AS PRD,
LmpProjectInfo.PlannedQty,
LmpProjectInfo.AuthorizedQty,
LmpProjectInfo.WbsElementID
FROM
Item_Schedule INNER JOIN
Lu_Schedule_Types ON Item_Schedule.ItemScheduleType = Lu_Schedule_Types.ScheduleTypeId RIGHT OUTER JOIN
LmpProjectInfo ON Item_Schedule.ItemWbsElement = LmpProjectInfo.WbsElementID
WHERE
(Item_Schedule.IsActive = 1) AND (Item_Schedule.ItemWbsElement = #WbsElement) AND
(Item_Schedule.ItemScheduleDate < DATEADD(d, 1, #EndDate)) AND
(Item_Schedule.ItemScheduleDate >= #StartDate)
GROUP BY Lu_Schedule_Types.ScheduleType, Lu_Schedule_Types.ScheduleTypeId,
LmpProjectInfo.PlannedQty, LmpProjectInfo.AuthorizedQty,
LmpProjectInfo.WbsElementID
ORDER BY Lu_Schedule_Types.ScheduleTypeId
Try this one -
INSERT INTO dbo.table1 -- insert in table
(
ScheduleType
, I01
, I02
, PRD
, PlannedQty
, AuthorizedQty
, WbsElementID
)
SELECT
t.ScheduleType
, I01 = SUM(CASE WHEN InductionProduction = 1 AND MONTH(s.ItemScheduleDate) = 1 THEN ItemQty END)
, I02 = SUM(CASE WHEN InductionProduction = 1 AND MONTH(s.ItemScheduleDate) = 2 THEN ItemQty END)
, PRD = SUM(CASE WHEN InductionProduction = 2 THEN ItemQty END)
, i.PlannedQty
, i.AuthorizedQty
, i.WbsElementID
--INTO #temp_table -- or insert in temp table
FROM dbo.Item_Schedule s
JOIN dbo.Lu_Schedule_Types t ON s.ItemScheduleType = t.ScheduleTypeId
RIGHT JOIN dbo.LmpProjectInfo i ON s.ItemWbsElement = i.WbsElementID
WHERE s.IsActive = 1
AND s.ItemWbsElement = #WbsElement
AND s.ItemScheduleDate < DATEADD(d, 1, #EndDate))
AND s.ItemScheduleDate >= #StartDate
GROUP BY
t.ScheduleType
, t.ScheduleTypeId
, i.PlannedQty
, i.AuthorizedQty
, i.WbsElementID
ORDER BY t.ScheduleTypeId