Return a 0 when no data present - ssms

I have looked at a few questions similar and tried to apply my own knowledge to get the query to work correctly but still cant get the outcome i desire.
I have 5 Call lines i need to report on from our DB. The problem is some of them can go a full day without a call. Instead of reporting 0, it just doesn't pull the line through. Unfortunately for Reporting purposes I need it to put 0.
SELECT CASE [Campaign]
WHEN '1' THEN 'Line A'
WHEN '2' THEN 'Line B'
WHEN '3' THEN 'Line C'
WHEN '4' THEN 'Line D'
WHEN '5' THEN 'Line E'
ELSE 'Outbound Dialling' END AS [Line_name],
COUNT(UniqueID) AS [Total Calls]
FROM Telephone_Table
WHERE [CallTime] BETWEEN '2017-12-01 00:00:00' AND '2017-12-01 23:59:59'
AND [Campaign] IN ('402','403','404','405','406')
Result:
Line_name | Campaign | Total Calls
Line A | 402 | 13
Line B | 403 | 11
Line C | 405 | 26
Line E | 406 | 178
Quite often Line D doesn't get a call. Instead of listing it as 0 it will miss it completely.
I have tried the following but none have worked:
COUNT(UniqueID)+1
CASE WHEN COUNT(UniqueID) = '0' THEN 1 ELSE COUNT(UniqueID)
I tried creating another table in the DB with just these lines and a name in there to join against instead of using a "Case When" in case that was the issue but that didn't work.
Any one have any suggestions? Thank you.

Here's a suggestion: add a dummy for each group you want displayed, then subtract 1 from the count:
SELECT CASE [Campaign]
WHEN '402' THEN 'Line A'
WHEN '403' THEN 'Line B'
WHEN '404' THEN 'Line C'
WHEN '405' THEN 'Line D'
WHEN '406' THEN 'Line E'
ELSE 'Outbound Dialling' END AS [Line_name]
,[Campaign]
,COUNT(UniqueID)-1 AS [Total Calls]
FROM
(SELECT [Campaign], [UniqueID] FROM Telephone_Table
WHERE [CallTime] BETWEEN '2017-12-01 00:00:00' AND '2017-12-01 23:59:59'
AND [Campaign] IN ('402','403','404','405','406')
UNION SELECT '402' AS [Campaign], 'DUMMY1' AS UniqueID
UNION SELECT '403' AS [Campaign], 'DUMMY2' AS UniqueID
UNION SELECT '404' AS [Campaign], 'DUMMY3' AS UniqueID
UNION SELECT '405' AS [Campaign], 'DUMMY4' AS UniqueID
UNION SELECT '406' AS [Campaign], 'DUMMY5' AS UniqueID) AS a
GROUP BY [Campaign]
I may have mixed up my syntax, I don't have sql-server handy at the moment to check, but this general idea should work.

Related

Having problem with putting values into ranges

I have the following statement
SELECT
CASE
WHEN response BETWEEN 0 AND 5 then '0 - 5'
WHEN response BETWEEN 6 AND 10 then '6 - 10'
else 'over 10'
end AS 'range',
COUNT(*) as 'count'
FROM((SELECT datediff(MIN(referral_interventions.dateOfintervention), referral.referralDate) as response
from referral
LEFT JOIN referral_interventions on referral.refid =referral_interventions.refID
LEFT JOIN interventions on referral_interventions.typeOfintervention = interventions.intid
WHERE referral.referralDate > '2021-11-01'
GROUP BY referral.refid)
AS tempdiff)
GROUP BY 'range';
The select statement within the first FROM works and produces 119 results with response ranging from 0 to 12.
The full statement produces all 119 showing as
range count
0 - 5 119
Any ideas wher my syntax etc might be wrong
Sorted
I changed ' to ` around range and count

How do I put a condition in the select statement in T-SQL

