Repeating an attribute value in sql - sql

I have a simple query that I would like some specific results but not sure of the right way to go about it. I'm using a SQL Server database and my query is as follows:
SELECT dt.year ,
db.dist_code ,
db.dist_name ,
db.s_code ,
db.s_name ,
fl.zip ,
fl.num_births ,
total_enrollment
FROM dbo.fact_enrollment_school AS fs
INNER JOIN dbo.dim_building AS db ON fs.building_key = db.building_key
INNER JOIN dbo.dim_time AS dt ON fs.time_key = dt.time_key
LEFT OUTER JOIN dbo.fact_live_birth AS fl ON dt.time_key = fl.time_key
AND db.building_key = fl.building_key
GROUP BY dt.year ,
db.dist_code ,
db.dist_name ,
db.school_code ,
db.school_name ,
fl.zip ,
total_enrollment ,
fl.num_births
What I need is to output the num_births total for every district_code that is the same.
Desired output:

I think you can achieve this by window function:
SELECT dt.year ,
db.dist_code ,
db.dist_name ,
db.s_code ,
db.s_name ,
fl.zip ,
sum(fl.num_births) over (partition by dt.year, db.dist_code),
total_enrollment
FROM dbo.fact_enrollment_school AS fs
INNER JOIN dbo.dim_building AS db ON fs.building_key = db.building_key
INNER JOIN dbo.dim_time AS dt ON fs.time_key = dt.time_key
LEFT OUTER JOIN dbo.fact_live_birth AS fl ON dt.time_key = fl.time_key
AND db.building_key = fl.building_key;

Related

Convert Oracle query to SQL Server using a CTE

I am trying to convert the following Oracle query to SQL Server and have run into an issue trying to create my CTE for the hierarchy order. I only provided the last select statement as there are 7 with statements and thought the code would be too long to post. Any ideas?
SELECT '"'||rownum||'"' as ORIGINAL_ORDER, A.*
FROM (
SELECT
'"'||LEVEL||'"'
, CAST('"'||lpad(' ',level*2,' ')||P.POSITION_NBR||'"' AS VARCHAR(100)) AS
HIERARCHY
,'"'||P.POSITION_NBR||'"' AS POS_NBR
,'"'||P.DESCR||'"' AS POS_TITLE
,'"'||P.CLASSIFICATION_CD||'"' AS CLASSCd
, '"'||P.LOCATION||'"' AS LOC
, '"'||P.LOC_DESCR||'"' AS LOC_DESCR
, '"'||P.DEPTID||'"' AS DEP
, '"'||P.DEPT_DESCR||'"' AS DEP_DESCR
, F.LANG_PROF
, A.EMPS
, B.ACCOMPLISHMENT "ACC_READ"
, B.DT_ISSUED "DT_ISSUED_READ"
, B.RESULTS_LEVEL_CD "LEVEL_CD_READ"
, B.RESULTS_EXPIRY_DT "EXPIRY_DT_READ"
, C.ACCOMPLISHMENT "ACC_WRITE"
, C.DT_ISSUED "DT_ISSUED_WRITE"
, C.RESULTS_LEVEL_CD "LEVEL_CD_WRITE"
, C.RESULTS_EXPIRY_DT "EXPIRY_DT_WRITE"
, D.ACCOMPLISHMENT "ACC_ORAL"
, D.DT_ISSUED "DT_ISSUED_ORAL"
, D.RESULTS_LEVEL_CD "LEVEL_CD_ORAL"
, D.RESULTS_EXPIRY_DT "EXPIRY_DT_ORAL"
, E.XLATLONGNAME
from POSITIONS P
LEFT JOIN JOB A
ON P.POSITION_NBR = A.POSITION_NBR
LEFT JOIN SLE_READ B
ON A.EMPLID = B.EMPLID
LEFT JOIN SLE_WRITE C
ON A.EMPLID = C.EMPLID
LEFT JOIN SLE_ORAL D
ON A.EMPLID = D.EMPLID
LEFT JOIN POS_LANG_REQ E
ON A.POSITION_NBR = E.POSITION_NBR
LEFT JOIN POS_LANG_PROF F
ON P.POSITION_NBR = F.POSITION_NBR
start with P.position_nbr = '&&pPOSN_STARTSAT'`enter code here`
connect by nocycle prior p.position_nbr = p.reports_to
order siblings by p.position_nbr ) A

SQL Server : How to make this query more efficient/faster?

