Nested case limit - sql

I'm trying to use nested case but SQL is giving me an error on 10 limit. Below is my sql. Do you have any suggestions for me?
ALTER VIEW [dbo].[vwOpti_ChannelPreference] AS
SELECT SUB.*,
CASE WHEN PCYCResponse + JBIResponse > 1 THEN 'SF Multi'
ELSE CASE WHEN MDLResponse + SermoResponse + BioPharmResponse + MedscapeResponse + PharmaConnectResponse + THResponse
+ OtherResponse > 1 THEN 'MCM Multi'
ELSE CASE WHEN MDLResponse + SermoResponse + BioPharmResponse + MedscapeResponse + PharmaConnectResponse + THResponse
+ PCYCResponse + JBIResponse + OtherResponse > 1 THEN 'SF & MCM Multi'
ELSE CASE WHEN MDLResponse + SermoResponse + BioPharmResponse + MedscapeResponse + PharmaConnectResponse + THResponse
+ PCYCResponse + JBIResponse + OtherResponse = 0 THEN 'None'
ELSE CASE WHEN MDLResponse = 1 THEN 'MDL'
ELSE CASE WHEN SermoResponse = 1 THEN 'Sermo'
ELSE CASE WHEN BioPharmResponse = 1 THEN 'BioPharmCommunications'
ELSE CASE WHEN MedscapeResponse = 1 THEN 'Medscape'
ELSE CASE WHEN PharmaConnectResponse = 1 THEN 'PharmaConnect'
ELSE CASE WHEN THResponse = 1 THEN 'Targeted Healthcare'
ELSE CASE WHEN PCYCResponse = 1 THEN 'PCYC'
ELSE CASE WHEN JBIResponse = 1 THEN 'JBI'
ELSE CASE WHEN OtherResponse = 1 THEN 'Other'
END END END END END END END END END END END END AS ChannelPref
FROM ( SELECT CC.*,
MAX(CASE WHEN MTE.DesignVendor = 'MDL' THEN 1 ELSE 0 END) AS MDLResponse,
MAX(CASE WHEN MTE.DesignVendor = 'Sermo' THEN 1 ELSE 0 END) AS SermoResponse,
MAX(CASE WHEN MTE.DesignVendor = 'BioPharmCommunications' THEN 1 ELSE 0 END) AS BioPharmResponse,
MAX(CASE WHEN MTE.DesignVendor = 'Medscape' THEN 1 ELSE 0 END) AS MedscapeResponse,
MAX(CASE WHEN MTE.DesignVendor = 'PharmaConnect' THEN 1 ELSE 0 END) AS PharmaConnectResponse,
MAX(CASE WHEN MTE.DesignVendor = 'Targeted Healthcare' THEN 1 ELSE 0 END) AS THResponse,
MAX(CASE WHEN MTE.DesignVendor = 'PCYC' THEN 1 ELSE 0 END) AS PCYCResponse,
MAX(CASE WHEN MTE.DesignVendor = 'JBI' THEN 1 ELSE 0 END) AS JBIResponse,
MAX(CASE WHEN MTE.DesignVendor NOT IN ('MDL','Sermo', 'BioPharmCommunications', 'Medscape', 'PharmaConnect',
'Targeted Healthcare', 'PCYC', 'JBI') THEN 1 ELSE 0 END) AS OtherResponse
--SELECT DISTINCT MTE.CHANNELNAME
FROM slice_CampaignContact CC
--LEFT JOIN slice_MktgTactic MTI ON I.MktgTacticID = MTI.MktgTacticID AND I.SliceDate = MTI.SliceDate
LEFT JOIN slice_Engagements E ON CC.ContactID = E.ContactID AND CC.SliceDate = E.SliceDate
LEFT JOIN slice_MktgTactic MTE ON E.MktgTacticID = MTE.MktgTacticID AND E.SliceDate = MTE.SliceDate
GROUP BY CC.SliceDate, CC.BrandCd, CC.ContactID, CC.SyncID, CC.FirstName, CC.LastName, CC.CampaignName,
ClientSegment, ControlSegmentName) SUB