A carer can provide support to two different service at the same Start time and End time this is called 1:2 Service type. The unique ID for this type of shift type are generated as the same unique ID for this type of service. I want to add 2 at the end of the unique ID for every second service. How do I find this? Bare in mind I am using this within the UNION with other 3 select statement. The first query above the Union is the one
My query below:
SELECT DISTINCT
CASE
WHEN SHIFT_CODE = '1:2 Support'
THEN '3'
ELSE ''
END [Datatype Id],
CAST(SS.Schedule_Subshift_ID AS VARCHAR(20)) + ' 1:2' [Unique Visit ID]
'' [Date],
'' [Start Time],
''+ ',' [End Time],
''+ ',,,' [Unique Client ID],
'' [Client Forename]
FROM
Subshift
UNION
SELECT DISTINCT
CASE
WHEN CAST(CAST(EE.Start_Date_SK AS VARCHAR(255)) AS DATE) >= (GETDATE() - 41)
THEN ' 11 '
ELSE ''
END [DataTypeID],
'' [Unique Visit ID],
'' [Date],
'' [Start Time],
''+ ',' [End Time],
''+ ',,,' [Unique Client ID],
'' [Client Forename]
FROM
Subshift
Result I get is:
Service Unique Visit ID Carer Date Start Time End Time SHIFT_PROPERTY_CODE
Moira 211870 2 A 16/12/2019 19:00 22:00, 1:2 Support
Marta 211870 2 A 16/12/2019 19:00 22:00, 1:2 Support
Rebecca 211871 2 B 19/12/2019 19:00 22:00, 1:2 Support
Elsie 211871 2 B 19/12/2019 19:00 22:00, 1:2 Support
Desired Result should be:
Service Unique Visit ID Carer Date Start Time End Time SHIFT_PROPERTY_CODE
Moira 211870 A 16/12/2019 19:00 22:00, 1:2 Support
Marta 211870 2 A 16/12/2019 19:00 22:00, 1:2 Support
Rebecca 211871 B 19/12/2019 19:00 22:00, 1:2 Support
Elsie 211871 2 B 19/12/2019 19:00 22:00, 1:2 Support
You can try something along these lines:
SELECT
Case Row_Number() OVER (Partition By SS.Schedule_Subshift_ID Order By ClientName)
when 1 then S.Schedule_Subshift_ID
when 2 then S.Schedule_Subshift_ID + ' 2'
end
FROM Subshift
You can partition by service id and order by time for example, I don't exactly understand your case. Please keep in mind that the Query you copied DOES NOT result in the result sets below. So if you want me to be more specific - please provide the proper query.

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.

Getting rid of grouping field

Is there a safe way to not have to group by a field when using an aggregate in another field? Here is my example
SELECT
C.CustomerName
,D.INDUSTRY_CODE
,CASE WHEN D.INDUSTRY_CODE IN ('003','004','005','006','007','008','009','010','017','029')
THEN 'PM'
WHEN UPPER(CustomerName) = 'ULINE INC'
THEN 'ULINE'
ELSE 'DR'
END AS BU
,ISNULL((SELECT SUM(GrossAmount)
where CONVERT(date,convert(char(8),InvoiceDateID )) between DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 1, 0) and DATEADD(year, -1, GETDATE())),0) [PREVIOUS YEAR GROSS]
FROM factMargins A
LEFT OUTER JOIN dimDate B ON A.InvoiceDateID = B.DateId
LEFT OUTER JOIN dimCustomer C ON A.CustomerID = C.CustomerId
LEFT OUTER JOIN CRCDATA.DBO.CU10 D ON D.CUST_NUMB = C.CustomerNumber
GROUP BY
C.CustomerName,D.INDUSTRY_CODE
,A.InvoiceDateID
order by CustomerName
before grouping I was only getting 984 rows but after grouping by the A.InvoiceDateId field I am getting over 11k rows. The rows blow up since there are multiple invoices per customer. Min and Max wont work since then it will pull data incorrectly. Would it be best to let my application (crystal) get rid of the extra lines? Usually I like to have my base data be as close as possible to how the report will layout if possible.
Try moving the reference to InvoiceDateID to within an aggregate function, rather than within a selected subquery's WHERE clause.
In Oracle, here's an example:
with TheData as (
select 'A' customerID, 25 AMOUNT , trunc(sysdate) THEDATE from dual union
select 'B' customerID, 35 AMOUNT , trunc(sysdate-1) THEDATE from dual union
select 'A' customerID, 45 AMOUNT , trunc(sysdate-2) THEDATE from dual union
select 'A' customerID, 11000 AMOUNT , trunc(sysdate-3) THEDATE from dual union
select 'B' customerID, 12000 AMOUNT , trunc(sysdate-4) THEDATE from dual union
select 'A' customerID, 15000 AMOUNT , trunc(sysdate-5) THEDATE from dual)
select
CustomerID,
sum(amount) as "AllRevenue"
sum(case when thedate<sysdate-3 then amount else 0 end) as "OlderRevenue",
from thedata
group by customerID;
Output:
CustomerID | AllRevenue | OlderRevenue
A | 26070 | 26000
B | 12035 | 12000
This says:
For each customerID
I want the sum of all amounts
and I want the sum of amounts earlier than 3 days ago

