Solved

T-SQL CASE Statement

Posted on 2014-01-02
6
903 Views
Last Modified: 2014-01-02
Hello:

Below is a select statement pulling fields of data from another select statement.  The "Month" field is formatted and returned as "Month 01", "Month 02", "Month 03", etc. through "Month 18".

When I run this statement against our data, some months legitimately do not appear.  Month 02 is an example.  There are no purchase orders for that month and, therefore, it does not show when selected.

But, I would like to show fields of data for Month 02 and any other "missing months".

So, I would like to have a single line of data representing Month 02 but have all other fields for that line be blank or 0.

How can I accomplish this?

Truthfully, I started with the second "big" select statement.  When I could not find a way to add missing months in it, I "added" the first select statement that is wrapped around the select case statement.  (I hope that makes sense.)

Thanks!

TBSupport



select
ContractNum, VENDORID, StartDate, EndDate, Month, ITEMNMBR, ITEMDESC, AvailQuantity, EXTDCOST
 FROM(
select RCG.dbo.POContractHeader.ContractNum, RCG.dbo.POContractHeader.VENDORID, RCG.dbo.POContractHeader.StartDate, RCG.dbo.POContractHeader.EndDate,
'Month ' +
CASE WHEN DATEDIFF(m,GETDATE(),RCG.dbo.POContractHeader.EndDate) + 1 < 10
THEN CAST(CAST('0' AS VARCHAR) + CAST(DATEDIFF(m,GETDATE(),RCG.dbo.POContractHeader.EndDate) + 1 AS VARCHAR(1)) AS VARCHAR(2))
ELSE CAST(DATEDIFF(m,GETDATE(), RCG.dbo.POContractHeader.EndDate) + 1 AS VARCHAR(2))
END
AS Month,
--RCG.dbo.PODraws.PONUMBER,
RCG.dbo.POContractDetail.ITEMNMBR, RCG.dbo.POContractDetail.ITEMDESC, RCG.dbo.POContractDetail.AvailQuantity, RCG.dbo.POContractDetail.EXTDCOST
from RCG.dbo.POContractHeader
INNER JOIN RCG.dbo.POContractDetail on RCG.dbo.POContractHeader.ContractNum = RCG.dbo.POContractDetail.ContractNum
and RCG.dbo.POContractHeader.VENDORID = RCG.dbo.POContractDetail.VENDORID
INNER JOIN RCG.dbo.PODraws on RCG.dbo.POContractDetail.ContractNum = RCG.dbo.PODraws.ContractNum
and RCG.dbo.POContractDetail.VENDORID = RCG.dbo.PODraws.VENDORID
where RCG.dbo.POContractHeader.StartDate IS NOT NULL and RCG.dbo.POContractHeader.EndDate IS NOT NULL
and RCG.dbo.POContractDetail.AvailQuantity <> 0
and (RCG.dbo.POContractHeader.EndDate >= DATEADD(m, DATEDIFF(m, 0, GETDATE()), 0)) AND
(RCG.dbo.POContractHeader.EndDate < DATEADD(m, DATEDIFF(m, 0, GETDATE()) + 18, 0))
and RCG.dbo.POContractHeader.VENDORID = '8000028'
GROUP BY RCG.dbo.POContractHeader.VENDORID,
RCG.dbo.POContractHeader.ContractNum,
RCG.dbo.POContractHeader.StartDate, RCG.dbo.POContractHeader.EndDate,
RCG.dbo.POContractDetail.ITEMNMBR, RCG.dbo.POContractDetail.ITEMDESC, RCG.dbo.POContractDetail.AvailQuantity, RCG.dbo.POContractDetail.EXTDCOST--,
--RCG.dbo.PODraws.PONUMBER,
) as test
--ORDER BY RCG.dbo.POContractHeader.VENDORID, RCG.dbo.POContractHeader.EndDate
0
Comment
Question by:TBSupport
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
  • 2
6 Comments
 
LVL 25

Accepted Solution

by:
chaau earned 500 total points
ID: 39752491
You need to create a simple recursive CTE for the numbers 1 to 18, like this:
;with numbers as(
  SELECT 1 as N
  UNION ALL 
  SELECT numbers.N + 1
  FROM numbers
  WHERE N < 18)
-- your normal select goes here, below is an example
SELECT * FROM numbers

Open in new window

Or, if above is too confusing, you can use UNION ALL, like this:
;with numbers as(
SELECT 1 as N
UNION ALL
SELECT 2 as N
UNION ALL
SELECT 3 as N
UNION ALL
SELECT 4 as N
UNION ALL
SELECT 5 as N
-- and so on
)

Open in new window