You don't need the ELSE CASE every time -- that is just the way CASE works -- each WHEN is only checked on when prior WHENs fail. Like this:
SELECT SUB.*,
CASE
WHEN PCYCResponse + JBIResponse > 1 THEN 'SF Multi'
WHEN MDLResponse + SermoResponse + BioPharmResponse + MedscapeResponse + PharmaConnectResponse + THResponse + OtherResponse > 1 THEN 'MCM Multi'
WHEN MDLResponse + SermoResponse + BioPharmResponse + MedscapeResponse + PharmaConnectResponse + THResponse + PCYCResponse + JBIResponse + OtherResponse > 1 THEN 'SF & MCM Multi'
WHEN MDLResponse + SermoResponse + BioPharmResponse + MedscapeResponse + PharmaConnectResponse + THResponse + PCYCResponse + JBIResponse + OtherResponse = 0 THEN 'None'
WHEN MDLResponse = 1 THEN 'MDL'
WHEN SermoResponse = 1 THEN 'Sermo'
WHEN BioPharmResponse = 1 THEN 'BioPharmCommunications'
WHEN MedscapeResponse = 1 THEN 'Medscape'
WHEN PharmaConnectResponse = 1 THEN 'PharmaConnect'
WHEN THResponse = 1 THEN 'Targeted Healthcare'
WHEN PCYCResponse = 1 THEN 'PCYC'
WHEN JBIResponse = 1 THEN 'JBI'
WHEN OtherResponse = 1 THEN 'Other'
ELSE 'Woah, nothing matched'
END AS ChannelPref
FROM ( SELECT CC.*, -- etc

Related

Issue with complex query "the multi-part identifier could not be bound"

I am having trouble creating this view on SQL. As a query, it runs fine, but when trying to save it as a view, it gives me the "the multi-part identifier could not be bound" error. I think it has something to do with implicit joins.
The issue occurs when inserting the part with the extra tabs in the script below (case statements).
Is there a way to rewrite it to save it as a view?
Thanks
WITH MNP AS
(SELECT
GoodsReceivedID AS ID,
PORef,
MIN(IncomingDate) AS Manip_Start_Date,
SUM(CASE WHEN ArticleType = 'TEX' THEN UNITS ELSE 0 END) AS TEX_Mnp,
SUM(CASE WHEN ArticleType = 'ACC' THEN UNITS ELSE 0 END) AS ACC_Mnp,
SUM(CASE WHEN ArticleType = 'SHOE' THEN UNITS ELSE 0 END) AS SHOE_Mnp,
SUM(CASE WHEN ArticleType = 'TARA' THEN UNITS ELSE 0 END) AS TARA_Mnp,
SUM(CASE WHEN ArticleType NOT IN ('TEX','ACC','SHOE','TARA') THEN UNITS ELSE 0 END) AS MIX_Mnp,
SUM(UNITS) AS Total_Units
FROM dbo.NT_ManipulationResult
GROUP BY PORef, GoodsReceivedID),
INV AS
(SELECT
GoodsReceivedID,
SUM(CASE WHEN UNITOFSUPPLYID = 1 THEN IN_TOTAL_UNITS END) AS Invoice_Units,
SUM (CASE WHEN UNITOFSUPPLYID = 2 THEN IN_TOTAL_UNITS END) AS Invoice_KG,
SUM (InvoiceNet + InvoiceVAT) AS Invoice_TOT
FROM [dbo].[NT_GoodsReceivedInvoice]
GROUP BY GoodsReceivedID
)
SELECT
GR.ID,
GR.VL_Ref,
GR.DateReceived,
MNP.Manip_Start_Date,
COALESCE(DATEDIFF (Day, DateReceived, MNP.Manip_Start_Date),'') AS DaysToManipulate,
WR.Name AS Warehouse,
GR.ArticleOriginID AS Origin,
SP.Name AS Supplier,
GD.Name AS Grade,
COALESCE(INV.Invoice_TOT,0) AS Invoice_TOT,
COALESCE(INV.Invoice_Units,0) AS Invoice_Units,
COALESCE(INV.Invoice_KG,0) AS Invoice_KG,
COALESCE(MNP.Total_Units,0) AS ManipulatedUnits,
CASE WHEN COALESCE(MNP.Total_Units,0) <> 0 THEN COALESCE(MNP.Total_Units,0) - COALESCE(INV.Invoice_Units,0) ELSE 0 END AS Manip_Difference,
COALESCE(MNP.TEX_Mnp,0) AS TEX_Mnp,
COALESCE(MNP.ACC_Mnp,0) AS ACC_Mnp,
COALESCE(MNP.SHOE_Mnp,0) AS SHOE_Mnp,
COALESCE(MNP.TARA_Mnp,0) AS TARA_Mnp,
COALESCE(MNP.MIX_Mnp,0) AS MIX_Mnp,
CASE WHEN COALESCE(MNP.Total_Units,0) <> 0 THEN (COALESCE(INV.Invoice_TOT,0) / (COALESCE(MNP.TEX_Mnp,0) + 0.35*COALESCE(MNP.ACC_Mnp,0) + 1.2*COALESCE(MNP.SHOE_Mnp,0) + .45*COALESCE(MNP.TARA_Mnp,0) +.8*COALESCE(MNP.MIX_Mnp,0))) ELSE 0 END AS TEX_Cost,
CASE WHEN COALESCE(MNP.Total_Units,0) <> 0 THEN 0.35*(COALESCE(INV.Invoice_TOT,0) / (COALESCE(MNP.TEX_Mnp,0) + 0.35*COALESCE(MNP.ACC_Mnp,0) + 1.2*COALESCE(MNP.SHOE_Mnp,0) + .45*COALESCE(MNP.TARA_Mnp,0) +.8*COALESCE(MNP.MIX_Mnp,0))) ELSE 0 END AS ACC_Cost,
CASE WHEN COALESCE(MNP.Total_Units,0) <> 0 THEN 1.2*(COALESCE(INV.Invoice_TOT,0) / (COALESCE(MNP.TEX_Mnp,0) + 0.35*COALESCE(MNP.ACC_Mnp,0) + 1.2*COALESCE(MNP.SHOE_Mnp,0) + .45*COALESCE(MNP.TARA_Mnp,0) +.8*COALESCE(MNP.MIX_Mnp,0))) ELSE 0 END AS SHOE_Cost,
CASE WHEN COALESCE(MNP.Total_Units,0) <> 0 THEN 0.45*(COALESCE(INV.Invoice_TOT,0) / (COALESCE(MNP.TEX_Mnp,0) + 0.35*COALESCE(MNP.ACC_Mnp,0) + 1.2*COALESCE(MNP.SHOE_Mnp,0) + .45*COALESCE(MNP.TARA_Mnp,0) +.8*COALESCE(MNP.MIX_Mnp,0))) ELSE 0 END AS TARA_Cost,
CASE WHEN COALESCE(MNP.Total_Units,0) <> 0 THEN 0.8*(COALESCE(INV.Invoice_TOT,0) / (COALESCE(MNP.TEX_Mnp,0) + 0.35*COALESCE(MNP.ACC_Mnp,0) + 1.2*COALESCE(MNP.SHOE_Mnp,0) + .45*COALESCE(MNP.TARA_Mnp,0) +.8*COALESCE(MNP.MIX_Mnp,0))) ELSE 0 END AS MIX_Cost
FROM dbo.NT_GoodsReceived AS GR
LEFT OUTER JOIN MNP ON GR.ID = MNP.ID
LEFT OUTER JOIN [dbo].[NT_Warehouse] WR ON GR.WarehouseID = WR.ID
LEFT OUTER JOIN [dbo].[NT_ArticleOrigin] AO ON GR.ArticleOriginID = AO.ID
LEFT OUTER JOIN [dbo].[NT_Supplier] SP ON GR.SupplierID = SP.ID
LEFT OUTER JOIN [dbo].[NT_ArticleGrade] GD ON GR.ArticleGradeID = GD.ID
LEFT OUTER JOIN INV ON GR.ID = INV.GoodsReceivedID
WHERE GR.ID NOT IN (19,20)
I found a solution:
Instead of adding MNP and INV as WITH statements within the query, I created them as separate views which I referenced to within this new query which I could now save as view.
Script ended as follows:
SELECT
GR.ID,
GR.VL_Ref,
GR.DateReceived,
MNP.Manip_Start_Date,
COALESCE (DATEDIFF (Day, GR.DateReceived, MNP.Manip_Start_Date),'') AS DaysToManipulate,
WR.Name AS Warehouse,
GR.ArticleOriginID AS Origin,
SP.Name AS Supplier,
GD.Name AS Grade,
COALESCE(INV.Invoice_TOT,0) AS Invoice_TOT,
COALESCE(INV.Invoice_Units,0) AS Invoice_Units,
COALESCE(INV.Invoice_KG,0) AS Invoice_KG,
COALESCE(MNP.Total_Units,0) AS ManipulatedUnits,
CASE WHEN MNP.Total_Units IS NOT NULL THEN MNP.Total_Units - INV.Invoice_Units ELSE 0 END AS Manip_Difference,
COALESCE(MNP.TEX_Mnp,0) AS TEX_Mnp,
COALESCE(MNP.ACC_Mnp,0) AS ACC_Mnp,
COALESCE(MNP.SHOE_Mnp,0) AS SHOE_Mnp,
COALESCE(MNP.TARA_Mnp,0) AS TARA_Mnp,
COALESCE(MNP.MIX_Mnp,0) AS MIX_Mnp,
CASE WHEN MNP.Total_Units IS NOT NULL THEN (COALESCE(INV.Invoice_TOT,0) / (COALESCE(MNP.TEX_Mnp,0) + 0.35*COALESCE(MNP.ACC_Mnp,0) + 1.2*COALESCE(MNP.SHOE_Mnp,0) + .45*COALESCE(MNP.TARA_Mnp,0) +.8*COALESCE(MNP.MIX_Mnp,0))) ELSE 0 END AS TEX_Cost,
CASE WHEN MNP.Total_Units IS NOT NULL THEN 0.35*(COALESCE(INV.Invoice_TOT,0) / (COALESCE(MNP.TEX_Mnp,0) + 0.35*COALESCE(MNP.ACC_Mnp,0) + 1.2*COALESCE(MNP.SHOE_Mnp,0) + .45*COALESCE(MNP.TARA_Mnp,0) +.8*COALESCE(MNP.MIX_Mnp,0))) ELSE 0 END AS ACC_Cost,
CASE WHEN MNP.Total_Units IS NOT NULL THEN 1.2*(COALESCE(INV.Invoice_TOT,0) / (COALESCE(MNP.TEX_Mnp,0) + 0.35*COALESCE(MNP.ACC_Mnp,0) + 1.2*COALESCE(MNP.SHOE_Mnp,0) + .45*COALESCE(MNP.TARA_Mnp,0) +.8*COALESCE(MNP.MIX_Mnp,0))) ELSE 0 END AS SHOE_Cost,
CASE WHEN MNP.Total_Units IS NOT NULL THEN 0.45*(COALESCE(INV.Invoice_TOT,0) / (COALESCE(MNP.TEX_Mnp,0) + 0.35*COALESCE(MNP.ACC_Mnp,0) + 1.2*COALESCE(MNP.SHOE_Mnp,0) + .45*COALESCE(MNP.TARA_Mnp,0) +.8*COALESCE(MNP.MIX_Mnp,0))) ELSE 0 END AS TARA_Cost,
CASE WHEN MNP.Total_Units IS NOT NULL THEN 0.8*(COALESCE(INV.Invoice_TOT,0) / (COALESCE(MNP.TEX_Mnp,0) + 0.35*COALESCE(MNP.ACC_Mnp,0) + 1.2*COALESCE(MNP.SHOE_Mnp,0) + .45*COALESCE(MNP.TARA_Mnp,0) +.8*COALESCE(MNP.MIX_Mnp,0))) ELSE 0 END AS MIX_Cost
FROM dbo.NT_GoodsReceived AS GR
LEFT OUTER JOIN MNP ON GR.ID = MNP.ID
LEFT OUTER JOIN dbo.NT_Warehouse AS WR ON GR.WarehouseID = WR.ID
LEFT OUTER JOIN dbo.NT_ArticleOrigin AS AO ON GR.ArticleOriginID = AO.ID
LEFT OUTER JOIN dbo.NT_Supplier AS SP ON GR.SupplierID = SP.ID
LEFT OUTER JOIN dbo.NT_ArticleGrade AS GD ON GR.ArticleGradeID = GD.ID
LEFT OUTER JOIN INV ON GR.ID = INV.GoodsReceivedID
WHERE (GR.ID NOT IN (19, 20))

SQL add conversion of date to existing query

I'm would like to convert the date using this function. I'm using SQL server 2014
CONVERT(varchar, sc.StartDate,103) + '" + " " + "' + '" + " - " + "' + CONVERT(varchar, sc.EndDate,103) SIPDate
so it will display in dd/mm/yyyy - dd/mm/yyyy. How do i add it into the query? Thanks.
The query is:
SELECT CONCAT(sc.StartDate, sc.ENDDate) SIPDate,
COUNT (sj.LOComment) WeekReviewed,
COUNT(sjd.WeekNo) TotalWeek,
SUM(sjj.TotalDaysRecord) TotalDaysRecord,
COUNT(CASE sjd.JournalStatusCode WHEN 'D' THEN 1 ELSE NULL END) PENDingComplete
FROM StudentJournalDate sjd
LEFT JOIN StudentJournal sj
ON sjd.WeekNo = sj.WeekNo
LEFT OUTER JOIN
(
SELECT sj.WeekNo,
CASE WHEN RTRIM(sj.Day1Journal) = '' OR sj.Day1Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day2Journal) = '' OR sj.Day2Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day3Journal) = '' OR sj.Day3Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day4Journal) = '' OR sj.Day4Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day5Journal) = '' OR sj.Day5Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day6Journal) = '' OR sj.Day6Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day7Journal) = '' OR sj.Day7Journal IS NULL THEN 0 ELSE 1 END AS TotalDaysRecord
FROM StudentJournal sj
) AS sjj
ON sjj.WeekNo = sj.WeekNo
LEFT OUTER JOIN StudentSIP sc
ON sc.AdminNo = sjd.AdminNo
GROUP BY CONCAT(sc.StartDate, sc.ENDDate)
You can just SELECT and GROUP BY this formatted date expression, i.e.:
SELECT CONVERT(varchar, sc.StartDate, 103) + " - " + CONVERT(varchar, sc.EndDate, 103) AS SIPDate,
COUNT (sj.LOComment) WeekReviewed,
COUNT(sjd.WeekNo) TotalWeek,
SUM(sjj.TotalDaysRecord) TotalDaysRecord,
COUNT(CASE sjd.JournalStatusCode WHEN 'D' THEN 1 ELSE NULL END) PENDingComplete
FROM StudentJournalDate sjd
LEFT JOIN StudentJournal sj
ON sjd.WeekNo = sj.WeekNo
LEFT OUTER JOIN
(
SELECT sj.WeekNo,
CASE WHEN RTRIM(sj.Day1Journal) = '' OR sj.Day1Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day2Journal) = '' OR sj.Day2Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day3Journal) = '' OR sj.Day3Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day4Journal) = '' OR sj.Day4Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day5Journal) = '' OR sj.Day5Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day6Journal) = '' OR sj.Day6Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day7Journal) = '' OR sj.Day7Journal IS NULL THEN 0 ELSE 1 END AS TotalDaysRecord
FROM StudentJournal sj
) AS sjj
ON sjj.WeekNo = sj.WeekNo
LEFT OUTER JOIN StudentSIP sc
ON sc.AdminNo = sjd.AdminNo
GROUP BY CONVERT(varchar, sc.StartDate, 103) + " - " + CONVERT(varchar, sc.EndDate, 103)
Try this. since your SQL SERVER is 2014 you can use format to format the date
SELECT CONCAT(FORMAT(sc.StartDate,'dd/MM/yyy'),+ ' - ' +FORMAT(sc.ENDDate,'dd/MM/yyy')) SIPDate,
COUNT (sj.LOComment) WeekReviewed,
COUNT(sjd.WeekNo) TotalWeek,
SUM(sjj.TotalDaysRecord) TotalDaysRecord,
COUNT(CASE sjd.JournalStatusCode WHEN 'D' THEN 1 ELSE NULL END) PENDingComplete
FROM StudentJournalDate sjd
LEFT JOIN StudentJournal sj
ON sjd.WeekNo = sj.WeekNo
LEFT OUTER JOIN
(
SELECT sj.WeekNo,
CASE WHEN RTRIM(sj.Day1Journal) = '' OR sj.Day1Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day2Journal) = '' OR sj.Day2Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day3Journal) = '' OR sj.Day3Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day4Journal) = '' OR sj.Day4Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day5Journal) = '' OR sj.Day5Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day6Journal) = '' OR sj.Day6Journal IS NULL THEN 0 ELSE 1 END +
CASE WHEN RTRIM(sj.Day7Journal) = '' OR sj.Day7Journal IS NULL THEN 0 ELSE 1 END AS TotalDaysRecord
FROM StudentJournal sj
) AS sjj
ON sjj.WeekNo = sj.WeekNo
LEFT OUTER JOIN StudentSIP sc
ON sc.AdminNo = sjd.AdminNo
GROUP BY CONCAT(FORMAT(sc.StartDate,'dd/MM/yyy'),+ ' - ' +FORMAT(sc.ENDDate,'dd/MM/yyy'))