Question for the SQL Wizards & Masters out there. I've got to get the execution time down on this beast. It's taking 5+ minutes to execute and occasionally times out. I need help understanding how to make it more efficient. I'm returning about 100,000 rows.
The scenario is: I’m trying to identify “valid orders” that should be flagged for something called the "Dating season". These orders will have items associated with valid ‘category codes’ (dbo.DTITEMS ON od.CATEGORY = dbo.DTITEMS.CATEGORY).
Then I use the results of this query to basically update an order field “DTGSEASON” with the value of the current "dating season."
I reference a table called DATING (separate from CRM.Dbo.Dating) that stores parameters like Promotion Start & End Dates, current dating season, etc.
Here’s the query I’m running to find ‘Valid Orders’, called vDatingValidOrdersReg:
SELECT
h.CUSTOMER
, h.ORDNUMBER
, h.INVNETWTX
, dtgseason.VALUE AS dtgseason
, c.comp_dqdatingmin
, dbo.DTITEMS.ALTMINIMUM
, d.dat_datingapprovedon
, d.dat_ordsincepromostart
, h.EXPDATE
, dbo.DATING.PROMOSTART
, d.dat_season
, d.dat_year
, od.ITEM
, od.CATEGORY
, d.dat_DatingID
, c.Comp_Name
, d.dat_state
, h.ORDUNIQ
, c.comp_dqdatingmax
FROM CRM.dbo.Dating AS d
INNER JOIN CRM.dbo.Company AS c
ON d.dat_CompanyId = c.Comp_CompanyId
LEFT OUTER JOIN dbo.OEORDH AS h
ON c.Comp_IdCust = h.CUSTOMER
LEFT OUTER JOIN dbo.OEORDHO AS dtgseason
ON h.ORDUNIQ = dtgseason.ORDUNIQ AND dtgseason.OPTFIELD = 'dtgseason'
INNER JOIN dbo.OEORDD AS od
ON h.ORDUNIQ = od.ORDUNIQ
INNER JOIN dbo.DTITEMS
ON od.CATEGORY = dbo.DTITEMS.CATEGORY
INNER JOIN dbo.DATING
ON d.dat_season = dbo.DATING.SEASON
AND d.dat_year = dbo.DATING.YEAR
AND dbo.DTITEMS.SEASON = dbo.DATING.SEASON
AND dbo.DTITEMS.YEAR = dbo.DATING.YEAR
WHERE (h.ORDDATE BETWEEN dbo.DATING.PROMOSTART AND dbo.DATING.PROMOEND)
AND (h.EXPDATE BETWEEN dbo.DATING.EXPSHIPST AND dbo.DATING.EXPSHIPEND)
AND (d.dat_state = 'Approve')
AND (d.dat_Deleted IS NULL)
AND (dbo.DATING.SEASCLOSED = 0)
AND (dbo.DTITEMS.ALTMINIMUM = 0)
AND (h.ORDNUMBER NOT IN (
SELECT ORDNUMBER
FROM dbo.vDatingValidOrdersAlt))
AND (dbo.DATING.ORDERON = 1)
Here’s the query it references, which is basically the same thing, but looks for orders with different item categories: vDatingValidOrdersAlt. Is this my problem?
SELECT
h.CUSTOMER
, h.ORDNUMBER
, h.INVNETWTX
, dtgseason.VALUE AS dtgseason
, c.comp_dqdatingmin
, dbo.DTITEMS.ALTMINIMUM
, d.dat_datingapprovedon
, d.dat_ordsincepromostart
, h.EXPDATE
, dbo.DATING.PROMOSTART
, d.dat_season
, d.dat_year
, od.ITEM
, od.CATEGORY
, d.dat_DatingID
, c.Comp_Name
, d.dat_state
, h.ORDUNIQ, c.comp_dqdatingmax
FROM CRM.dbo.Dating AS d
INNER JOIN CRM.dbo.Company AS c
ON d.dat_CompanyId = c.Comp_CompanyId
LEFT OUTER JOIN dbo.OEORDH AS h
ON c.Comp_IdCust = h.CUSTOMER
LEFT OUTER JOIN dbo.OEORDHO AS dtgseason
ON h.ORDUNIQ = dtgseason.ORDUNIQ AND dtgseason.OPTFIELD = 'dtgseason'
INNER JOIN dbo.OEORDD AS od
ON h.ORDUNIQ = od.ORDUNIQ
INNER JOIN dbo.DTITEMS
ON od.CATEGORY = dbo.DTITEMS.CATEGORY
INNER JOIN dbo.DATING
ON d.dat_season = dbo.DATING.SEASON
AND d.dat_year = dbo.DATING.YEAR
AND dbo.DTITEMS.SEASON = dbo.DATING.SEASON
AND dbo.DTITEMS.YEAR = dbo.DATING.YEAR
WHERE (h.ORDDATE BETWEEN dbo.DATING.PROMOSTART AND dbo.DATING.PROMOEND)
AND (h.EXPDATE BETWEEN dbo.DATING.EXPSHIPST AND dbo.DATING.EXPSHIPEND)
AND (d.dat_state = 'Approve')
AND (d.dat_Deleted IS NULL)
AND (dbo.DATING.SEASCLOSED = 0)
AND (dbo.DTITEMS.ALTMINIMUM > 0)
AND (dbo.DATING.ORDERON = 1)
There must be a way to make this query less resource-intensive, but I'm not sure how to go about it. Thoughts and suggestions?
You have a logical issue in both of these queries. You have a left join to dbo.OEORDH but then have a where clause on that table. That is logically changing your left join to an inner join. As for performance I don't see anything glaring that you can change in your sql. I would however be surprised if you have indexes situated to cover these queries. We would need to see the table definition and indexes. Also, posting the execution plans would be crucial in figuring this out.
Here is what those two queries might look like with some formatting.
SELECT h.CUSTOMER
, h.ORDNUMBER
, h.INVNETWTX
, dtgseason.VALUE AS dtgseason
, c.comp_dqdatingmin
, di.ALTMINIMUM
, d.dat_datingapprovedon
, d.dat_ordsincepromostart
, h.EXPDATE
, dd.PROMOSTART
, d.dat_season
, d.dat_year
, od.ITEM
, od.CATEGORY
, d.dat_DatingID
, c.Comp_Name
, d.dat_state
, h.ORDUNIQ
, c.comp_dqdatingmax
FROM CRM.dbo.Dating AS d
INNER JOIN CRM.dbo.Company AS c ON d.dat_CompanyId = c.Comp_CompanyId
LEFT OUTER JOIN dbo.OEORDH AS h ON c.Comp_IdCust = h.CUSTOMER
LEFT OUTER JOIN dbo.OEORDHO AS dtgseason ON h.ORDUNIQ = dtgseason.ORDUNIQ
AND dtgseason.OPTFIELD = 'dtgseason'
INNER JOIN dbo.OEORDD AS od ON h.ORDUNIQ = od.ORDUNIQ
INNER JOIN dbo.DTITEMS di ON od.CATEGORY = di.CATEGORY
INNER JOIN dbo.DATING dd ON d.dat_season = dd.SEASON
AND d.dat_year = dd.YEAR
AND di.SEASON = dd.SEASON
AND di.YEAR = dd.YEAR
WHERE h.ORDDATE BETWEEN dd.PROMOSTART AND dd.PROMOEND
AND h.EXPDATE BETWEEN dd.EXPSHIPST AND dd.EXPSHIPEND
AND d.dat_state = 'Approve'
AND d.dat_Deleted IS NULL
AND dd.SEASCLOSED = 0
AND di.ALTMINIMUM = 0
AND h.ORDNUMBER NOT IN (SELECT ORDNUMBER FROM dbo.vDatingValidOrdersAlt)
AND dd.ORDERON = 1
And the second one.
SELECT h.CUSTOMER
, h.ORDNUMBER
, h.INVNETWTX
, dtgseason.VALUE AS dtgseason
, c.comp_dqdatingmin
, di.ALTMINIMUM
, d.dat_datingapprovedon
, d.dat_ordsincepromostart
, h.EXPDATE
, dd.PROMOSTART
, d.dat_season
, d.dat_year
, od.ITEM
, od.CATEGORY
, d.dat_DatingID
, c.Comp_Name
, d.dat_state
, h.ORDUNIQ
, c.comp_dqdatingmax
FROM CRM.dbo.Dating AS d
INNER JOIN CRM.dbo.Company AS c ON d.dat_CompanyId = c.Comp_CompanyId
LEFT OUTER JOIN dbo.OEORDH AS h ON c.Comp_IdCust = h.CUSTOMER
LEFT OUTER JOIN dbo.OEORDHO AS dtgseason ON h.ORDUNIQ = dtgseason.ORDUNIQ
AND dtgseason.OPTFIELD = 'dtgseason'
INNER JOIN dbo.OEORDD AS od ON h.ORDUNIQ = od.ORDUNIQ
INNER JOIN dbo.DTITEMS as di ON od.CATEGORY = di.CATEGORY
INNER JOIN dbo.DATING as dd ON d.dat_season = dd.SEASON
AND d.dat_year = dd.YEAR
AND di.SEASON = dd.SEASON
AND di.YEAR = dd.YEAR
WHERE h.ORDDATE BETWEEN dd.PROMOSTART AND dd.PROMOEND
AND h.EXPDATE BETWEEN dd.EXPSHIPST AND dd.EXPSHIPEND
AND d.dat_state = 'Approve'
AND d.dat_Deleted IS NULL
AND dd.SEASCLOSED = 0
AND di.ALTMINIMUM > 0
AND dd.ORDERON = 1