Or, if the above statement seems to be too bulky, use
;with numbers as(
SELECT TOP 18 row_number() over(order by number) as N FROM master..spt_values
)

Open in new window

And now all you need to do is to left-join the numbers cte with your existing query, like this:
;with numbers as(
-- put here any cte from the above, e.g.
SELECT TOP 18 row_number() over(order by number) as N FROM master..spt_values
),
months AS(
  SELECT 'Month ' + REPLACE(STR(N, 2), ' ', '0') AS Month
  FROM numbers)
select 
ContractNum, VENDORID, StartDate, EndDate, m.Month, ITEMNMBR, ITEMDESC, AvailQuantity, EXTDCOST
FROM months M LEFT JOIN
 (
select RCG.dbo.POContractHeader.ContractNum, RCG.dbo.POContractHeader.VENDORID, RCG.dbo.POContractHeader.StartDate, RCG.dbo.POContractHeader.EndDate,
'Month ' + REPLACE(STR(DATEDIFF(m,GETDATE(), RCG.dbo.POContractHeader.EndDate) + 1, 2), ' ', '0') AS Month,
--RCG.dbo.PODraws.PONUMBER,
RCG.dbo.POContractDetail.ITEMNMBR, RCG.dbo.POContractDetail.ITEMDESC, RCG.dbo.POContractDetail.AvailQuantity, RCG.dbo.POContractDetail.EXTDCOST
from RCG.dbo.POContractHeader
INNER JOIN RCG.dbo.POContractDetail on RCG.dbo.POContractHeader.ContractNum = RCG.dbo.POContractDetail.ContractNum
and RCG.dbo.POContractHeader.VENDORID = RCG.dbo.POContractDetail.VENDORID
INNER JOIN RCG.dbo.PODraws on RCG.dbo.POContractDetail.ContractNum = RCG.dbo.PODraws.ContractNum
and RCG.dbo.POContractDetail.VENDORID = RCG.dbo.PODraws.VENDORID
where RCG.dbo.POContractHeader.StartDate IS NOT NULL and RCG.dbo.POContractHeader.EndDate IS NOT NULL
and RCG.dbo.POContractDetail.AvailQuantity <> 0
and (RCG.dbo.POContractHeader.EndDate >= DATEADD(m, DATEDIFF(m, 0, GETDATE()), 0)) AND
(RCG.dbo.POContractHeader.EndDate < DATEADD(m, DATEDIFF(m, 0, GETDATE()) + 18, 0))
and RCG.dbo.POContractHeader.VENDORID = '8000028'
GROUP BY RCG.dbo.POContractHeader.VENDORID,
RCG.dbo.POContractHeader.ContractNum,
RCG.dbo.POContractHeader.StartDate, RCG.dbo.POContractHeader.EndDate,
RCG.dbo.POContractDetail.ITEMNMBR, RCG.dbo.POContractDetail.ITEMDESC, RCG.dbo.POContractDetail.AvailQuantity, RCG.dbo.POContractDetail.EXTDCOST--,
--RCG.dbo.PODraws.PONUMBER,
) as test ON m.Month = test.Month

Open in new window


BTW, have you noticed that your case When < 10 can be replaced with a simpler version REPLACE(STR(N, 2), ' ', '0')
0
 
LVL 41

Expert Comment