How to count up a single character in multiple fields in SQL

HI i have a table 'TableCustomers' and within this table are many fields titled 'Name1' 'Name2''Name3'.... 'Name40' some of these fields just have the letter 'x' i want to know how many 'x' are there in all 40 fields
One possible solution is something like;
SELECT
CASE WHEN [Name] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name1] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name2] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name3] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name4] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name5] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name6] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name7] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name8] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name9] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name10] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name11] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name12] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name13] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name14] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name15] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name16] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name17] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name18] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name19] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name20] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name21] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name22] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name23] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name24] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name25] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name26] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name27] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name28] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name29] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name30] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name31] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name32] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name33] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name34] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name35] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name36] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name37] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name38] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name39] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name40] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name41] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name42] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name43] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name44] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name45] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name46] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name47] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name48] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name49] = 'x' THEN 1 ELSE 0 END +
CASE WHEN [Name50] = 'x' THEN 1 ELSE 0 END
FROM [TableCustomers]
I generated this using an application called Nimble Text (http://nimbletext.com/) though you could use dynamic SQL along with the sys.columns view to generate this statement within SQL server, if the columns of the table change. Let me know if you would like an example of this...
You may try something like this:
select len(name00 + name01 + .. + name40) - len(replace(name00 + name01 + .. + name40, 'x', ''))
from yourTable;

Adding a count of values

Is there another way I can sum up counts with less code?
I'm using a view (my only option) to try to find out if a customer spent money during any two of the last 5 calendar years
Table name:
V_PERSON
V_REVENUE
Columns:
V_PERSON.ID
V.REVENUE.PersonID
V.REVENUE.Year1 revenue for the year (currently 2016)
V.REVENUE.Year2 revenue for the year (currently, 2015)
V.REVENUE.Year3
V.REVENUE.Year4
V.REVENUE.Year5
Here's what I've tried:
SELECT V_PERSON.ID
FROM V_PERSON
WHERE
(
(
SELECT '1'
FROM V_REVENUE
WHERE V_REVENUE.PersonID = V_PERSON.ID
AND V_REVENUE.Year1 > 0
)
+
(
SELECT '1'
FROM V_REVENUE
WHERE V_REVENUE.PersonID = V_PERSON.ID
AND V_REVENUE.Year2 > 0
)
+
(
SELECT '1'
FROM V_REVENUE
WHERE V_REVENUE.PersonID = V_PERSON.ID
AND V_REVENUE.Year3 > 0
)
+
(
SELECT '1'
FROM V_REVENUE
WHERE V_REVENUE.PersonID = V_PERSON.ID
AND V_REVENUE.Year4 > 0
)
+
(
SELECT '1'
FROM V_REVENUE
WHERE V_REVENUE.PersonID = V_PERSON.ID
AND V_REVENUE.Year5 > 0
)
) >= 2
Here's one option using exists with multiple case statements:
select id
from person p
where exists (
select 1
from revenue r
where p.id = r.personid
and case when r.year1 > 0 then 1 else 0 end +
case when r.year2 > 0 then 1 else 0 end +
case when r.year3 > 0 then 1 else 0 end +
case when r.year4 > 0 then 1 else 0 end +
case when r.year5 > 0 then 1 else 0 end >= 2
)
How about a CASE statement:
SELECT V_PERSON.ID
FROM V_PERSON
WHERE
(
SELECT (case when V_REVENUE.Year1 > 0 then 1 else 0 end) +
(case when V_REVENUE.Year2 > 0 then 1 else 0 end) +
(case when V_REVENUE.Year3 > 0 then 1 else 0 end) +
(case when V_REVENUE.Year4 > 0 then 1 else 0 end) +
(case when V_REVENUE.Year5 > 0 then 1 else 0 end)
FROM V_REVENUE
WHERE V_REVENUE.PersonID = V_PERSON.ID) >= 2

SQL Server Subquery Return Error

When I try to execute my statements, I get an error that returns "Subquery returned more than 1 value. Not allowed...," you know the rest. I'm not good with subqueries, in fact it's guessing with trial and error sometimes until I see the result I'm trying to gather. Can anyone explain to me the issue of why it's returning with this error?
I'm trying to return the score for one person's game before moving on to return all players from the same game.
The file is here if the data is relevant: SQL File
SELECT
TP.intPlayerID
,TP.strLastName + ', ' + TP.strFirstName AS strPlayerName
,TG.*
,TR.intGameID
,(
SELECT
CASE WHEN Game.F1S1 = 10 and Game.F2S1 = 10 THEN 20 + Game.F3S1
WHEN Game.F1S1 = 10 and Game.F2S1 < 10 THEN 10 + Game.F2S1 + Game.F2S2
WHEN Game.F1S1 + Game.F1S2 = 10 THEN 10 + Game.F2S1
ELSE Game.F1S1 + Game.F1S2
END
+
CASE WHEN Game.F2S1 = 10 and Game.F3S1 = 10 THEN 20 + Game.F4S1
WHEN Game.F2S1 = 10 and Game.F3S1 < 10 THEN 10 + Game.F3S1 + Game.F3S2
WHEN Game.F2S1 + Game.F2S2 = 10 THEN 10 + Game.F3S1
ELSE Game.F2S1 + Game.F2S2
END
+
CASE WHEN Game.F3S1 = 10 and Game.F4S1 = 10 THEN 20 + Game.F5S1
WHEN Game.F3S1 = 10 and Game.F4S1 < 10 THEN 10 + Game.F4S1 + Game.F4S2
WHEN Game.F3S1 + Game.F3S2 = 10 THEN 10 + Game.F4S1
ELSE Game.F3S1 + Game.F3S2
END
+
CASE WHEN Game.F4S1 = 10 and Game.F5S1 = 10 THEN 20 + Game.F6S1
WHEN Game.F4S1 = 10 and Game.F5S1 < 10 THEN 10 + Game.F5S1 + Game.F5S2
WHEN Game.F4S1 + Game.F4S2 = 10 THEN 10 + Game.F5S1
ELSE Game.F4S1 + Game.F4S2
END
+
CASE WHEN Game.F5S1 = 10 and Game.F6S1 = 10 THEN 20 + Game.F7S1
WHEN Game.F5S1 = 10 and Game.F6S1 < 10 THEN 10 + Game.F6S1 + Game.F6S2
WHEN Game.F5S1 + Game.F5S2 = 10 THEN 10 + Game.F6S1
ELSE Game.F5S1 + Game.F5S2
END
+
CASE WHEN Game.F6S1 = 10 and Game.F7S1 = 10 THEN 20 + Game.F8S1
WHEN Game.F6S1 = 10 and Game.F7S1 < 10 THEN 10 + Game.F7S1 + Game.F7S2
WHEN Game.F6S1 + Game.F6S2 = 10 THEN 10 + Game.F7S1
ELSE Game.F6S1 + Game.F6S2
END
+
CASE WHEN Game.F7S1 = 10 and Game.F8S1 = 10 THEN 20 + Game.F9S1
WHEN Game.F7S1 = 10 and Game.F8S1 < 10 THEN 10 + Game.F8S1 + Game.F8S2
WHEN Game.F7S1 + Game.F7S2 = 10 THEN 10 + Game.F8S1
ELSE Game.F7S1 + Game.F7S2
END
+
CASE WHEN Game.F8S1 = 10 and Game.F9S1 = 10 THEN 20 + Game.F10S1
WHEN Game.F8S1 = 10 and Game.F9S1 < 10 THEN 10 + Game.F9S1 + Game.F9S2
WHEN Game.F8S1 + Game.F8S2 = 10 THEN 10 + Game.F9S1
ELSE Game.F8S1 + Game.F8S2
END
+
CASE WHEN Game.F9S1 = 10 and Game.F10S1 = 10 THEN 20 + Game.F10S2
WHEN Game.F9S1 = 10 and Game.F10S1 < 10 THEN 10 + Game.F10S1 + Game.F10S2
WHEN Game.F9S1 + Game.F9S2 = 10 THEN 10 + Game.F10S1
ELSE Game.F9S1 + Game.F9S2
END
+
CASE WHEN Game.F10S1 = 10 and Game.F10S2 = 10 THEN 20 + Game.F10S3
WHEN Game.F10S1 = 10 and Game.F10S2 < 10 THEN 10 + Game.F10S2 + Game.F10S3
WHEN Game.F10S1 + Game.F10S2 = 10 THEN 10 + Game.F10S3
ELSE Game.F10S1 + Game.F10S2
END
AS GameScore
FROM
(
SELECT
TR.intGameID
,SUM( CASE WHEN TR.intRollIndex = 1 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F1S1
,SUM( CASE WHEN TR.intRollIndex = 1 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F1S2
,SUM( CASE WHEN TR.intRollIndex = 2 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F2S1
,SUM( CASE WHEN TR.intRollIndex = 2 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F2S2
,SUM( CASE WHEN TR.intRollIndex = 3 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F3S1
,SUM( CASE WHEN TR.intRollIndex = 3 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F3S2
,SUM( CASE WHEN TR.intRollIndex = 4 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F4S1
,SUM( CASE WHEN TR.intRollIndex = 4 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F4S2
,SUM( CASE WHEN TR.intRollIndex = 5 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F5S1
,SUM( CASE WHEN TR.intRollIndex = 5 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F5S2
,SUM( CASE WHEN TR.intRollIndex = 6 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F6S1
,SUM( CASE WHEN TR.intRollIndex = 6 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F6S2
,SUM( CASE WHEN TR.intRollIndex = 7 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F7S1
,SUM( CASE WHEN TR.intRollIndex = 7 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F7S2
,SUM( CASE WHEN TR.intRollIndex = 8 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F8S1
,SUM( CASE WHEN TR.intRollIndex = 8 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F8S2
,SUM( CASE WHEN TR.intRollIndex = 9 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F9S1
,SUM( CASE WHEN TR.intRollIndex = 9 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F9S2
,SUM( CASE WHEN TR.intRollIndex = 10 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F10S1
,SUM( CASE WHEN TR.intRollIndex = 10 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F10S2
,SUM( CASE WHEN TR.intRollIndex = 10 and TR.intRollNumberIndex = 3 THEN TR.intNumberOfPins ELSE 0 END ) F10S3
FROM
TRolls AS TR
GROUP BY
TR.intGameID ) AS Game )
FROM
TPlayers AS TP
,TGames AS TG
,TRolls AS TR
WHERE
TP.intPlayerID = TG.intPlayerID
AND TG.intGameID = TR.intGameID
AND TP.intPlayerID = 21
It's a bit difficult to debug without the table designs but from what I see in your query, there may be a few issues (again, depending on your table design).
Your inner subquery does not have a Where Statement. Therefore, it
will bring all games in TRolls table, grouped by intGameID; It will
return multiple games; this is probably the issue as the "Game"
subquery is used in a SELECT statement, so it should return only one row;
you may need to add a WHERE clause to your subquery, and
maybe another join, depending on your table structure and their
relationships. If you really need to get the score for each game
(meaning, you don't know the gameID yet) you need to do that in the
FROM statement (not in the select statement as you are) like this
SELECT
TP.intPlayerID
,TP.strLastName + ', ' + TP.strFirstName AS strPlayerName
,TG.*
,TR.intGameID
,Game.Gamescore
FROM
TPlayers AS TP
,TGames AS TG
,TRolls AS TR
, (Select ... ...
) As Game
WHERE ...
From your question I understand in a Game you have multiple Players.
You are filtering just "PlayerID = 21" so you are adding all the
scores from all games for that player - is that what you really want?
Or are you missing another condition to filter a specific game?
You mentioned you are not familiar with subqueries, so here's a quick rule of thumb:
If used in the Select Statement (like yours) a subquery can only
return one row. Always.
If used in the From Statement (like my example) it brings you a
virtual "temp table" with multiple rows, you enclose it in
parenthesis and use an Alias to identify it; then you join it with
other tables in your From Statement using its given Alias.
If used in the Where Statement it should return a boolean value (true
or false), and a common example of that would be verifying whether or
not an information exists somewhere, like this:
WHERE EXISTS (SELECT 'X' from .... Where ....)