SQL over partition count then group by month

I've been playing around with using COUNT(value) OVER (PARTITION BY anothervalue) and I love how fast it is pulling results from my db. I'm trying to step things up now so that I can create a table that will show me multiple counts - one for each month, side by side. I'm not sure if it is possible but wanted to check here. I had a look around online but couldn't find any examples of the question having been asked before, so no leads.
Here is what I currently have:
SELECT DISTINCT
TBL.CATEGORY as 'Category Name',
COUNT(TBL.ROW_ID) OVER (PARTITION BY TBL.CATEGORY) as 'Rows in Category'
FROM
MYDB.TBL
WHERE
TBL.FIELD1 = 'something'
AND TBL.FIELD2 = 'somethingelse'
AND TBL.CREATED >= '2014-01-01'
ORDER BY [Rows in Category] desc
Gives me a lovely table like this:
Category Name |Rows in Category
ABC | 166
CBA | 137
CCC | 112
Where I'm trying to get now is to subdivide by month so my output ends up looking something like this (does not have to be exact, the headers can be shuffled around):
JANUARY |FEBRUARY
Category Name |Rows in Category | Category Name |Rows in Category
ABC | 162 | CBA | 51
CBA | 86 | CCC | 32
CCC | 70 | ABC | 4
When I try adding GROUP BY it throws an error about something not being contained in an aggregate function.
If I have to I can just stack queries on top of each other and limit each one to only show one month, but that seems like a lot of repetitive code and I'd prefer a side by side view if it can be done.
Any ideas?
The format will not be exactly as you described. But this would be a normal way to show the result and all information has been included, make sure you do not display more than 1 year at a time.
Try this:
;WITH x AS
(
SELECT TBL.CATEGORY, TBL.ROW_ID, datename(month, TBL.CREATED) month
FROM
MYDB.TBL
WHERE
TBL.FIELD1 = 'something'
AND TBL.FIELD2 = 'somethingelse'
AND TBL.CREATED >= '2014-01-01'
AND TBL.CREATED < '2015-01-01'
)
SELECT CATEGORY as 'Category Name', [January],[February]
FROM x
PIVOT(
count([ROW_ID])
FOR month
in([January],[February])
)AS p
#t-clausen.dk thanks for your help with this. I had not previously used coalesce for anything so I learned something useful today. In the end, since I it turns out I need a total column anyway, I added a YTD column and was able to order by that.
Wanted to post the final result in case it is of use to anyone else:
WITH X AS
(
SELECT
tbl.category,
tbl.row_id,
DATENAME(MONTH, tbl.created) MONTH,
COUNT(tbl.row_id) OVER (PARTITION BY tbl.category) AS 'YTD'
FROM
db.tbl
WHERE
tbl.randomcolumn = 'something specific'
AND tbl.anothercolumn = 'something else specific'
AND created >= '2014-01-01'
AND created < '2015-01-01'
)
SELECT
category AS 'Category Name',
[January], [February], [March], [April], [May], [June], [July], [August], [September], [October], [November], [December],
[YTD]
FROM X
PIVOT
(COUNT([row_id])
FOR MONTH
in([January], [February], [March], [April], [May], [June], [July], [August], [September], [October], [November], [December])
)AS P
ORDER BY [YTD] DESC
Switch out the lower case parts for the equivalents in your own db/table if looking to repurpose this query.