How to add Parameter to report

select distinct sotr_sys_no
, SODETS_VINYL_COLOUR
, SODETS_MDF_COLOUR
, SOTR_PROMISED_DATE
, DATEDIFF(dd,getdate(),sotr_promised_date) as DueDays
, AEXTRA_5_SHORT_NAME
, AEXTRA_5_VINYL_PARTCODE
, CASE WHEN SODETS_MDF_COLOUR > '0' THEN AltMDFCode ELSE AEXTRA_5_MDF_PARTCODE END AS AEXTRA_5_MDF_PARTCODE
, ISNULL(Vinylqty,0) As VinylQty
, ISNULL(MDFqty,0) as MDFQty
, Vinyldue
, MDFdue
, WO.WOOutstanding
from Defactouser.F_SO_Transaction WITH (NOLOCK)
inner join defactouser.F_SO_Transaction_Details WITH (NOLOCK)
on sotr_sys_no = sotd_head_no
inner join defactouser.F_SO_Transaction_Details_Extra WITH (NOLOCK)
on SOTD_SYS_NO = SODETS_LINK
left outer join (
select distinct AEXTRA_5_CODE as AltMDFKey
, AEXTRA_5_MDF_PARTCODE AS AltMDFCode
from DeFactoUser.F_AD_Extra_5 WITH (NOLOCK)
) as AltMDF
on SODETS_MDF_COLOUR = AltMDF.AltMDFKey
left outer join defactouser.F_AD_Extra_5 WITH (NOLOCK)
on SODETS_VINYL_COLOUR = [AEXTRA_5_CODE]
inner join defactouser.F_ST_Products WITH (NOLOCK)
on sotd_strc_code = strc_code
left Outer join (
SELECT Product_Code As VinylStockCode, sum(Physical_Qty_Units) as Vinylqty FROM DBO.DFBI_Stock_Physical WITH (NOLOCK)
WHERE Warehouse = 'DOORS' and LEFT(product_code ,3) = 'vfl'
Group By Product_Code
HAVING SUM(Physical_Qty_Units) >0
) VinylStock
on AEXTRA_5_VINYL_PARTCODE = VinylStock.VinylStockCode
left outer join (
SELECT Product_Code As MDFStockCode, sum(Physical_Qty_Units) as MDFqty FROM DBO.DFBI_Stock_Physical WITH (NOLOCK)
WHERE Warehouse = 'PANELS' and LEFT(product_code ,3) = 'MDF'
Group By Product_Code
HAVING SUM(Physical_Qty_Units) >0
) MDFStock
on CASE WHEN SODETS_MDF_COLOUR > '0' THEN AltMDF.AltMDFCode ELSE AEXTRA_5_MDF_PARTCODE END = MDFStock.MDFStockCode
left Outer JOin (select stex_strc_code as VinylStex , sum(STEX_QTY_UNITS) as Qty, MIN(stex_promised_date) as Vinyldue
from defactouser.F_ST_Transaction_Expediting
where left(stex_strc_code ,3) = 'vfl'
and stex_type = 'pop+'
group By STEX_STRC_CODE
) VinylStockIn
on AEXTRA_5_VINYL_PARTCODE = VinylStex
left Outer Join (
select stex_strc_code as MDFStex , sum(STEX_QTY_UNITS) as Qty, MIN(stex_promised_date) as MDFdue
from defactouser.F_ST_Transaction_Expediting
where left(stex_strc_code ,3) = 'mdf'
and stex_type = 'pop+'
group By STEX_STRC_CODE
) MDFStockIn on CASE WHEN SODETS_MDF_COLOUR > '0' THEN AltMDF.AltMDFCode ELSE AEXTRA_5_MDF_PARTCODE END = MDFStex
LEFT OUTER JOIN (
select SOTD_HEAD_NO, SODETS_VINYL_COLOUR as WOVinyl, SUM(BMTD_QTY_OUTSTANDING) as WOOutstanding from defactouser.f_bm_transactions_details
inner join defactouser.F_SO_Transaction_Details on BMTD_ORDER_LINK_NUMBER = SOTD_SYS_NO
inner join defactouser.F_SO_Transaction_Details_Extra on BMTD_ORDER_LINK_NUMBER = SODETS_LINK
where bmtd_type = 1 and bmtd_bmtr_type = 0 and bmtd_stwh_code in ('doors', 'shef trans') and SOTD_STATUS <99
Group by SOTD_HEAD_NO, SODETS_VINYL_COLOUR
) WO
on sotr_sys_no = WO.SOTD_HEAD_NO AND SODETS_VINYL_COLOUR = WO.WOVinyl
where (SOTD_QTY_UNITS_OUTSTANDING > 0
and SOTR_TYPE = 10
and SOTD_STWH_CODE IN ('doors' , 'hpp shef')
and left(sotd_strc_code ,5) <> 'drill'
and SOTR_CUST_CODE <>'hpp'
and STRC_ANAL1 = '1027'
and ISNULL(VinylQty,0) <10
and DATEDIFF(dd,getdate(),sotr_promised_date) <5
)
or
(SOTD_QTY_UNITS_OUTSTANDING > 0
and SOTR_TYPE = 10
and SOTD_STWH_CODE IN ('doors' , 'hpp shef')
and left(sotd_strc_code ,5) <> 'drill'
and SOTR_CUST_CODE <>'hpp'
and STRC_ANAL1 = '1027'
and ISNULL(MDFQty,0) <4
and DATEDIFF(dd,getdate(),sotr_promised_date) <5
)
Order By MDFQty, AEXTRA_5_MDF_PARTCODE
Currently this query produces a report that returns a table with products due to arrive in the next 5 days. How do I add a parameter to the report that will show me the results as it is, and then also to show a report for products due in whenever. I am using Report Builder 3.0, and have tried to add a parameter but cannot get the desired result.
Can this be done without editing the query and just in report builder?
Change you WHERE clause and replace < 5 with < #Days. Assuming the query is not a stored proc and is directly in the dataset query then SSRS will automatically add the #Days parameter to your report.

