CASE Statement in query - sql

I am trying to return a bunch of values in a table without causing "duplicate" outputs. I thought a CASE statement or derived table may help? Any input would be great.
Within the column Product_code there are the following values
(AFF,E,H,PD,PDM,PDRL,PDRM etc)
Here is my SQL:
SELECT DISTINCT
[Member Id] = c.master_customer_id,
[Full Name] = c.label_name,
[First Name] = c.first_name,
[Last Name] = c.last_name,
[Email] = ISNULL(c.primary_email_address,''),
[Annual Meeting] = MAX(ca.product_code)
CASE WHEN od.product_code IN (AFF,E,H,PD,PDM,PDRL,PDRM) then ??
--[Membership Type] = od.product_code
FROM order_detail od
INNER JOIN customer c
on c.master_customer_id = od.ship_master_customer_id
and c.sub_customer_id = od.ship_sub_customer_id
and od.subsystem = 'MBR'
INNER JOIN cus_activity ca
on ca.master_customer_id = c.master_customer_id
and ca.sub_customer_id = c.sub_customer_id
and ca.subsystem = 'MTG'
and ca.activity_subcode IN ('2012AM', '2011AM')
and ca.product_code IN ('2012AM','2011AM')
INNER JOIN cus_address caddr
on caddr.master_customer_id = c.master_customer_id
and caddr.sub_customer_id = c.sub_customer_id
INNER JOIN cus_address_detail caddrd
on caddrd.cus_address_id = caddr.cus_address_id
where c.customer_class_code NOT IN ('STAFF', 'TEST_MBR')
and c.customer_status_code = 'ACTIVE'
and c.primary_email_address IS NOT NULL
and ca.master_customer_id IN (select order_detail.ship_master_customer_id
from order_detail where order_detail.subsystem = 'MBR')
and caddrd.priority_seq = 0
and caddrd.address_status_code = 'GOOD'
and od.product_code in
( 'AFF','E','H', 'PD','PDM','PDRL','PDRM','PDRU','R',
'RM','RRL','RRM','RRU','S','SM','SRL','SRM','SRU','SU','SUM','SURL','SURM','SURU' )
and od.cycle_end_date >= '01/01/2011' and od.cycle_end_date <= '12/31/2012'
GROUP BY c.master_customer_id,c.label_name,
c.FIRST_NAME,c.LAST_NAME,c.primary_email_address,od.product_code,caddr.country_descr
order by c.master_customer_id

You are looking for a Cross-Tab result (also known as a Pivot table) based on a given customer. You want all possible membership status levels as a person could be multiple levels (per your example).
With the group by on the customer ID, everything will roll-up to the member. So, if there are multiple product codes, I have applied SUM() based on each individual "product_code" you wanted to consider.
Next, to help optimize your query, I would ensure your Order_Detail has an index on
( SubSystem, Product_Code, Cycle_End_Date, ship_master_customer_id )
I've slightly rewritten to better allow myself to follow what you were getting and the criteria related to each table. Hopefully it makes sense to what you started with.
SELECT
c.master_customer_id as [Member Id],
c.label_name as [Full Name],
c.first_name as [First Name],
c.last_name as [Last Name],
ISNULL(c.primary_email_address,'') as [Email],
MAX(ca.product_code) as [Annual Meeting],
SUM( CASE WHEN od.product_code = 'AFF' then 1 else 0 end ) as Membership_AFF,
SUM( CASE WHEN od.product_code = 'E' then 1 else 0 end ) as Membership_E,
SUM( CASE WHEN od.product_code = 'H' then 1 else 0 end ) as Membership_H,
SUM( CASE WHEN od.product_code = 'PD' then 1 else 0 end ) as Membership_PD,
SUM( CASE WHEN od.product_code = 'PDM' then 1 else 0 end ) as Membership_PDM,
SUM( CASE WHEN od.product_code = 'PDRL' then 1 else 0 end ) as Membership_PDRL,
SUM( CASE WHEN od.product_code = 'PDRM' then 1 else 0 end ) as Membership_PDRM
FROM
order_detail od
INNER JOIN customer c
on od.ship_master_customer_id = c.master_customer_id
and od.ship_sub_customer_id = c.sub_customer_id
and c.customer_class_code NOT IN ('STAFF', 'TEST_MBR')
and c.customer_status_code = 'ACTIVE'
and c.primary_email_address IS NOT NULL
INNER JOIN cus_activity ca
on od.ship_master_customer_id = ca.master_customer_id
and od.ship_sub_customer_id = ca.sub_customer_id
and ca.subsystem = 'MTG'
and ca.activity_subcode IN ('2012AM', '2011AM')
and ca.product_code IN ('2012AM','2011AM')
INNER JOIN cus_address caddr
on od.ship_master_customer_id = caddr.master_customer_id
and od.ship_sub_customer_id = caddr.sub_customer_id
INNER JOIN cus_address_detail caddrd
on caddr.cus_address_id = caddrd.cus_address_id
and caddrd.priority_seq = 0
and caddrd.address_status_code = 'GOOD'
WHERE
od.subsystem = 'MBR'
and od.product_code in ( 'AFF','E','H','PD','PDM','PDRL','PDRM','PDRU',
'R','RM','RRL','RRM','RRU','S','SM','SRL',
'SRM','SRU','SU','SUM','SURL','SURM','SURU' )
and od.cycle_end_date >= '01/01/2011'
and od.cycle_end_date <= '12/31/2012'
GROUP BY
od.ship_master_customer_id,
c.label_name,
c.FIRST_NAME,
c.LAST_NAME,
c.primary_email_address,
caddr.country_descr
order by
od.ship_master_customer_id

