Group By Operator Not Behaving as Expected - sql

I have this query:
SELECT groupname,
Result = CASE
WHEN ( thd_requesttype_dca_oms_form IS NULL
OR thd_requesttype_dca_oms_form = '' ) THEN
thd_requesttypeidmform
ELSE thd_requesttype_dca_oms_form
END
FROM zendeskticketexport
WHERE (groupname = 'DC Maintenance')
AND thd_requesttype_dca_oms_form = 'attribute_update_requests__discontinue___obsolete_request'
GROUP BY groupname,
thd_requesttype_dca_oms_form,
thd_requesttypeidmform
ORDER BY groupname
The result I am receiving:
groupname Result
DC Maintenance attribute_update_requests__discontinue___obsolete_request
DC Maintenance attribute_update_requests__discontinue___obsolete_request
DC Maintenance attribute_update_requests__discontinue___obsolete_request
What's throwing me off is the result; I believe the group by operator should group identical records together, but something with the group by operator in conjuction with the case operator is causing these records not to group. In testing the two cases, I see the following query is returning 0 records:
select * from ZendeskTicketExport
where groupName = 'DC Maintenance' and thd_requesttypeidmform = 'attribute_update_requests__discontinue___obsolete_request'
In my mind this would indicate that all of the records should group together, since the case operator is only returning values for the thd_requesttype_dca_oms_form field. Thanks in advance.

You're grouping by a third column. SQL Server will create your groups, even if that column itself isn't in the SELECT.
Try this instead:
SELECT groupname,
CASE
WHEN (thd_requesttype_dca_oms_form IS NULL OR
thd_requesttype_dca_oms_form = '' ) THEN thd_requesttypeidmform
ELSE thd_requesttype_dca_oms_form
END
FROM zendeskticketexport
WHERE
groupname = 'DC Maintenance' AND
thd_requesttype_dca_oms_form = 'attribute_update_requests__discontinue___obsolete_request'
GROUP BY groupname,
thd_requesttype_dca_oms_form,
CASE
WHEN (thd_requesttype_dca_oms_form IS NULL OR
thd_requesttype_dca_oms_form = '' ) THEN thd_requesttypeidmform
ELSE thd_requesttype_dca_oms_form
END
ORDER BY groupname

Related

Group by query with rollup