by:Sharath
ID: 39752531
If you have months from 01 to 18, you can hardcode them like this in a sub-query and LEFT JOIN your actual query.
SELECT ContractNum, 
       VENDORID, 
       StartDate, 
       EndDate, 
       t1.[Month], 
       ITEMNMBR, 
       ITEMDESC, 
       AvailQuantity, 
       EXTDCOST 
  FROM (SELECT 'Month01' [Month] 
        UNION ALL 
        SELECT 'Month02' 
        UNION ALL 
        SELECT 'Month03' 
        UNION ALL 
        SELECT 'Month04' 
        UNION ALL 
        SELECT 'Month05' 
        UNION ALL 
        SELECT 'Month06' 
        UNION ALL 
        SELECT 'Month07' 
        UNION ALL 
        SELECT 'Month08' 
        UNION ALL 
        SELECT 'Month09' 
        UNION ALL 
        SELECT 'Month10' 
        UNION ALL 
        SELECT 'Month11' 
        UNION ALL 
        SELECT 'Month12' 
        UNION ALL 
        SELECT 'Month13' 
        UNION ALL 
        SELECT 'Month14' 
        UNION ALL 
        SELECT 'Month15' 
        UNION ALL 
        SELECT 'Month16' 
        UNION ALL 
        SELECT 'Month17' 
        UNION ALL 
        SELECT 'Month18') t1 
       LEFT JOIN (SELECT RCG.DBO.POContractHeader.ContractNum, 
                         RCG.DBO.POContractHeader.VENDORID, 
                         RCG.DBO.POContractHeader.StartDate, 
                         RCG.DBO.POContractHeader.EndDate, 
                         'Month ' + CASE WHEN DATEDIFF(M, GETDATE(), RCG.DBO.POContractHeader.EndDate) + 1 < 10 THEN CAST(CAST('0' AS VARCHAR) + CAST(DATEDIFF(M, GETDATE(), RCG.DBO.POContractHeader.EndDate) + 1 AS VARCHAR(1)) AS VARCHAR(2)) ELSE CAST(DATEDIFF(M, GETDATE(), RCG.DBO.POContractHeader.EndDate) + 1 AS VARCHAR(2)) END AS [Month],
                         --RCG.dbo.PODraws.PONUMBER,  
                         RCG.DBO.POContractDetail.ITEMNMBR, 
                         RCG.DBO.POContractDetail.ITEMDESC, 
                         RCG.DBO.POContractDetail.AvailQuantity, 
                         RCG.DBO.POContractDetail.EXTDCOST 
                    FROM RCG.DBO.POContractHeader 
                         INNER JOIN RCG.DBO.POContractDetail 
                                 ON RCG.DBO.POContractHeader.ContractNum = RCG.DBO.POContractDetail.ContractNum
                                    AND RCG.DBO.POContractHeader.VENDORID = RCG.DBO.POContractDetail.VENDORID
                         INNER JOIN RCG.DBO.PODraws 
                                 ON RCG.DBO.POContractDetail.ContractNum = RCG.DBO.PODraws.ContractNum
                                    AND RCG.DBO.POContractDetail.VENDORID = RCG.DBO.PODraws.VENDORID
                   WHERE RCG.DBO.POContractHeader.StartDate IS NOT NULL 
                     AND RCG.DBO.POContractHeader.EndDate IS NOT NULL 
                     AND RCG.DBO.POContractDetail.AvailQuantity <> 0 
                     AND ( RCG.DBO.POContractHeader.EndDate >= DATEADD(M, DATEDIFF(M, 0, GETDATE()), 0) )
                     AND ( RCG.DBO.POContractHeader.EndDate < DATEADD(M, DATEDIFF(M, 0, GETDATE()) + 18, 0) )
                     AND RCG.DBO.POContractHeader.VENDORID = '8000028' 
                   GROUP BY RCG.DBO.POContractHeader.VENDORID, 
                            RCG.DBO.POContractHeader.ContractNum, 
                            RCG.DBO.POContractHeader.StartDate, 
                            RCG.DBO.POContractHeader.EndDate, 
                            RCG.DBO.POContractDetail.ITEMNMBR, 
                            RCG.DBO.POContractDetail.ITEMDESC, 
                            RCG.DBO.POContractDetail.AvailQuantity, 
                            RCG.DBO.POContractDetail.EXTDCOST--,  
                 --RCG.dbo.PODraws.PONUMBER,  
                 ) AS test 
              ON t1.[Month] = t2.[Month] 
--ORDER BY RCG.dbo.POContractHeader.VENDORID, RCG.dbo.POContractHeader.EndDate

Open in new window

0
 
LVL 1

Author Comment

by:TBSupport
ID: 39752568
Thanks, All, for the responses!

Sharath_123>> I think that your "[Month]" is out of place.  Can you check, again, and update the case?  

Also, where is "t2"?

TBSupport
0
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 1

Author Comment

by:TBSupport
ID: 39752583
chaau>>Your solution works really well!  Thank you!  Question:  Is there a way for me to get the EXTDCOST to return "0" instead of "NULL"?
0
 
LVL 25

Expert Comment

by:chaau
ID: 39752607
Sure, use ISNULL(), like this:
.....
select 
ContractNum, VENDORID, StartDate, EndDate, m.Month, ITEMNMBR, ITEMDESC, AvailQuantity, ISNULL(EXTDCOST,0) AS EXTDCOST
......

Open in new window

0
 
LVL 41

Expert Comment

by:Sharath
ID: 39752619
>>  I think that your "[Month]" is out of place.
What do you mean?

>> Also, where is "t2"?
replace t2 with test.
0

Featured Post

Free eBook: Backup on AWS

Everything you need to know about backup and disaster recovery with AWS, for FREE!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Hi, I have heard from my friends that it’s not possible to create Label Printing report using SSRS. I am amazed after hearing this words not possible in SSRS. I googled lot and found that it is possible to some of people know about the Report Bui…
In this article I will describe the Copy Database Wizard method as one possible migration process and I will add the extra tasks needed for an upgrade when and where is applied so it will cover all.
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question