Related

CASE statement in the ORDER BY CLAUSE

SQL SERVER
I'm attempting to sort records in my ORDER BY clause in an exact manner. So the records should be sorted in the following manner. I think my issue might be the CASE STATEMENT syntax, but I can't seem to find anything telling me that it's wrong, other than the code not running.
od.Status
Firm,
In Process,
Released,
Everything Else
I believed I could assign each type of record a number, and then sort those numbers.
The code below gives me "ORDER BY items must appear in the select list if SELECT DISTINCT is specified"
SELECT DISTINCT
oh.Order_Number AS Order_Number,
oh.Status AS Order_Status,
oh.Customer_Name AS Customer_Name,
vsc.Salesman_Name AS Salesman_Name,
vsc.Email_Address AS Email_Address,
od.Work_Code AS Work_Code,
od.Product_Code AS Product_Code,
CONVERT(char(10),od.Projected_Ship_Date,101) AS Projected_Ship_Date,
CONVERT(char(10),od.Due_Date,101) AS OD_Due_Date,
format(oh.Gross_Amount, '$#,##0.##') AS Gross_Amount,
DATEDIFF(DAY,oh.Order_Date,'{%Current Date%}') AS DIP,
od.Part_Number AS Part_Number,
od.Status AS Status,
CAST(qd.Delivery_Notes AS NVARCHAR(MAX)) AS Delivery_Notes
FROM
dbo.Order_Header oh LEFT OUTER JOIN dbo.Commission_Distribution cd ON oh.Order_Header_ID = cd.Order_Header_ID LEFT OUTER JOIN
dbo.vSalesman_Code vsc ON cd.Salesman_Code = vsc.Salesman_Code JOIN
dbo.Order_Detail od ON od.Order_Header_ID = oh.Order_Header_ID JOIN
dbo.Quotation_Detail qd ON od.Quotation_Detail_ID = qd.Quotation_Detail_ID JOIN
dbo.Quotation_Header qh ON qd.Quotation_Header_ID = qh.Quotation_Header_ID
WHERE
oh.Status = 'Open' AND
cd.Company_Code = 'AIN' AND
oh.Customer_Name NOT IN ( 'A.I. Innovations' , 'AI PROPERTIES Fortville LLC' , 'AI-IN Intercompany' , 'AI-NC Intercompany' ) AND
od.Status <> 'Closed' AND
LEFT(od.Part_Number, 3) <> 'MTS' AND
vsc.Salesman_Name NOT IN ( 'House' , 'House Accounts' ) AND
od.Status <> 'Hold' AND
od.Product_Code NOT LIKE '%PROCES%' AND
od.Product_Code NOT LIKE '%VISTA WARRANT%'
ORDER BY
CASE
WHEN od.Status = 'Firm' THEN 1
WHEN od.Status = 'In Process' THEN 2
WHEN od.Status = 'Released' THEN 3
ELSE 4
END,
vsc.Email_Address ASC,
CONVERT(char(10),od.Projected_Ship_Date,101) ASC
Any help on this would be appreciated. I haven't been able to find very much on this issue. Most issues I've found want to sort one set DESC, and another set ASC, but not in a particular order.
Thanks
Just updated your query:
SELECT DISTINCT
oh.Order_Number AS Order_Number,
oh.Status AS Order_Status,
oh.Customer_Name AS Customer_Name,
vsc.Salesman_Name AS Salesman_Name,
vsc.Email_Address AS Email_Address,
od.Work_Code AS Work_Code,
od.Product_Code AS Product_Code,
CONVERT(char(10),od.Projected_Ship_Date,101) AS Projected_Ship_Date,
CONVERT(char(10),od.Due_Date,101) AS OD_Due_Date,
format(oh.Gross_Amount, '$#,##0.##') AS Gross_Amount,
DATEDIFF(DAY,oh.Order_Date,'{%Current Date%}') AS DIP,
od.Part_Number AS Part_Number,
od.Status AS Status,
CAST(qd.Delivery_Notes AS NVARCHAR(MAX)) AS Delivery_Notes,
CASE
WHEN od.Status = 'Firm' THEN 1
WHEN od.Status = 'In Process' THEN 2
WHEN od.Status = 'Released' THEN 3
ELSE 4
END As StatusOrderId
FROM
dbo.Order_Header oh LEFT OUTER JOIN dbo.Commission_Distribution cd ON
oh.Order_Header_ID = cd.Order_Header_ID LEFT OUTER JOIN
dbo.vSalesman_Code vsc ON cd.Salesman_Code = vsc.Salesman_Code JOIN
dbo.Order_Detail od ON od.Order_Header_ID = oh.Order_Header_ID JOIN
dbo.Quotation_Detail qd ON od.Quotation_Detail_ID = qd.Quotation_Detail_ID JOIN
dbo.Quotation_Header qh ON qd.Quotation_Header_ID = qh.Quotation_Header_ID
WHERE
oh.Status = 'Open' AND
cd.Company_Code = 'AIN' AND
oh.Customer_Name NOT IN ( 'A.I. Innovations' , 'AI PROPERTIES Fortville LLC' , 'AI-IN Intercompany' , 'AI-NC Intercompany' ) AND
od.Status <> 'Closed' AND
LEFT(od.Part_Number, 3) <> 'MTS' AND
vsc.Salesman_Name NOT IN ( 'House' , 'House Accounts' ) AND
od.Status <> 'Hold' AND
od.Product_Code NOT LIKE '%PROCES%' AND
od.Product_Code NOT LIKE '%VISTA WARRANT%'
ORDER BY
CASE
WHEN od.Status = 'Firm' THEN 1
WHEN od.Status = 'In Process' THEN 2
WHEN od.Status = 'Released' THEN 3
ELSE 4
END,
vsc.Email_Address ASC,
CONVERT(char(10),od.Projected_Ship_Date,101) ASC
The problem is that the "case" statement in your order by must actually appear as a column in the select statement because you are doing a select distinct. Here is an example, the first query is invalid, the second works
select distinct
tableName = t.name
from sys.tables t
order by case
when t.name like '%something%' then 1
else 2
end;
select distinct
orderingColumn = case
when t.name like '%something%' then 1
else 2
end,
tableName = t.name
from sys.tables t
order by case
when t.name like '%something%' then 1
else 2
end
The problem here is that the orderingColumn will be returned by the select statement, and it seems like you don't want that, but that's easily fixed by a CTE or subquery:
with MyQuery as
(
select distinct
orderingColumn = case
when t.name like '%something%' then 1
else 2
end,
tableName = t.name
from sys.tables t
)
select tableName from MyQuery order by orderingColumn;