I'm trying to make a query that shows me every region and then make a count to see how mano contracts I have per region, but somehow I'm getting an error on ROLLUP (BO2.area)
This is the query
SELECT
CASE WHEN BO2.area IS NULL THEN ISNULL(BO2.area, 'TOTAL') ELSE BO2.area END Area,
COUNT(BO.status = 'INSTALLED') Contracts
FROM
BO2
JOIN BO ON BO.bostamp = BO2.bo2stamp
GROUP BY
ROLLUP (BO2.area)
Should use GROUPING instead of a null check, and inside the aggregate you need a CASE expression. So:
SELECT
CASE WHEN GROUPING(BO2.area)=1 THEN 'TOTAL' ELSE BO2.area END Area,
SUM( CASE WHEN BO.status = 'INSTALLED' THEN 1 ELSE 0 END ) Contracts
FROM
BO2
JOIN BO ON BO.bostamp = BO2.bo2stamp
GROUP BY
ROLLUP (BO2.area)
your query fails because Area is number (I'm guessing) and you want to combine it to text , so you need to cast it to string:
SELECT
CASE WHEN GROUPING(BO2.area)=1 THEN (cast(BO2.area as varchar(100)),'TOTAL') ELSE BO2.area END as Area
, COUNT(CASE WHEN BO.status = 'INSTALLED' THEN 1 ELSE 0 END ) Contracts
FROM
BO2
JOIN BO ON BO.bostamp = BO2.bo2stamp
GROUP BY
ROLLUP (BO2.area)

How to return 'blank' using Sum function in Sql, if Sum is resulting 0 in SQL

I am using Sql Server 2008. I am adding some column value using Sum function. Like the code below:
SELECT 'RCOAuthorizer LMS',
'' AS Consumer_Loan,
'' AS Auto_Loan,
'' AS Credit_Card,
SUM(CASE
WHEN sq2.loan_type = 'Loan Amendment' THEN sq2.user_count
ELSE ''
END ) AS Loan_Amendment,
SUM(CASE
WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count
ELSE ''
END ) AS Pre_Payment,
SUM(CASE
WHEN sq2.loan_type = 'Corporate Credit card' THEN sq2.user_count
ELSE ''
END ) AS Corporate_Credit_card,
'' AS Auto_Payment_Release,
'' AS Car_Mulkiya
FROM
( SELECT 'RCOAuthorizer' AS ws_name,
'Loan Amendment' AS loan_type,
COUNT (DISTINCT a.bpm_referenceno) AS user_count,
a.user_id AS user_id
FROM BM_LMS_DecisionHistoryGrid a
INNER JOIN
( SELECT m.bpm_referenceno
FROM BM_LMS_EXTTABLE m
WHERE m.request_type = 'Loan Amendment' ) sq1 ON a.bpm_referenceno = sq1.bpm_referenceno
WHERE workstep_name = 'RCOAuthorizer'
GROUP BY a.user_id
UNION SELECT 'RCOAuthorizer',
'Pre-Payment',
COUNT (DISTINCT a.bpm_referenceno), a.user_id
FROM BM_LMS_DecisionHistoryGrid a
INNER JOIN
( SELECT m.bpm_referenceno
FROM BM_LMS_EXTTABLE m
WHERE m.request_type = 'Pre-Payment' ) sq1 ON a.bpm_referenceno = sq1.bpm_referenceno
WHERE workstep_name = 'RCOAuthorizer'
GROUP BY a.user_id
UNION SELECT 'RCOAuthorizer',
'Corporate Credit card',
COUNT (DISTINCT a.bpm_referenceno), a.user_id
FROM BM_LMS_DecisionHistoryGrid a
INNER JOIN
( SELECT m.bpm_referenceno
FROM BM_LMS_EXTTABLE m
WHERE m.request_type = 'Corporate Credit card' ) sq1 ON a.bpm_referenceno = sq1.bpm_referenceno
WHERE workstep_name = 'RCOAuthorizer'
GROUP BY a.user_id ) sq2
GROUP BY sq2.ws_name
The above query will return Sum of all the numbers available in 'a' column. But in case, there is no record, then it will return '0' as result.
I require that if there is no record, it must show blank instead of showing '0'. How to handle the same.
To start, you don't need an ISNULL with a back value of 0 (the neutral for adding) inside a SUM aggregate, as the SUM already ignores NULL values. So SUM(ISNULL(Column, 0)) is equal to SUM(Column) (but different from ISNULL(SUM(Column), 0)!).
Seems that you want a VARCHAR result instead of a numeric one. You can solve this with a CASE.
Select
CASE WHEN Sum(a) = 0 THEN '' ELSE CONVERT(VARCHAR(100), Sum(a)) END
from
table;
If you don't want to repeat the SUM expression:
;WITH SumResult AS
(
Select CONVERT(VARCHAR(100), Sum(a)) AS SumTotal
from table
)
SELECT
CASE WHEN R.SumTotal = '0' THEN '' ELSE R.SumTotal END
FROM
SumResult AS R
Keep in mind that in these both cases, if there is no record to calculate the sum from, the result will be NULL.
EDIT: There is no point in adding '' inside your SUM, as it's converted to 0 to be able to sum. The solution is still the same as I posted before.
Change
SUM(CASE
WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count
ELSE ''
END ) AS Pre_Payment,
for
CASE
WHEN SUM(CASE WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count END) = 0 THEN ''
ELSE CONVERT(VARCHAR(100), SUM(CASE WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count)) END AS Pre_Payment,
Just try this ( use isnull again ):
Select isnull(Sum(isnull(a,0)),0) from table_;
I used table_ instead of table, because table is a reserved keyword.
SQL Fiddle Demo

How to sort data in stored procedure with column positions of select statement with CASE

This is not working
ORDER BY
CASE
WHEN #OrderBy = 'EndDateInDays' AND #OrderByDirection = 'D'
THEN 10
END DESC,
CASE
WHEN #OrderBy = 'EndDateInDays' AND #OrderByDirection != 'D'
THEN 10
END
Where this one is working
ORDER BY 10 DESC
As per documentation,
ORDER BY order_by_expression
order_by_expression Specifies a column or expression on which to sort
the query result set. A sort column can be specified as a name or
column alias, or a nonnegative integer representing the position of
the column in the select list.
Source: SELECT - ORDER BY Clause (Transact-SQL)
You are specifying an expression, hence the SQL Server does not sort by value in column #10. Instead it sorts your rows by a constant value '10', which results in no sort being performed.
Suggested solution
Move all complex columns into a CROSS APPLY sub-query and add another CROSS APPLY with a sorting column:
SELECT F.Id
,cols.Favourite
,F.Agent
,F.Name
,cols.DatePublished
,UF.ToolTip
,F.CreationDate
FROM MyTable F
INNER JOIN MyTable2 UF
ON f.Id = UF.Id
CROSS APPLY (
SELECT (CASE WHEN UFF.[Id] IS NULL THEN CONVERT(BIT, 0) ELSE CONVERT(BIT, 1) END) AS Favourite
,CONVERT(Datetime, F.[Date] , 103) AS DatePublished
) cols
CROSS APPLY (
SELECT -- Make sure to correctly cast all numeric and date values to text
CASE WHEN #OrderBy = 'EndDateInDays' THEN CONVERT(VARCHAR(100), F.[EndDateDate], 126)
WHEN #OrderBy = 'Name' THEN F.Name
WHEN #OrderBy = 'DatePublished' THEN cols.DatePublished
ELSE CONVERT(VARCHAR(100), F.Id) -- This is default sort
END AS [SortCol]
) sort
ORDER BY
CASE WHEN #OrderByDirection = 'D' THEN sort.[SortCol] END DESC
,CASE WHEN #OrderByDirection != 'D' THEN sort.[SortCol] END
;
You can use the column alias. Let's say it is EndDateInDays:
ORDER BY (CASE WHEN #OrderBy = 'EndDateInDays' AND #OrderByDirection = 'D'
THEN EndDateInDays
END) DESC,
(CASE WHEN #OrderBy = 'EndDateInDays' AND #OrderByDirection <> 'D'
THEN EndDateInDays
END)
If EndDateInDays is a number (as suggested by the name), you could do:
ORDER BY (CASE WHEN #OrderBy = 'EndDateInDays' AND #OrderByDirection = 'D'
THEN - EndDateInDays
WHEN #OrderBy = 'EndDateInDays' AND #OrderByDirection <> 'D'
THEN EndDateInDays
END)
Also, be careful if you start combining multiple columns. It is better to have a separate CASE expression for each column to prevent inadvertent type mismatching.

SQL - Distinct with Case When

When i use the following query it returns duplicate External IDs as it lists the different cases as different rows.
SELECT DISTINCT
OENT.OTHER_EXTERNAL_ID AS 'Agent Master Number'
,CASE WHEN SE.Organization_Name IS NULL OR RTRIM(LTRIM(SE.ORGANIZATION_NAME)) = '' THEN '' ELSE SE.ORGANIZATION_NAME END AS 'Agent'
GROUP BY
OENT.OTHER_EXTERNAL_ID
,CASE WHEN SE.Organization_Name IS NULL OR RTRIM(LTRIM(SE.ORGANIZATION_NAME)) = '' THEN '' ELSE SE.ORGANIZATION_NAME END
Where do i use the distinct properly so it lists the case as one row no matter what case it satisfies?
Thanks
Problem is that it keep returning
AGENT_NUMBER AGENT
MA12348677 DREHWING, DOUGLAS
MA12348677 DREHWING, DOUGLAS A
Where i want this to be one row as they have the same AGENT_NUMBER
select distinct
OENT.OTHER_EXTERNAL_ID AS AGENT_NUMBER,
CASE
WHEN SE.Organization_Name IS NULL OR RTRIM(LTRIM(SE.ORGANIZATION_NAME)) = '' THEN ''
ELSE upper( SE.ORGANIZATION_NAME )
END AS AGENT
FROM SomeTableName
order by AGENT_NUMBER
It will still return duplicates in case if Agent number differs. If you want to find duplicated names then
select AGENT, count (AGENT_NUMBER) from (
select OENT.OTHER_EXTERNAL_ID AS AGENT_NUMBER,
CASE
WHEN SE.Organization_Name IS NULL OR RTRIM(LTRIM(SE.ORGANIZATION_NAME)) = '' THEN ''
ELSE upper( SE.ORGANIZATION_NAME )
END AS AGENT
FROM SomeTableName
)
group by AGENT
HAVING count (AGENT_NUMBER) >1
order by AGENT
To find duplicate names for same Agent number:
select AGENT_NUMBER, count (AGENT) from (
select OENT.OTHER_EXTERNAL_ID AS AGENT_NUMBER,
CASE
WHEN SE.Organization_Name IS NULL OR RTRIM(LTRIM(SE.ORGANIZATION_NAME)) = '' THEN ''
ELSE upper( SE.ORGANIZATION_NAME )
END AS AGENT
FROM SomeTableName
)
group by AGENT_NUMBER
HAVING count (AGENT) >1
order by AGENT_NUMBER

how to use case statement in group by

I have following case statements in my SELECT clause, also I
have a group by clause...
So, Is it okay to specify UF.CONT_PID & UF.M_STATUS_CD in my
GROUP BY Clause ? I need to specify the entire CASE statement
in GROUP BY ?
CASE WHEN UF.CONT_PID IN
('04007005', '01019045','01019046') OR
(UF.M_STATUS_CD IN ('01', '02')
THEN
1
ELSE
0
END
Rather than repeat the expression, you could do:
SELECT col /*, other cols */ FROM
(
SELECT col = CASE WHEN /*...long-winded expression...*/
THEN 1 ELSE 0 END /*, other cols */
FROM dbo.table
) AS x
GROUP BY col;
I believe you can group by in two ways:
GROUP BY UF.CONT_PID, UF.M_STATUS_CD
OR
GROUP BY CASE WHEN UF.CONT_PID IN ('04007005', '01019045','01019046') OR (UF.M_STATUS_CD IN ('01', '02') THEN 1 ELSE 0 END
But keep in mind that these are very different groupings.