Applying cluster indexing to a view in SQL Server 2012

I have a view which queries around 1+ million rows and takes around 10-15 minutes to finish its execution,I want to provide cluster indexing to it so that it exists in physical schema and takes less time to load, but there are a number of constraints in order to provide cluster indexing i.e. only INNER JOIN are allowed and No subqueries should be present in views defination how do I replace the LEFT JOIN present in this view with INNER JOIN and how do I eliminate subqueries from this views defination so that cluster indexing can be applied to it.
CREATE view [dbo].[FTM_ProfileDetailsView] with SCHEMABINDING as
select FTM.Id
, FTM.EmployeeId
, FTM.CustomerId
, FTM.AbsenceFirstDate
, FTM.BackgroundHistory
, FTM.BackgroundHistoryComments
, FTM.IsEmployeeAbsent,FTM.ServiceId
, Case When isnull(FTM.IsSelfManagement,'')='' THEN cast(0 as bit) ELSE FTM.IsSelfManagement END as IsSelfManagement
, PR.ServiceLineId,FTM.ProfileId,PR.StatusId,Status.Status as StatusName
, PR.ReasonID
, PR.ModifiedDate
, PR.WithdrawnReason
, PR.CreatedBy
, PR.CreatedDate
, PR.IsActive
, mgrs.usernames as LineManagers
, cust.CustomerName
, ltrim(rtrim( emp.EmployeeTitle+' '+ emp.FirstName+' '+ emp.Surname)) as EmployeeFullName
, FTM.ProfileManagerId
, FTM.IsProfileManagement
, AM.MonitoringChecks
, AM.Frequency
, AM.ProfileManagerNotes
, AM.TaskDateAndTime
, FTM.ProfileManagementCriteriaId
,cast(case when PR.StatusId = 13 then 1 else 0 end as bit) as IsActiveMonitoring
, CustServ.CustomerServiceName
, BU.Name as BusinessUnit
, emp.DASID
, emp.DateOfBirth as EmployeeDOB
, addr.PostCode
, coninfo.Email
, (select top 1
StatusId from dbo.PR_Profileintervention ProfileInt
where ProfileInt.ProfileId=FTM.Profileid
order by ProfileInt.Id desc) as LatestInterventionStatusId
, (select name from dbo.FTM_Intervention Intr
where Intr.Id=(select top 1 InterventionId from dbo.PR_Profileintervention ProfileInt
where ProfileInt.ProfileId=FTM.Profileid
order by ProfileInt.Id desc))
as LatestInterventionName from FTM_Profile FTM
LEFT JOIN dbo.ProfileManagersView mgrs ON mgrs.ProfileID = FTM.ProfileID
INNER JOIN dbo.Customer cust on cust.Id= FTM.CustomerId
INNER JOIN dbo.Employee emp on emp.Id = FTM.EmployeeId
INNER JOIN dbo.PR_Profile PR on PR.Profileid=FTM.ProfileId
LEFT JOIN dbo.BusinessUnit BU on BU.Id=PR.BUId
LEFT JOIN dbo.PR_dv_Status [Status] on [Status].Id = PR.StatusId
LEFT JOIN dbo.CM_ActiveMonitoringDetails AM on AM.ProfileId = PR.Profileid
LEFT JOIN dbo.FTM_CustomerServiceMapping CustServ on CustServ.ServiceId = FTM.ServiceId and CustServ.CustomerId = FTM.CustomerId
LEFT JOIN dbo.contact con on con.Id = emp.ContactID
LEFT JOIN dbo.address addr on addr.Id = con.HomeAddressId
LEFT JOIN dbo.contactinfo coninfo on coninfo.Id = con.ContactInfoId
I have a suggestion. Can you try and change your query so the sub -queries in the SELECT are placed in CROSS APPLYs?
So something along the lines of this in your WHERE clause:
CROSS APPLY (
select top 1 StatusId AS LatestInterventionStatusId
from dbo.PR_Profileintervention ProfileInt
where ProfileInt.ProfileId=FTM.Profileid
order by ProfileInt.Id desc
) LatestInterventionStatusId
CROSS APPLY (
select name AS LatestInterventionName
from dbo.FTM_Intervention Intr
where Intr.Id=(select top 1 InterventionId
from dbo.PR_Profileintervention ProfileInt
where ProfileInt.ProfileId=FTM.Profileid
order by ProfileInt.Id desc)
)LatestInterventionName
And then of course change the column names in the SELECT to something like this:
, LatestInterventionStatusId.LatestInterventionStatusId
, LatestInterventionName.LatestInterventionName
Give this a go and let me know if it makes a different.
Ok, you didn't give me an answer on my question, but the subqueries should be changed. Try to use this instead the two subqueries:
/*
...
, emp.DateOfBirth as EmployeeDOB
, addr.PostCode
, coninfo.Email
*/
, p.StatusId as LatestInterventionStatusId
, p.name as LatestInterventionName
from FTM_Profile FTM
OUTER APPLY (
select TOP 1 Intr.name, ProfileInt.StatusId
from dbo.PR_Profileintervention ProfileInt
LEFT JOIN dbo.FTM_Intervention Intr ON Intr.Id = ProfileInt.InterventionId
where ProfileInt.ProfileId = FTM.Profileid
order by ProfileInt.Id desc
) p
/*
LEFT JOIN dbo.ProfileManagersView mgrs ON mgrs.ProfileID = FTM.ProfileID
INNER JOIN dbo.Customer cust on cust.Id= FTM.CustomerId
INNER JOIN dbo.Employee emp on emp.Id = FTM.EmployeeId
...
*/