Adding an additional Inner join with mutiple tables SQL

I'm wondering how to inner join customer name-(CUSTNAM) from table rm001 to this query & have it added to my SSRS Report. Could use help adding this. Thanks
I've tried adding after the "from" saleslineitems as an "and" but it broke the SSRS report.
use n
select distinct a.[SOP Number]
--, [Item Number]
, a.[Customer Number], a.[Created Date from Sales Transaction], a.[Primary Shipto Address Code from Sales Line Item]
, a.[City from Sales Transaction],
,c.city
,case
when b.CITY <> c.city then 'Cities Do Not Match'
when c.city = '' then 'Cities do not Match'
when isnull(c.city,'1') = '1' then 'Cities Do Not Match'
else ''
end as [validate cities]
,b.USERDEF1 as GP_F
, c.f_number as EZ_F
,case
when b.USERDEF1 <> c.f_number then 'Fs do not Match'
when b.USERDEF1 = '' then 'No F in GP'
else ''
end as [validate Fs]
, c.f_expiration
,case
when c.f_expiration <= getdate() then ' F EXPIRED '
when c.f_expiration <= DATEADD(d,15,getDate()) then 'F expiring soon'
--when c.f_expiration >= dateAdd(d,61,getdate()) then 'valid F Expiration'
else ''
end as [valid f date]
--,( select top(1) c.f_number from NBS_BoundBook..contacts where c.f_number = b.userdef1 order by c.uid desc )
--, a.*
from SalesLineItems a
inner join rm00102 b on a.[customer number] = b.CUSTNMBR and a.[Primary Shipto Address Code from Sales Line Item] = b.ADRSCODE
left join NBS_BoundBook..contacts c on Replace(Replace(ltrim(rtrim(b.USERDEF1)),CHAR(10),''),CHAR(13),'') =
( select top(1) Replace(Replace(ltrim(rtrim(c.f_number)),CHAR(10),''),CHAR(13),'') from NBS_BoundBook..contacts
where Replace(Replace(ltrim(rtrim(c.f_number)),CHAR(10),''),CHAR(13),'') = Replace(Replace(ltrim(rtrim(b.USERDEF1)),CHAR(10),''),CHAR(13),'')
and c.city= b.CITY order by c.uid desc )
where [sop type] = 'Order'
and [Created Date from Sales Transaction] >= dateAdd(d,-3, getDate())
and [Item Tracking Option] in ( 'Serial Numbers' )
order by a.[Customer Number]
Something like this should work:
.....
FROM SalesLineItems a
INNER JOIN rm00102 b
ON a.[customer number] = b.CUSTNMBR
AND a.[Primary Shipto Address Code from Sales Line Item] = b.ADRSCODE
INNER JOIN rm001 cust
ON cust.[customer number] = a.[customer number]
LEFT JOIN NBS_BoundBook..contacts c
....

