I'm trying to build code that will generate a file in a specific format. The code worked in its entirety until I added A.PrevYTDSales and A.YtdQtySold, so I'm not sure what's going on. It now gives me an error saying "error converting varchar to numeric" so I'm assuming I have a syntax error somewhere but I can't find where. Below is the code.
select
Inv.StockCode -- part
+ '|' + Inv.Description -- desc
+ '|' + isnull(
replace(
CONVERT(varchar,
CAST(
isnull(
case when 0 > (Inv.QOH - isnull(Sor.QOO,0)) then 0
else (Inv.QOH - isnull(Sor.QOO,0)) end
,0)
as Money)
, 1)
,'.00','')
,'0') -- QOH
+ '|' + replace(convert(varchar,cast(BoxQty as money),1),'.00','') -- box qty
+ '|' + YTDSales -- YTD Qty Sold
+ '|' + PrevYTDSales -- Prev YTD Qty Sold
+ '|' + convert(varchar,TRY_CAST(Mass as NUMERIC(19,4))) -- mass
+ '|' + isnull(convert(varchar,DueDt+3,101),' ') -- duedt
+ '|' +
case when isnull(convert(varchar,DueDt+3,101),' ') = ' ' then ' '
when 0 > (Inv.QOH - isnull(Sor.QOO,0)) then
isnull(
replace(
CONVERT(varchar,
CAST(
isnull(
case when 0 > (GitQty - isnull(Sor.QOOtoPOS,0)) then 0
else (GitQty - isnull(Sor.QOOtoPOS,0)) end
,0)
as Money)
, 1)
,'.00','')
,'0')
else
replace(convert(varchar,convert(money,GitQty),1),'.00','')
end -- QTY coming
+ '|' + COO -- COO
+ '|' + Tariff -- tariff
+ '|' + Location -- Customer
+ '|' + isnull(Cus.Customer,' ') -- customer
+ '|' + isnull(
replace(
replace(
Cus.CustStockCode
,Char(13),'')
,Char(10),'')
,' ') customer part
+ '|' + isnull(Cus.StockCode,' ')
+ '|' + 'R'
as partlist
from (
select
A.StockCode as StockCode
,B.Description as Description
,Sum(QtyOnHand) as QOH
,B.UserField2 as BoxQty
,A.YtdQtySold as YTDSales
,A.PrevYearQtySold as PrevYTDSales
,B.Mass as Mass
,B.ProductClass
,B.CountryOfOrigin as COO
,B.TariffCode as Tariff
,case
when Warehouse = '01' then 'All W/H'
when Warehouse = '02' then 'All W/H'
else ''
end as Location
from CompanyR.dbo.InvWarehouse A
left join CompanyR.dbo.InvMaster B on A.StockCode = B.StockCode
left join CompanyR.dbo.[InvMaster+] C on B.StockCode = C.StockCode
where Warehouse in ('01', '02')
and A.StockCode not like 'TEC%'
and B.StockCode is not null
group by A.StockCode , B.Description, B.UserField2, A.YtdQtySold, A.PrevYearQtySold, Mass, B.ProductClass
,B.CountryOfOrigin
,B.TariffCode
,case
when Warehouse = '01' then 'All W/H'
when Warehouse = '02' then 'All W/H'
else ''
end
) Inv
LEFT JOIN
(
select
sum(case
when (Getdate()+57) < MLineShipDate then 0
else (MOrderQty)
end
) as QOO,
sum(case
when ( MLineShipDate > isnull(DueDt, GetDate() ) )
AND
( MLineShipDate < isnull(POSDt, GetDate()+57) )
then MOrderQty
else 0
end
) as QOOtoPOS,
DueDt,
GitQty,
POSDt,
A.MStockCode as StockCode
from CompanyR.dbo.SorDetail A
left join CompanyR.dbo.SorMaster B on A.SalesOrder = B.SalesOrder
left join (
select StockCode
,(ExpectedDueDate) as DueDt
,SUM(GtrQuantity-QtyReceived) as GitQty
from CompanyR.dbo.GtrDetail A
where TransferComplete <> 'Y'
and CompanyR.dbo.get_week(ExpectedDueDate,0) >= CompanyR.dbo.get_week(GETDATE(),0)
and ExpectedDueDate = (select Min(ExpectedDueDate)
from CompanyR.dbo.GtrDetail B where TransferComplete <> 'Y' and A.StockCode = B.StockCode
and CompanyR.dbo.get_week(ExpectedDueDate,0) >= CompanyR.dbo.get_week(GETDATE(),0) )
group by StockCode, ExpectedDueDate
) GIT on A.MStockCode = GIT.StockCode
left join (
select
MStockCode
,min(MLatestDueDate) as POSDt
from CompanyR.dbo.PorMasterDetail
where MCompleteFlag <> 'Y'
and MLatestDueDate > getdate()
and MStockCode not like '-%'
and MStockCode not like '#%'
and MStockCode not like '*%'
group by MStockCode
) POS on A.MStockCode = POS.MStockCode
where 1=1
and A.MLineShipDate < dateadd(week,8,getdate())
and A.MLineShipDate >= DATEADD(s, -0,DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0))
and A.MStockCode not like '*%'
and A.MStockCode not like '-%'
and B.OrderStatus not in ('\','*','9')
group by A.MStockCode,DueDt,POSDt,GitQty
) Sor on Inv.StockCode = Sor.StockCode
LEFT JOIN CompanyR.dbo.ArCustStkXref Cus on Inv.StockCode = Cus.StockCode and Cus.Customer <> ''
It's supposed to output something like this
098-01-PK|#6 , 3MM DL WASHER 200 PAIR PK|0|0|1.0000| | |TWN|7318.22.0000|All W/H| | | |L
098-01-PK|#6 , 3MM DL WASHER 200 PAIR PK|0|0|1.0000| | |TWN|7318.22.0000|| | | |L
098-01|#6 , 3MM DL WASHER PAIR|0|3,000|1.0000| | |TWN|7318.22.0000|All W/H| | | |L
098-01|#6 , 3MM DL WASHER PAIR|0|3,000|1.0000| | |TWN|7318.22.0000|| | | |L
Anyone have any ideas where I could be having an issue?
Apparently the only conversion to numeric that you have is for the Mass, column.
Since you added the new columns into the group by, probably new rows would appear showing the Mass column with (maybe) a null or some new strange value.
Try running the query from the query inside the from clause by itself and then looking for distinct values for the Mass column and check if they all are numeric.
Hope it helps!
Related
I have the following (obfuscated) SQL running on SQL Server 2012 and need to significantly improve its performance. It works, but sometimes takes more than 60s to return.
I would like to extract the JOINS but this post seems to indicate that this will not be possible (because of things like MIN and MAX) - so how can improve the performance and get these joins simplified/improved?
SELECT
wm.id, wm.uid, wm.em, wm.fn, wm.ln, c, y, RTRIM(LTRIM(yCode)) AS yCode, wm.d1, ISNULL(wm.ffn, wm.pp) as ffn, wm.ada,
case
when wm.mss & 2=2
then 'false'
else 'true'
end AS isa,
(
SELECT ', '+RTRIM(p1.cKey)
FROM profile p1
inner join loc stl on p1.cKey=stl.cKey
WHERE p1.id = wm.id and p1.s = 'A'
FOR XML PATH('')
) [lst],
lishc.[lstCount],
TotalCount = COUNT(*) OVER(),
la.lsa, wskp.cKey AS pid
FROM wmm wm
LEFT JOIN profile p1 ON wm.id = p1.id
LEFT JOIN (
SELECT UA.id, CONVERT(datetime, UA.ins, 1) As lsa
FROM actlog UA
INNER JOIN (
select id, max(ins) as laa
from actlog
group by id
) UAJ on UA.id=UAJ.id and UA.ins=UAJ.laa
) la on la.id=wm.id
LEFT JOIN (
SELECT id, cKey FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY d1 desc) AS ROWNUM
FROM keypro where sc = 'SAP' AND cKeyDesc = 'SAP Agent ID'
) x WHERE ROWNUM = 1
) wskp ON wskp.id = wm.id
LEFT JOIN (
(SELECT p1.id ,COUNT(p1.cKey) AS [lstCount]
FROM profile p1
inner join loc stl on p1.cKey=stl.cKey
where p1.s = 'A'
GROUP BY p1.id)
) lishc ON lishc.id = wm.id
WHERE (#id = 0 OR wm.id = #id)
AND (#uid IS NULL OR wm.uid LIKE '%' + #uid + '%')
AND (#c IS NULL OR wm.c LIKE '%' + #c + '%')
AND (#fn IS NULL OR wm.fn LIKE '%' + #fn + '%')
AND (#ln IS NULL OR wm.ln LIKE '%' + #ln + '%')
AND (#em IS NULL OR wm.em LIKE '%' + #em + '%')
AND (#ffn IS NULL OR (wm.ffn LIKE '%' + #ffn + '%' OR wm.pp LIKE '%' + #ffn + '%'))
AND (#pid IS NULL OR wskp.cKey LIKE '%' + #pid + '%' )
AND (#Date1 IS NULL OR (CAST(wm.d1 AS DATE) BETWEEN CAST(#Date1 AS DATE) AND CAST(#Date2 AS DATE)))
AND (#lsa1 IS NULL OR (CAST(la.lsa AS DATE) BETWEEN CAST(#lsa1 AS DATE) AND CAST(#lsa2 AS DATE)))
AND (#Active IS NULL OR (wm.mss & 2 != 2))
AND (#Inactive IS NULL OR (wm.mss & 2 = 2))
AND (#External IS NULL OR (wm.ada = 'biz'))
AND (#Internal IS NULL OR (wm.ada <> 'biz'))
AND (#ApplyyFilter =0 OR (wm.yCode IN (SELECT #yCode WHERE 1 = 0)))
AND (#ApplylstFilter = 0 OR(p1.cKey IN (SELECT #ShipToList WHERE 1 = 0)))
AND (#ApplylstFilter = 0 OR(p1.s = 'A'))
AND (#ApplyNoFilter = 0 OR (lishc.[lstCount] is null))
AND (#lstCount = 0 OR lishc.[lstCount] = #lstCount)
AND (#ApplyLimitedFilter = 0 OR (wm.id IN (0)))
AND (#ApplyMoreFilter = 0 OR (wm.id IN (SELECT #idss WHERE 1 = 0)))
GROUP BY wm.id, wm.uid, wm.em, wm.fn, wm.ln, y, yCode,c,wm.d1,wm.ffn,wm.mss,wm.ada, la.lsa, wskp.cKey, lishc.[lstCount], wm.pp
ORDER BY lsa DESC
OFFSET #PageOffset ROWS FETCH NEXT #PageSize ROWS ONLY
The quick hit here is to add OPTION (RECOMPILE) so SQL Server can eliminate the predicates that correspond to null parameters and create a new plan for each search.
And see, generally Dynamic Search Conditions in T‑SQL
The next thing to do is to get rid of the wildcard searches wherever possible.
And transform this
(CAST(la.lsa AS DATE) BETWEEN CAST(#lsa1 AS DATE) AND CAST(#lsa2 AS DATE)))
into a SARGable pattern like
la.lsa >= #lsa1 and la.lsa < #lsa2
Then start to pull this query apart, and hand-write separate queries for the most common or critical cases.
iam using simple query i want year to get extracted and that should be used in table extraction
select *
from v_AuthListInfo LI
where title like '%SUG%'
and Title like '%P1%'
and Title like '%' + '' + year(getdate()) + '' + '%'
I am getting this error
Msg 245, Level 16, State 1, Line 26
Conversion failed when converting the varchar value '%' to data type int.
Ideally it should come 2018 and it should extract those records with 2018
and I want records minus 1 yr means 2017
so in all I want records of 2018 and 2017
but iam not able to get can you tell me where iam going wrong in concatenation
want to combine output of these two queries
select
count(*) [Total Clients], li.title,li.CI_UniqueID,coll.name,
SUM (CASE WHEN ucs.status=3 or ucs.status=1 then 1 ELSE 0 END ) as 'Installed / Not Applicable',
sum( case When ucs.status=2 Then 1 ELSE 0 END ) as 'Required',
sum( case When ucs.status=0 Then 1 ELSE 0 END ) as 'Unknown',
round((CAST(SUM (CASE WHEN ucs.status=3 or ucs.status=1 THEN 1 ELSE 0 END) as float)/count(*) )*100,2) as 'Compliant%',
round((CAST(count(case when ucs.status not in('3','1') THEN '*' end) as float)/count(*))*100,2) as 'NotCompliant%'
From v_Update_ComplianceStatusAll UCS
inner join v_r_system sys on ucs.resourceid=sys.resourceid
inner join v_FullCollectionMembership fcm on ucs.resourceid=fcm.resourceid
inner join v_collection coll on coll.collectionid=fcm.collectionid
inner join v_AuthListInfo LI on ucs.ci_id=li.ci_id
where coll.CollectionID='SMS00001' and
--title like '%SUG%'
Title like '%P1%'
and Title like '%SUG_' + '' + CAST(year(getdate()) as varchar) + '' + '%'
--and Title like '%SUG_' + '' + CAST(year(getdate())-1 as varchar) + '' + '%'
group by li.title,li.CI_UniqueID,coll.name
order by li.title ASC
select
count(*) [Total Clients], li.title,li.CI_UniqueID,coll.name,
SUM (CASE WHEN ucs.status=3 or ucs.status=1 then 1 ELSE 0 END ) as 'Installed / Not Applicable',
sum( case When ucs.status=2 Then 1 ELSE 0 END ) as 'Required',
sum( case When ucs.status=0 Then 1 ELSE 0 END ) as 'Unknown',
round((CAST(SUM (CASE WHEN ucs.status=3 or ucs.status=1 THEN 1 ELSE 0 END) as float)/count(*) )*100,2) as 'Compliant%',
round((CAST(count(case when ucs.status not in('3','1') THEN '*' end) as float)/count(*))*100,2) as 'NotCompliant%'
From v_Update_ComplianceStatusAll UCS
inner join v_r_system sys on ucs.resourceid=sys.resourceid
inner join v_FullCollectionMembership fcm on ucs.resourceid=fcm.resourceid
inner join v_collection coll on coll.collectionid=fcm.collectionid
inner join v_AuthListInfo LI on ucs.ci_id=li.ci_id
where coll.CollectionID='SMS00001' and
--title like '%SUG%'
Title like '%P1%'
-- Title like '%SUG_' + '' + CAST(year(getdate()) as varchar) + '' + '%'
and Title like '%SUG_' + '' + CAST(year(getdate())-1 as varchar) + '' + '%'
group by li.title,li.CI_UniqueID,coll.name
order by li.title ASC
Cast your year to varchar because year returns int value
select * from v_AuthListInfo LI
where title like '%SUG%'
and Title like '%P1%'
and Title like '%' + '' + CAST(year(getdate()) as varchar(4)) + '' + '%'
The problem is that year() returns a number, not a string. Because of this, SQL Server interprets the + as addition, rather than string concatenation.
SQL Server has a convenient function, datename(), that returns a string:
select *
from v_AuthListInfo LI
where title like '%SUG%' and
title like '%P1%' and
title like '%' + datename(year, getdate()) + '%';
The empty strings that you are concatenating in the like pattern are useless.
I have this output:
Contact_Type Category_Type Category_Count
---------------------------------------------------
Window Admissions 1775
Window Financial Aid 17377
Window Miscellaneous 2720
Window Student Financials 14039
Phone Admissions 5758
Phone Financial Aid 10048
Phone Miscellaneous 4497
Phone Registration 11
Phone Student Financials 4857
and this is my query:
SELECT
Contact_Type, Category_Type1, Category_Type2, Category_Type3,
Category_Type4, Category_Type5
FROM
(SELECT
CASE
WHEN event.contact_type = 0 THEN 'Window'
WHEN event.contact_type = 1 THEN 'Phone'
END AS Contact_Type,
cat.category_type AS Category_Type,
COUNT(ec.category_id) AS Category_Count,
'Category_Type' + CAST(ROW_NUMBER() OVER (PARTITION BY Contact_Type
ORDER BY Contact_Type) AS varchar(20)) AS ColumnSequence
FROM
yLines.ylines_event AS Event
JOIN
ylines.ylines_event_category AS ec ON ec.event_id = event.event_id
JOIN
ylines.ylines_category AS cat ON ec.category_id = cat.category_id
WHERE /*event.contact_type = '0' AND*/
CAST(FORMAT(event.event_date_time, 'yyyy') AS int) BETWEEN 2014 AND dateadd(year, 1, event.event_date_time)
GROUP BY
Category_Type, Contact_Type) a
PIVOT
(MAX(Contact_Type)
FOR ColumnSequence IN (Category_Type1, Category_Type2, Category_Type3,
Category_Type4, Category_Type5)) as piv;
If I run this it gives me an error:
Msg 207, Level 16, State 1, Line 1
Invalid column name 'Contact_Type'
and I can't seem to fix this. I am trying to transpose it so I see two rows only with 'Windows' and 'Phone' and the five Category Types transposed as five columns with the count in each. I am writing T-SQL statements. Please help!
I would try do it in dynamic
; WITH [CONTACT]
AS (
SELECT *
FROM (
VALUES
('Window', 'Admissions ', ' 1775')
, ('Window', 'Financial Aid ', '17377')
, ('Window', 'Miscellaneous ', ' 2720')
, ('Window', 'Student Financials', '14039')
, ('Phone ', 'Admissions ', ' 5758')
, ('Phone ', 'Financial Aid ', '10048')
, ('Phone ', 'Miscellaneous ', ' 4497')
, ('Phone ', 'Registration ', ' 11')
, ('Phone ', 'Student Financials', ' 4857')
) X ([Contact_Type], [Category_Type], [Category_Count])
)
SELECT *
INTO #TEMP_PIVOT
FROM [CONTACT]
DECLARE #TYPE VARCHAR(MAX)
SET #TYPE = STUFF(
(SELECT DISTINCT ', ' + QUOTENAME(RTRIM(LTRIM([CATEGORY_TYPE])))
FROM #TEMP_PIVOT
FOR XML PATH('')
)
, 1, 1, '')
DECLARE #SQL VARCHAR(MAX)
SET #SQL = ' SELECT [CONTACT_TYPE] '
+ ' , ' + #TYPE
+ ' FROM #TEMP_PIVOT '
+ ' PIVOT ( '
+ ' MAX([CATEGORY_COUNT]) '
+ ' FOR [CATEGORY_TYPE] IN (' + #TYPE + ')'
+ ' ) P '
EXECUTE (#SQL)
In the group by clause you say
`group by Category_Type, Contact_Type`
However, you have defined a calculated column as contact_type which is not available in the group by clause. You should use
GROUP BY Category_Type, -- Contact_Type
case
when event.contact_type=0 then 'Window'
when event.contact_type=1 then 'Phone'
end
It is a better approach to name your calculated columns different than the columns in any of your tables.
Use case statements for pivoting:
SELECT CONTACT_TYPE,
SUM(CASE WHEN CATEGORY_TYPE='Admissions' THEN CATEGORY_COUNT END) ADMISSIONS,
SUM(CASE WHEN CATEGORY_TYPE='Financial Aid' THEN CATEGORY_COUNT END) FINANCIAL_AID,
SUM(CASE WHEN CATEGORY_TYPE='Miscellaneous' THEN CATEGORY_COUNT END) MISCELLANEOUS,
SUM(CASE WHEN CATEGORY_TYPE='Student Financials' THEN CATEGORY_COUNT END) STUDENT_FINANCIALS,
SUM(CASE WHEN CATEGORY_TYPE='Registration' THEN CATEGORY_COUNT END) REGISTRATION
FROM TEST_3 GROUP BY CONTACT_TYPE;
Output:
CONTACT_TYPE ADMISSIONS FINANCIAL_AID MISCELLANEOUS STUDENT_FINANCIALS REGISTRATION
Phone 5758 10048 4497 4857 11
Window 1775 17377 2720 14039 null
I am having some trouble . I have been writing a SQL query that fetches 5 columns from 2 tables. In a simple join, the column named CustomerCode is displayed correctly, but in the below query, it is displayed NULL. In fact, I want to select from the two tables with a left join.
This is my query:
select fff.*,CustomerCode,SUBSTRING(( SELECT DISTINCT
RIGHT('0000'
+ LTRIM(RTRIM(CustomerCode)),
4)
+ '-'
FROM TatEstelam.dbo.CustomerInfo
WHERE ltrim(rtrim(CodeMelli)) <> '' and CodeMelli <> '0000000000' AND CODEMELLI <> '0' AND Nationalcode = fff.CodeMelli
FOR
XML PATH('')
), 0,
LEN(( SELECT DISTINCT
RIGHT('0000'
+ LTRIM(RTRIM(CustomerCode)),
4)
+ '-'
FROM TatEstelam.dbo.CustomerInfo
WHERE ltrim(rtrim(CodeMelli)) <> '' and CodeMelli <> '0000000000' AND CODEMELLI <> '0' AND Nationalcode = fff.CodeMelli
FOR
XML PATH('')
)))
AS customerNumber from ( SELECT NameOutput AS Fullname ,
shobehNew AS BRANCHNO ,
ShenaseMelli AS Nationalcode ,
[CodeMelli],
CreateDate AS RegisterDate ,
N'ساها حقوقی' as type
FROM TatEstelam.dbo.tblCodeMRequest_0 where CreateDate BETWEEN '920101' AND '930501' and CusType = 6) as fff
LEFT JOIN (select DISTINCT Nationalcode,customercode,NationalID from TatEstelam.dbo.CustomerInfo where InqueryType <> '01' ) ci ON fff.Nationalcode = ci.NationalID and ltrim(rtrim(CodeMelli)) <> '' and CodeMelli <> '0000000000' AND CODEMELLI <> '0'
ORDER BY CODEmELLI
but in this query customer code will display :
select * from TatEstelam.dbo.CustomerInfo c right join TatEstelam.dbo.tblCodeMRequest_0 m
on c.Nationalcode = m.ShenaseMelli
I have two tables with structures like this:
VelocityBase
Aisle | ItemId | ConfigId | InventSizeId | InventColorId | InventLocationId | DataAreaId | VelocityCategory
VelocitySalesCount
ItemId | ConfigId | InventSizeId | InventColorId | InventLocationId | DataAreaId | Sales
Every row in the Base table represents a SKU and the sum of the related SalesCount records' "Sales" fields determines the "Picks". This query works:
SELECT Aisle, COUNT(*) as '# SKUs',
SUM(Sales) as '# Picks',
SUM(CASE WHEN VelocityCategory = 'Hot' THEN 1 ELSE 0 END) as 'Hot SKUs',
SUM(CASE WHEN VelocityCategory = 'Hot' THEN SALES ELSE 0 END) as 'Hot Picks',
SUM(CASE WHEN VelocityCategory = 'Warm' THEN 1 ELSE 0 END) as 'Warm SKUs',
SUM(CASE WHEN VelocityCategory = 'Warm' THEN SALES ELSE 0 END) as 'Warm Picks',
SUM(CASE WHEN VelocityCategory = 'Cold' THEN 1 ELSE 0 END) as 'Cold SKUs',
SUM(CASE WHEN VelocityCategory = 'Cold' THEN SALES ELSE 0 END) as 'Cold Picks'
FROM [dbo].[VelocityBase] Base
LEFT OUTER JOIN [dbo].[VelocitySalesCount] SalesCount
ON Base.ItemId = SalesCount.ItemId
AND Base.ConfigId = SalesCount.ConfigId
AND Base.InventSizeId = SalesCount.InventSizeId
AND Base.InventColorId = SalesCount.InventColorId
AND Base.InventLocationId = SalesCount.InventLocationId
AND SalesCount.DataAreaId = Base.DataAreaId
GROUP BY Aisle
ORDER BY Aisle
However, the columns are hard coded. What I would like is that the "Hot", "Warm", "Cold", etc be generated based on what values are present in the database for this column. That way if a user added a row that had "Lukewarm" as the VelocityCategory, two new columns would appear with that data.
I'm not sure if something like SQL to generate SQL or maybe a PIVOT function would do the trick.
Thanks in advance!
EDIT:
I'm narrowing in. I've got the Sum of the Sales figures using this:
DECLARE #SQLStatement NVARCHAR(4000)
,#PivotValues NVARCHAR(4000);
SET #PivotValues = '';
SELECT #PivotValues = #PivotValues + ',' + QUOTENAME(VelocityCategory)
FROM
(
SELECT DISTINCT VelocityCategory
FROM dbo.VelocityBase
) src;
SET #PivotValues = SUBSTRING(#PivotValues,2,4000);
SELECT #SQLStatement =
'SELECT pvt.*
FROM
(
SELECT Aisle, VelocityCategory, Sales
FROM VelocityBase Base
LEFT OUTER JOIN [dbo].[VelocitySalesCount] SalesCount
ON Base.ItemId = SalesCount.ItemId
AND Base.ConfigId = SalesCount.ConfigId
AND Base.InventSizeId = SalesCount.InventSizeId
AND Base.InventColorId = SalesCount.InventColorId
AND Base.InventLocationId = SalesCount.InventLocationId
AND SalesCount.DataAreaId = Base.DataAreaId
) VelocityBase
PIVOT ( Sum(Sales) FOR VelocityCategory IN ('+#PivotValues+') ) pvt';
EXECUTE sp_executesql #SQLStatement;
Thanks for the link to the previous question which got me this far.
I usually do not use PIVOT, just "usual" dynamic SQL like this:
DECLARE #sSQL NVARCHAR(MAX)= '' ,
#sSQLSum NVARCHAR(MAX)= '' ,
#sSQlBegin NVARCHAR(MAX)= '
SELECT Aisle, COUNT(*) As ''# SKUs'',
SUM(Sales) As ''# Picks'',
' ,
#sSQLEnd NVARCHAR(MAX)= 'FROM [Dbo].[VelocityBase] Base
LEFT OUTER JOIN [Dbo].[VelocitySalesCount] SalesCount
ON Base.ItemId = SalesCount.ItemId
AND Base.ConfigId = SalesCount.ConfigId
AND Base.InventSizeId = SalesCount.InventSizeId
AND Base.InventColorId = SalesCount.InventColorId
AND Base.InventLocationId = SalesCount.InventLocationId
AND SalesCount.DataAreaId = Base.DataAreaId
GROUP BY Aisle
ORDER BY Aisle' ;
WITH c AS ( SELECT DISTINCT
VelocityCategory N
FROM Dbo.VelocityBase
)
SELECT #sSQLSum = #sSQLSum + 'SUM(CASE WHEN c.N=''' + c.N
+ ''' THEN 1 ELSE 0 END ) AS ''' + c.N + ' SKUs'',' + CHAR(13)
+ 'SUM(CASE WHEN c.N=''' + c.N
+ ''' THEN SALES ELSE 0 END ) AS ''' + c.N + ' Sales'',' + CHAR(13)
FROM c
IF(LEN(#sSQLSum))>0
SET #sSQLSum = LEFT(#sSQLSum, ( LEN(#sSQLsum) - 2 ))
SET #sSQL = #sSQlBegin + #sSQLSum + CHAR(13) + #sSQLEnd
EXEC (#sSQL)
Unless you generate the query dynamically, I don't think there's a way to generate what you want.
Your problem could be solved easily if your tables were normalized. For instance, the VelocityBase table should have a VelocityCategoryID column instead of a VelocityCategory column. This new column should be a foreign key to a new table called VelocityCategory (or something like that) then your query for this calculation becomes almost trivial.