SQL Server 2008 : FROM clause syntax error

My code returns a syntax error on L42 (the from clause). I've looked and looked and to me, the syntax looks correct for the FROM.
The top part of the code creates a temp table 'subproducts'. Then I want to pull data from DB tables & pull relevant details from the new temp table.
Any ideas?
drop table ##subproducts;
SELECT
F1.[OrderNo]
,F1.[OrderSeqNo]
,F1.[OrderLineNo]
,sum(F1.[LineCost]) as LineCost
,sum(F1.[NetCost]) as NetCost
,sum(F1.[OrderNet]) as OrderNet
INTO
##subproducts
FROM
[UFPData].[dbo].[SalesStats] F1
WHERE
F1.MainProd = 'S'
GROUP BY
F1.OrderNo, F1.OrderSeqNo, F1.OrderLineNo;
SELECT *
FROM SalesStats F1
LEFT OUTER JOIN ##subproducts F2 ON F1.OrderNo = F2.OrderNo
AND F1.OrderSeqNo = F2.Orderseqno
AND F1.OrderLineNo = F2.OrderLineNo
WHERE YEAR(InvDate) = 2015
AND MONTH(InvDate) = 5
AND CustNo = 100382
AND MainProd = 'Y';
SELECT
ContractInfo.CONTRNO,
ContractInfo.CONTRDESC,
repcode,
RepName,
PriceAgreement,
ordercycle,
SalesStats.CustNo,
Customer.CustName,
SalesStats.InvDate,
SalesStats.InvoiceNo,
salesstats.ProdCode,
Price as ContractPrice,
subproduct.LineCost as LineCost,
subproduct.NetCost as NetCost,
subproduct.OrderNet as OrderNet,
contractinfo.NETCOST as BidPrice,
contractinfo.NETCOST* SUM(quantity) as BidCost,
FROM
UFPData.dbo.SalesStats
RIGHT OUTER JOIN
##subproducts ON UFPData.dbo.SalesStats.ProdCode = ##subproducts.ProdCode,
UFPData.dbo.SalesStats
LEFT OUTER JOIN
UFPData.dbo.Customer ON UFPData.dbo.SalesStats.CustNo = UFPData.dbo.Customer.CustNo, UFPData.dbo.SalesStats
LEFT OUTER JOIN
Pricing.dbo.InvManCen ON UFPData.dbo.SalesStats.ProdCode = Pricing.dbo.invmancen.UFPCODE, UFPData.dbo.SalesStats
RIGHT OUTER JOIN
UFPData.dbo.ContractInfo ON UFPData.dbo.Customer.CustNo = UFPData.dbo.ContractInfo.CUSTNO
AND UFPData.dbo.salesstats.prodcode = UFPData.dbo.contractinfo.prodcode,
WHERE
invdate BETWEEN '2015-05-01' and '2015-05-31'
AND TeamCode IN ('tm1','tm2','tm3')
AND ContractInfo.CONTRNO IN ('1500','1502','1503','1504','1505','1506','701','702','703','705','141',
'712', '713', '714', '715', '716', '717', '718', '719', '730', '731', '732') or CONTRNO between '3000' and '3049')
--and left(ordercycle,1) <> 'c'
GROUP BY
ContractInfo.CONTRNO,
repcode,
RepName,
SalesStats.CustNo,
Customer.CustName,
SalesStats.InvDate,
salesstats.ProdCode,
Price,
contractinfo.NETCOST,
SalesStats.InvoiceNo,
InvManCen.PS98,
ContractInfo.CONTRDESC,
ordercycle,
PriceAgreement,
case
when invdate > ('20' + LEFT(ENDDATE,2)+ '-'+ SUBSTRING(cast(ENDDATE as varchar(6)),3,2)+ '-'+ SUBSTRING(cast(ENDDATE as varchar(6)),5,2)) then 'Expired' else 'Live' end;
Many thanks in advance
This doesn't look right to me:
FROM
UFPData.dbo.SalesStats right outer join ##subproducts on UFPData.dbo.SalesStats.ProdCode = ##subproducts.ProdCode,
UFPData.dbo.SalesStats left outer join UFPData.dbo.Customer on UFPData.dbo.SalesStats.CustNo = UFPData.dbo.Customer.CustNo,
UFPData.dbo.SalesStats left outer join Pricing.dbo.InvManCen on UFPData.dbo.SalesStats.ProdCode = Pricing.dbo.invmancen.UFPCODE,
UFPData.dbo.SalesStats right outer join UFPData.dbo.ContractInfo on UFPData.dbo.Customer.CustNo = UFPData.dbo.ContractInfo.CUSTNO and UFPData.dbo.salesstats.prodcode = UFPData.dbo.contractinfo.prodcode,
Usually the format is something like this:
FROM
TableName
INNER JOIN SomeOtherTable...
INNER JOIN AnotherTable...
Note that the first table is mentioned once, not before every join. You also seem to have errant commas after each join, which isn't syntactically correct. I think you want this:
FROM
UFPData.dbo.SalesStats
right outer join ##subproducts on UFPData.dbo.SalesStats.ProdCode = ##subproducts.ProdCode
left outer join UFPData.dbo.Customer on UFPData.dbo.SalesStats.CustNo = UFPData.dbo.Customer.CustNo
left outer join Pricing.dbo.InvManCen on UFPData.dbo.SalesStats.ProdCode = Pricing.dbo.invmancen.UFPCODE
right outer join UFPData.dbo.ContractInfo on UFPData.dbo.Customer.CustNo = UFPData.dbo.ContractInfo.CUSTNO and UFPData.dbo.salesstats.prodcode = UFPData.dbo.contractinfo.prodcode
There could very well be more syntax errors throughout your query. I recommend formatting the code a little more cleanly to more easily find them. For example, contrast the above with something like this:
FROM
UFPData.dbo.SalesStats
RIGHT OUTER JOIN ##subproducts
ON UFPData.dbo.SalesStats.ProdCode = ##subproducts.ProdCode
LEFT OUTER JOIN UFPData.dbo.Customer
ON UFPData.dbo.SalesStats.CustNo = UFPData.dbo.Customer.CustNo
LEFT OUTER JOIN Pricing.dbo.InvManCen
ON UFPData.dbo.SalesStats.ProdCode = Pricing.dbo.invmancen.UFPCODE
RIGHT OUTER JOIN UFPData.dbo.ContractInfo
ON UFPData.dbo.Customer.CustNo = UFPData.dbo.ContractInfo.CUSTNO
AND UFPData.dbo.salesstats.prodcode = UFPData.dbo.contractinfo.prodcode
It's a small change, and often a matter of personal preference, but well formatted code brings about a number of advantages. Less horizontal scrolling makes it easier to see the relevant code in a single glance, line breaks for specific keywords and clauses makes it easier to spot errant commas, etc.
Here's what I think should be valid syntax for what you've provided, please try it and compare it to the original as there were multiple errors:
DROP TABLE ##subproducts;
SELECT F1.[OrderNo] ,
F1.[OrderSeqNo] ,
F1.[OrderLineNo] ,
SUM(F1.[LineCost]) AS LineCost ,
SUM(F1.[NetCost]) AS NetCost ,
SUM(F1.[OrderNet]) AS OrderNet
INTO ##subproducts
FROM [UFPData].[dbo].[SalesStats] F1
WHERE F1.MainProd = 'S'
GROUP BY F1.OrderNo ,
F1.OrderSeqNo ,
F1.OrderLineNo;
SELECT *
FROM SalesStats F1
LEFT OUTER JOIN ##subproducts F2 ON F1.OrderNo = F2.OrderNo
AND F1.OrderSeqNo = F2.Orderseqno
AND F1.OrderLineNo = F2.OrderLineNo
WHERE YEAR(InvDate) = 2015
AND MONTH(InvDate) = 5
AND CustNo = 100382
AND MainProd = 'Y';
SELECT ContractInfo.CONTRNO ,
ContractInfo.CONTRDESC ,
repcode ,
RepName ,
PriceAgreement ,
ordercycle ,
SalesStats.CustNo ,
Customer.CustName ,
SalesStats.InvDate ,
SalesStats.InvoiceNo ,
SalesStats.ProdCode ,
Price AS ContractPrice ,
subproduct.LineCost AS LineCost ,
subproduct.NetCost AS NetCost ,
subproduct.OrderNet AS OrderNet ,
ContractInfo.NetCost AS BidPrice ,
ContractInfo.NetCost * SUM(quantity) AS BidCost
FROM UFPData.dbo.SalesStats
RIGHT OUTER JOIN ##subproducts ON UFPData.dbo.SalesStats.ProdCode = ##subproducts.ProdCode
LEFT OUTER JOIN UFPData.dbo.Customer ON UFPData.dbo.SalesStats.CustNo = UFPData.dbo.Customer.CustNo
LEFT OUTER JOIN Pricing.dbo.InvManCen ON UFPData.dbo.SalesStats.ProdCode = Pricing.dbo.invmancen.UFPCODE
RIGHT OUTER JOIN UFPData.dbo.ContractInfo ON UFPData.dbo.Customer.CustNo = UFPData.dbo.ContractInfo.CUSTNO
AND UFPData.dbo.salesstats.prodcode = UFPData.dbo.contractinfo.prodcode
WHERE invdate BETWEEN '2015-05-01' AND '2015-05-31'
AND TeamCode IN ( 'tm1', 'tm2', 'tm3' )
AND (ContractInfo.CONTRNO IN ( '1500', '1502', '1503', '1504', '1505',
'1506', '701', '702', '703', '705',
'141', '712', '713', '714', '715', '716',
'717', '718', '719', '730', '731', '732' )
OR CONTRNO BETWEEN '3000' AND '3049')
GROUP BY ContractInfo.CONTRNO ,
repcode ,
RepName ,
SalesStats.CustNo ,
Customer.CustName ,
SalesStats.InvDate ,
SalesStats.ProdCode ,
Price ,
ContractInfo.NetCost ,
SalesStats.InvoiceNo ,
InvManCen.PS98 ,
ContractInfo.CONTRDESC ,
ordercycle ,
PriceAgreement ,
CASE WHEN invdate > ( '20' + LEFT(ENDDATE, 2) + '-'
+ SUBSTRING(CAST(ENDDATE AS VARCHAR(6)), 3, 2)
+ '-' + SUBSTRING(CAST(ENDDATE AS VARCHAR(6)), 5,
2) ) THEN 'Expired'
ELSE 'Live'
END;