Query takes too long if i include a column in select statement

Below is the query which i need to optimize:
DECLARE #Power VARCHAR(10), #Button VARCHAR(10), #Casing VARCHAR(10), #Screen VARCHAR(10)
SELECT #Power = ActivityId FROM t_Activity WHERE ActivityName = 'PhonePowersUp?'
SELECT #Button = ActivityId FROM t_Activity WHERE ActivityName = 'T/S and Buttons functioning OK?'
SELECT #Casing = ActivityId FROM t_Activity WHERE ActivityName = 'Casing - no major defects?'
SELECT #Screen = ActivityId FROM t_Activity WHERE ActivityName = 'LCD works OK?'
SELECT
HQ.HandsetQuoteId [HandsetQuoteId], SS.Name [quote_status], HQ.QuoteDate [Quote Date], INS.DateInspected [DateInspected], PA.IMEI [IMEI_Quoted],
PA1.IMEI [IMEI_Inspected], INS.Grade [Grade], PB.PackageBoxName [PackageBoxName], CC.Name [ContactChannel], PhnBrd.Name [Brand], PM.ModelName [ModelQuoted],
PM1.ModelName [ModelInspected], U.FirstName [FirstName], U.Surname [Surname], U.Username [Username], UW.WarehouseId [WarehouseId], W.Name [Warehouse Name],
HQA.Value [Original Quote Value], HQ.QuoteValue [Quote Value], INS.InspectionValue [InspectionValue], HQ.AgreedValue [Agreed Value], CUS.FirstName [Store Name],
DATEDIFF(DAY, HQ.QuoteDate, GETDATE()) [Quote Age],
[ST_POWER] = CASE WHEN (CHARINDEX(','+ #Power +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Power +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
[ST_BUTTONS] = CASE WHEN (CHARINDEX(','+ #Button +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Button +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
[ST_CASING] = CASE WHEN (CHARINDEX(','+ #Casing +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Casing +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
[ST_Screen] = CASE WHEN (CHARINDEX(','+ #Screen +',', ','+PAR.Ok+',') > 0) THEN 'YES' WHEN (CHARINDEX(','+ #Screen +',', ','+PAR.Fault+',') > 0) THEN 'NO' ELSE NULL END,
st_deduct = PAR.PercentageDeduction, wt_deduct = MAX(APD.PercentageDeduction)
FROM t_Inspection AS INS
INNER JOIN t_HandsetQuote HQ ON HQ.HandsetQuoteId = INS.HandsetQuoteId
INNER JOIN t_QuoteHeader QH ON QH.QuoteHeaderId = HQ.QuoteHeaderId
INNER JOIN t_Customer CUS ON CUS.CustomerId = QH.CustomerId
INNER JOIN t_ContactChannel CC ON CC.ContactChannelId = CUS.ContactChannelId
INNER JOIN t_PackageBoxHandset PBH ON PBH.HandsetQuoteId = HQ.HandsetQuoteId
INNER JOIN t_PackageBox PB ON PB.PackageBoxId = PBH.PackageBoxId
INNER JOIN t_StockStatus SS ON SS.StockStatusId = HQ.StockStatusId
INNER JOIN t_PhoneAudit PA ON PA.PhoneAuditId = HQ.QuotePhoneAuditId
INNER JOIN t_PhoneModel PM ON PM.PhoneModelId = PA.PhoneModelId AND PA.PhoneAuditId = HQ.QuotePhoneAuditId
INNER JOIN t_PhoneBrand PhnBrd ON PM.PhoneBrandId = PhnBrd.PhoneBrandId
INNER JOIN t_PhoneAudit PA1 ON PA1.PhoneAuditId = HQ.InspectionPhoneAuditId
INNER JOIN t_PhoneModel PM1 ON PM1.PhoneModelId = PA1.PhoneModelId AND PA1.PhoneAuditId = HQ.InspectionPhoneAuditId
INNER JOIN t_PhoneBrand PhnBrd1 ON PM1.PhoneBrandId = PhnBrd1.PhoneBrandId
INNER JOIN t_User U ON INS.InspectorId = U.UserId
INNER JOIN t_UserWarehouse UW ON U.UserId = UW.UserId
INNER JOIN t_Warehouse W ON UW.WarehouseId = W.WarehouseId
LEFT JOIN t_HandsetQuoteAdditionalInfo HQA ON HQ.HandsetQuoteId = HQA.HandsetQuoteId AND HQA.KeyName = 'OriginalQuoteValue'
LEFT JOIN t_PhoneAuditRetail PAR ON PAR.HandsetQuoteId = HQ.HandsetQuoteId
LEFT JOIN t_HandsetQuoteActivity HQA1 ON HQA1.HandsetQuoteId = HQ.HandsetQuoteId AND HQA1.ActivityTestOK = 0 AND HQA1.ActivityStartTime = (
CASE
WHEN ((SELECT Count(1) FROM t_HandsetQuoteActivity WHERE HandsetQuoteId = HQA1.HandsetQuoteId AND ActivityStartTime <= QH.Cache_QuoteAcceptedDate AND ActivityId = HQA1.ActivityId) > 0)
THEN (SELECT Max(ActivityStartTime) FROM t_HandsetQuoteActivity WHERE HandsetQuoteId = HQA1.HandsetQuoteId AND ActivityStartTime <= QH.Cache_QuoteAcceptedDate AND ActivityId = HQA1.ActivityId GROUP BY HandsetQuoteId, ActivityId)
ELSE
(SELECT Min(ActivityStartTime) FROM t_HandsetQuoteActivity WHERE HandsetQuoteId = HQA1.HandsetQuoteId AND ActivityStartTime >= QH.Cache_QuoteAcceptedDate AND ActivityId = HQA1.ActivityId GROUP BY HandsetQuoteId, ActivityId)
END)
LEFT JOIN t_Activity_PercentageDeduction APD ON APD.ActivityId = HQA1.ActivityId AND APD.ContactChannelId = CUS.ContactChannelId AND APD.ContactChannelId = CC.ContactChannelId
WHERE Ins.DateInspected > GETDATE()-90
GROUP BY HQ.HandsetQuoteId, SS.Name, QH.CreatedDate, INS.DateInspected, PA.IMEI, PA1.IMEI, INS.Grade, PB.PackageBoxName, CC.Name, PhnBrd.Name, PM.ModelName, PM1.ModelName,
U.FirstName, U.Surname, U.Username, UW.WarehouseId, W.Name, HQA.Value, HQ.QuoteValue, INS.InspectionValue, HQ.AgreedValue, CUS.Firstname, HQ.QuoteDate, PAR.Ok, PAR.Fault,
PAR.PercentageDeduction
And, after properly debugging it, I came to know that when i remove wt_deduct = MAX(APD.PercentageDeduction) from the select list, the query executes with in less than a minute.
But, however i am not able to figure it out, that whats wrong with the column APD.PercentageDeduction, because when i include it in the select list, my query stucks and becomes too slow and takes 15 minutes to run and excluding it from the select list makes the query to run with in 30 seconds.
Additional Information:
Table -> t_Activity_PercentageDeduction contains only 400 records, column PercentageDeduction is of Decimal datatype.
Please let me know if you want some other information too.
If Im not mistaken you are only joining to that table in order to get that MAX value, and by adding this Max value, you are also having to do all the grouping. So there is actually quite a difference in the queries.
I would suggest using a co-related sub-query to get this piece of data.
remove the left join
LEFT JOIN t_Activity_PercentageDeduction APD ON APD.ActivityId = HQA1.ActivityId AND APD.ContactChannelId = CUS.ContactChannelId AND APD.ContactChannelId = CC.ContactChannelId
and set wt_deduct = to the new co-related sub-query
wt_deduct = (select MAX(PercentageDeduction) from t_Activity_PercentageDeduction
where ActivityId = HQA1.ActivityId
AND ContactChannelId = CUS.ContactChannelId
AND ContactChannelId = CC.ContactChannelId)
And you can remove all the grouping that is no longer required too.

SQL combining multiple select statements into a single query

I have the following query which gets the total outstanding invoices and removed the total payments and credit notes to get the outstanding balance.
declare #tInv decimal(19, 2)
declare #tCrn decimal(19, 2)
declare #tPay decimal(19, 2)
set #tInv =
(
SELECT SUM(ST_Unallocated) from Transactions where ST_COPYCUST = 'LOEH001' and ST_TRANTYPE = 'INV'
)
set #tCrn =
(
SELECT SUM(ST_Unallocated) from Transactions where ST_COPYCUST = 'LOEH001' and ST_TRANTYPE = 'CRN'
)
set #tPay =
(
SELECT SUM(ST_Unallocated) from Transactions where ST_COPYCUST = 'LOEH001' and ST_TRANTYPE = 'PAY'
)
declare #currBal decimal(19, 2)
set #currBal =
(
SELECT #tInv - #tPay - #tCrn
)
select #currBal
I want to combine the above query with the below query to show the total outstanding balance for each customer -
select
c.AccountNumber,
c.CustomerID,
c.FullName,
ct.Description as 'CustomerTypeDesc',
c.TelNumber,
c.EmailAddress
from Customers c
inner join CustomerTypes ct on c.CustomerType = ct.TypeID
left join Transactions t on c.AccountNumber = ST_COPYCUST
where c.StatusID = 0 or c.StatusID = 1
Any ideas how I can do this?
Thanks
Try the following query. I have made a few assumptions and have removed the join on the Transactions table from your primary query as I think this is surplus to requirements. The beauty of using these inline queries is that you can return more than one customer if required (by removing the filter on c.AccountNumber):
SELECT
c.AccountNumber
, c.CustomerID
, c.FullName
, ct.Description as 'CustomerTypeDesc'
, c.TelNumber
, c.EmailAddress
, (SELECT SUM(ST_Unallocated) from Transactions where ST_COPYCUST = c.AccountNumber and ST_TRANTYPE = 'INV') -
(SELECT SUM(ST_Unallocated) from Transactions where ST_COPYCUST = c.AccountNumber and ST_TRANTYPE = 'CRN') -
(SELECT SUM(ST_Unallocated) from Transactions where ST_COPYCUST = c.AccountNumber and ST_TRANTYPE = 'PAY') AS BalanceToPay
FROM Customers c
INNER JOIN CustomerTypes ct on c.CustomerType = ct.TypeID
WHERE c.StatusID IN (0,1) AND c.AccountNumber = ST_COPYCUST
Hope didn't broke it, should be faster than with subqueries:
SELECT
c.AccountNumber
, c.CustomerID
, c.FullName
, ct.Description as 'CustomerTypeDesc'
, c.TelNumber
, c.EmailAddress
, SUM(CASE WHEN ST_TRANTYPE = 'INV' THEN t.ST_Unallocated ELSE 0 END) AS tInv
, SUM(CASE WHEN ST_TRANTYPE = 'CRN' THEN t.ST_Unallocated ELSE 0 END) AS tCRN
, SUM(CASE WHEN ST_TRANTYPE = 'PAY' THEN t.ST_Unallocated ELSE 0 END) AS tPAY
, SUM(CASE WHEN ST_TRANTYPE = 'INV' THEN t.ST_Unallocated ELSE 0 END) -
SUM(CASE WHEN ST_TRANTYPE = 'PAY' THEN t.ST_Unallocated ELSE 0 END) -
SUM(CASE WHEN ST_TRANTYPE = 'CRN' THEN t.ST_Unallocated ELSE 0 END) as currBal
FROM Customers c
INNER JOIN CustomerTypes ct on c.CustomerType = ct.TypeID
LEFT JOIN Transactions t on c.AccountNumber = t.ST_COPYCUST
WHERE c.StatusID = 0 or c.StatusID = 1 AND c.AccountNumber = ST_COPYCUST
GROUP BY c.AccountNumber
, c.CustomerID
, c.FullName
, ct.Description
, c.TelNumber
, c.EmailAddress

SQL Pivot table for Blank data

following is my Query to generate the Pivoted result:
SELECT '# of Corrective Actions open and overdue' as [Corrective Actions breakdown],
[405],
[2865],
[3142],
[405]+[2865]+[3142] as [Total]
FROM
(Select il.Locationid , ca.CorrectiveActionsid, il.locOrder, ca.isDeleted caDeleted, i.isDeleted iDeleted, i.CompanyId companyid,ca.CADateBy, ca.Status from IncidentLocation il inner join incident i on il.IncidentId = i.IncidentId
inner join CorrectiveActions ca on i.IncidentId = ca.IncidentId
) AS SourceTable
PIVOT
(
COUNT(CorrectiveActionsid)
FOR LocationId IN ([405],[2865],[3142])
) PivotTable
where locOrder = 0 and caDeleted =0 and iDeleted = 0 and companyId = 210
and CADateBy <= '2013-01-01' and [Status] = 'Open'
I was thinking for blank data the count should return o. But I am getting no result at all. Please guide me what wrong I am doing and what should I do to get zero instead of blank for all the counted values.
looks like your query doesn't return any row, you can fix it like this (I've not fixed other parts of query, just want to show you a workaround):
select
A.[Corrective Actions breakdown],
coalesce([405], 0) as [405],
coalesce([2865], 0) as [2865],
coalesce([3142], 0) as [3142],
coalesce([405], 0) + coalesce([2865], 0) + coalesce([3142], 0) as [Total]
from (select '# of Corrective Actions open and overdue' as [Corrective Actions breakdown]) as A
outer apply (
SELECT
[405],
[2865],
[3142]
FROM
(Select il.Locationid , ISNULL(ca.CorrectiveActionsid, 0) AS CorrectiveActionsid, il.locOrder, ca.isDeleted caDeleted, i.isDeleted iDeleted, i.CompanyId companyid,ca.CADateBy, ca.Status from IncidentLocation il inner join incident i on il.IncidentId = i.IncidentId
inner join CorrectiveActions ca on i.IncidentId = ca.IncidentId
) AS SourceTable
PIVOT
(
COUNT(CorrectiveActionsid)
FOR LocationId IN ([405],[2865],[3142])
) PivotTable
where locOrder = 0 and caDeleted =0 and iDeleted = 0 and companyId = 210
and CADateBy <= '2013-01-01' and [Status] = 'Open'
) as p
I would expect the count() to return 0. If it doesn't, you can try using coalesce():
coalesce([405], 0) as [405]
In SQL Server COUNT will ignore NULL values. That being said, use an ISNULL function on the column you are going to aggregate.
SELECT '# of Corrective Actions open and overdue' as [Corrective Actions breakdown],
[405],
[2865],
[3142],
[405]+[2865]+[3142] as [Total]
FROM
(Select il.Locationid , ISNULL(ca.CorrectiveActionsid, 0) AS CorrectiveActionsid, il.locOrder, ca.isDeleted caDeleted, i.isDeleted iDeleted, i.CompanyId companyid,ca.CADateBy, ca.Status from IncidentLocation il inner join incident i on il.IncidentId = i.IncidentId
inner join CorrectiveActions ca on i.IncidentId = ca.IncidentId
) AS SourceTable
PIVOT
(
COUNT(CorrectiveActionsid)
FOR LocationId IN ([405],[2865],[3142])
) PivotTable
where locOrder = 0 and caDeleted =0 and iDeleted = 0 and companyId = 210
and CADateBy <= '2013-01-01' and [Status] = 'Open'