I have a pretty complex SQL query that I need run every Monday morning (early).
I've gotten the SQL query to give me the data I need but i'm at a loss how to have the query insert the results into a table.
The declare statements are causing the issue (I THINK)
Does anyone have any ideas? Ideally I'd like to setup a job that just runs and appends to a table.
Thanks.
K.
DECLARE #StartDateTime DATETIME;
DECLARE #EndDateTime DATETIME;
DECLARE #ReportOn CHAR(1);
DECLARE #Group1 VARCHAR(25);
DECLARE #Group2 VARCHAR(25);
DECLARE #Date1Grouping VARCHAR(25);
DECLARE #Date2Grouping VARCHAR(25);
DECLARE #DivisionID VARCHAR(10);
DECLARE #GroupSubsidiaries BIT;
SET #StartDateTime = '3/06/2013' ;
SET #EndDateTime = '3/12/2013' ;
SET #ReportOn = 'S' ;
SET #Group1 = 'Due Date' ;
SET #Group2 = 'Sale Date' ;
SET #Date1Grouping = 'Yearly' ;
SET #Date2Grouping = 'Daily' ;
SET #GroupSubsidiaries = 1 ;
DECLARE #GLEntries TABLE (ID INT PRIMARY KEY, Amount FLOAT, EntryDateTime DATETIME, GLClassificationType INT,
GroupID INT, GLAccountID INT, GLAccountClassTypeID INT, AccountID INT,
TransHeaderID INT, TransDetailID INT, DivisionID INT,
Classification INT, IsTaxable BIT, TaxClassID INT,
GoodsItemID INT, GoodsItemClassTypeID INT);
-- 'C' used for Closed Reports
IF ( #ReportOn = 'C' )
INSERT INTO #GLEntries
SELECT GL.ID, GL.Amount, GL.EntryDateTime, GL.GLClassificationType,
GL.GroupID, GL.GLAccountID, GL.GLAccountClassTypeID, GL.AccountID,
GL.TransactionID, GL.TransDetailID, GL.DivisionID,
GL.Classification, GL.IsTaxable, GL.TaxClassID,
GL.GoodsItemID, GL.GoodsItemClassTypeID
FROM GL WITH(NOLOCK)
WHERE (GL.GLAccountID <> 53)
AND EXISTS( SELECT 1
FROM TransHeader
WHERE ClosedDate BETWEEN #StartDateTime and #EndDateTime
AND ID = GL.TransactionID )
ELSE
INSERT INTO #GLEntries
SELECT GL.ID, GL.Amount, GL.EntryDateTime, GL.GLClassificationType,
GL.GroupID, GL.GLAccountID, GL.GLAccountClassTypeID, GL.AccountID,
GL.TransactionID, GL.TransDetailID, GL.DivisionID,
GL.Classification, GL.IsTaxable, GL.TaxClassID,
GL.GoodsItemID, GL.GoodsItemClassTypeID
FROM GL WITH(NOLOCK)
WHERE (GL.GLAccountID <> 53)
AND GL.EntryDateTime between #StartDateTime and #EndDateTime
;
SELECT Orders.*, Totals.*,
( SELECT -Sum(Amount)
FROM #GLEntries GL1
LEFT JOIN TransHeader TH ON (TH.ID = GL1.TransHeaderID)
WHERE GL1.GLClassificationType = 2005)
as TotalTaxes,
#StartDateTime as theStartDate,
#EndDateTime as theEndDate,
-- Selects Group1 based on #Group1
CASE
WHEN #Group1 = 'Product' THEN Product
WHEN #Group1 = 'None' THEN 'None'
WHEN #Group1 = 'Due Date' THEN
CASE
WHEN #Date1Grouping = 'Daily' THEN Convert( VARCHAR(25), Orders.DueDate, 112)
WHEN #Date1Grouping = 'Weekly' THEN Convert( VARCHAR(25), DateAdd(d, -DatePart(dw,Orders.DueDate) + 1, Orders.DueDate), 112 )
WHEN #Date1Grouping = 'Monthly' THEN Cast( DatePart(yyyy, Orders.DueDate) * 100 + DatePart(mm,Orders.DueDate) AS VARCHAR(7) )
WHEN #Date1Grouping = 'Yearly' THEN Cast( DatePart(yyyy, Orders.DueDate) AS VARCHAR(4) )
END
WHEN #Group1 = 'Sales Date' THEN
CASE
WHEN #Date1Grouping = 'Daily' THEN Convert( VARCHAR(25), Orders.EntryDateTime, 112 )
WHEN #Date1Grouping = 'Weekly' THEN Convert( VARCHAR(25), DateAdd(d, -DatePart(dw,Orders.EntryDateTime) + 1, Orders.EntryDateTime), 112 )
WHEN #Date1Grouping = 'Monthly' THEN Cast( DatePart(yyyy, Orders.EntryDateTime) * 100 + DatePart(mm, Orders.EntryDateTime) AS VARCHAR(7) )
WHEN #Date1Grouping = 'Yearly' THEN Cast( DatePart(yyyy, Orders.EntryDateTime) AS VARCHAR(4) )
END
WHEN #Group1 = 'Primary Salesperson' THEN Salesperson1LastName + Salesperson1FirstName
WHEN #Group1 = 'Customer Origin' THEN OriginName
WHEN #Group1 = 'Industry' THEN IndustryName
WHEN #Group1 = 'Order Origin' THEN OrderOriginName
WHEN #Group1 = 'Postal Code' THEN PostalCode
WHEN #Group1 = 'Postal Code 3 Digit' THEN PostalCode3Digit
WHEN #Group1 = 'Product Category' THEN ProductCategory
WHEN #Group1 = 'Account' THEN AccountName
WHEN #Group1 = 'Company Name' THEN CompanyName
WHEN #Group1 = 'Company Frequency' THEN CompanyName
WHEN #Group1 = 'Company Volume' THEN CompanyName
WHEN #Group1 = 'GL Department' THEN GLDepartment
WHEN #Group1 = 'Industry (Parent)' THEN IndustryParent
WHEN #Group1 = 'Company Origin (Parent)' THEN CompanyOriginParent
WHEN #Group1 = 'Order Origin (Parent)' THEN OrderOriginParent
WHEN #Group1 = 'Region' THEN RegionName
END AS Group1,
CASE
WHEN #Group2 = 'Product' THEN Product
WHEN #Group2 = 'None' THEN 'None'
WHEN #Group2 = 'Due Date' THEN
CASE
WHEN #Date2Grouping = 'Daily' THEN Convert( VARCHAR(25), Orders.DueDate, 112 )
WHEN #Date2Grouping = 'Weekly' THEN Convert( VARCHAR(25), DateAdd(d, -DatePart(dw, Orders.DueDate) + 1, Orders.DueDate), 112 )
WHEN #Date2Grouping = 'Monthly' THEN Cast( DatePart(yyyy, Orders.DueDate) * 100 + DatePart(mm, Orders.DueDate) AS VARCHAR(7) )
WHEN #Date2Grouping = 'Yearly' THEN Cast( DatePart(yyyy, Orders.DueDate) AS VARCHAR(4) )
END
WHEN #Group2 = 'Sales Date' THEN
CASE
WHEN #Date2Grouping = 'Daily' THEN Convert( VARCHAR(25), Orders.EntryDateTime, 112 )
WHEN #Date2Grouping = 'Weekly' THEN Convert( VARCHAR(25), DateAdd(d, -DatePart(dw, Orders.EntryDateTime) + 1, Orders.EntryDateTime), 112 )
WHEN #Date2Grouping = 'Monthly' THEN Cast( DatePart(yyyy, Orders.EntryDateTime) * 100 + DatePart(mm, Orders.EntryDateTime) AS VARCHAR(7) )
WHEN #Date2Grouping = 'Yearly' THEN Cast( DatePart(yyyy, Orders.EntryDateTime) AS VARCHAR(4) )
END
WHEN #Group2 = 'Primary Salesperson' THEN Salesperson1LastName + Salesperson1FirstName
WHEN #Group2 = 'Customer Origin' THEN OriginName
WHEN #Group2 = 'Industry' THEN IndustryName
WHEN #Group2 = 'Order Origin' THEN OrderOriginName
WHEN #Group2 = 'Postal Code' THEN PostalCode
WHEN #Group2 = 'Postal Code 3 Digit' THEN PostalCode3Digit
WHEN #Group2 = 'Product Category' THEN ProductCategory
WHEN #Group2 = 'Account' THEN AccountName
WHEN #Group2 = 'Company' THEN CompanyName
WHEN #Group2 = 'GL Department' THEN GLDepartment
WHEN #Group2 = 'Region' THEN RegionName
END AS Group2
FROM ( SELECT 1 AS StoreID,
fx_Return.DivisionID,
EmployeeGroup.DivisionName,
fx_Return.TransHeaderID,
fx_Return.OrderNumber,
fx_Return.InvoiceNumber,
fx_Return.CompanyName,
-fx_Return.GLAmount AS Amount,
GLAccount.AccountName,
fx_Return.StatusText,
fx_Return.Classification,
fx_Return.GLClassificationType,
fx_Return.Description,
fx_Return.EntryDateTime,
fx_Return.DiscountPrice,
fx_Return.SaleDate,
fx_Return.DueDate,
fx_Return.BuiltDate,
fx_Return.OrderCreatedDate,
fx_Return.ClosedDate,
fx_Return.AccountID,
fx_Return.GLDepartment,
fx_Return.SalesPerson1ID,
SalesPerson1.FirstName AS SalesPerson1FirstName,
SalesPerson1.LastName AS SalesPerson1LastName,
Origin.ItemName AS OriginName,
CASE
WHEN Origin.ParentID = 11 THEN Origin.ItemName
ELSE CompanyOriginParent.ItemName
END AS CompanyOriginParent,
Industry.ItemName AS IndustryName,
CASE
WHEN IndustryParent.ID = 10 THEN Industry.ItemName
ELSE IndustryParent.ItemName
END AS IndustryParent,
fx_Return.OrderOriginName,
CASE
WHEN OrderOrigin.ParentID = 13 THEN OrderOrigin.ItemName
ELSE OrderOriginParent.ItemName
END AS OrderOriginParent,
Address.PostalCode,
SUBSTRING(Address.PostalCode,1,3) AS PostalCode3Digit,
Product.ItemName AS Product,
ProductCategory.ElementName AS ProductCategory,
ProductSubCategory.ElementName AS ProductSubCategory,
Region.ItemName AS RegionName
FROM ( SELECT GL2.EntryDateTime,
SUM( CASE
WHEN #ReportOn NOT IN ('P','B') THEN GL2.Amount
WHEN GL2.GLAccountID IN (11, 12) THEN -GL2.Amount
WHEN GL2.GLClassificationType IN (4000, 2005) THEN GL2.Amount
ELSE 0
END ) AS GLAmount,
GL2.GLAccountID,
CASE
WHEN GL2.GLClassificationType IN (4000,5002)
AND COALESCE(GL2.Classification,-1) NOT IN (100,200,300,400,500) THEN 100
ELSE GL2.Classification
END AS Classification,
GL2.GLClassificationType,
GL2.DivisionID,
GL2.IsTaxable,
GL2.TaxClassID,
GL2.GroupID,
TransHeader.StatusText,
CAST(TransHeader.Description AS VARCHAR(30)) AS Description,
TransHeader.DueDate,
TransHeader.OrderOriginName,
-- TransHeader Related Fields
GL2.TransHeaderID,
TransHeader.OrderNumber,
COALESCE( TransHeader.InvoiceNumber, TransHeader.OrderNumber) as InvoiceNumber,
TransHeader.CreditMemoOrderID,
TransHeader.Salesperson1ID,
TransHeader.OrderOriginID,
TransHeader.InvoiceAddressID as OrderInvoiceAddressID,
TransHeader.PromotionID,
Transheader.DiscountPrice,
TransHeader.PricingLevelID,
TransHeader.ClosedDate,
TransHeader.OrderCreatedDate,
TransHeader.SaleDate,
TransHeader.BuiltDate,
-- TransDetail Related Fields
GL2.TransDetailID,
TransDetail.LineItemNumber,
TransDetail.Quantity,
GL2.GoodsItemID,
GL2.GoodsItemClassTypeID,
TransDetail.GoodsItemCode,
Station.StationName as GLDepartment,
-- Account Related Fields
GL2.AccountID,
ParentAccount.CompanyName,
ParentAccount.AccountNumber,
ParentAccount.PricingPlanTypeID,
ParentAccount.IndustryID,
ParentAccount.RegionID,
ParentAccount.OriginID as CompanyOriginID,
ParentAccount.Marketing3ID,
ParentAccount.BillingAddressID as CompanyBillingAddressID
FROM #GLEntries GL2
LEFT JOIN TransHeader WITH(NOLOCK) ON (TransHeader.ID = GL2.TransHeaderID)
LEFT JOIN Account WITH(NOLOCK) ON (Account.ID = GL2.AccountID)
LEFT JOIN Account ParentAccount WITH(NOLOCK) ON ParentAccount.ID = ( CASE WHEN #GroupSubsidiaries = 1 THEN COALESCE(Account.ParentID, Account.ID) ELSE Account.ID END )
LEFT JOIN TransDetail WITH(NOLOCK) ON (TransDetail.ID = GL2.TransDetailID)
LEFT JOIN Station WITH(NOLOCK) ON TransDetail.GLDepartmentID = Station.ID
WHERE ( GL2.GLClassificationType IN (4000)
OR ( #ReportOn = 'B' AND GL2.GLAccountID in (12) )
OR ( #ReportOn = 'P' AND GL2.GLAccountID in (11,12) )
)
GROUP BY GL2.EntryDateTime,
GL2.GLAccountID,
GL2.GLAccountClassTypeID,
GL2.Classification,
GL2.GLClassificationType,
GL2.DivisionID,
GL2.IsTaxable,
GL2.TaxClassID,
GL2.GroupID,
-- TransHeader Related Fields
GL2.TransHeaderID,
TransHeader.OrderNumber,
COALESCE( TransHeader.InvoiceNumber, TransHeader.OrderNumber ),
TransHeader.CreditMemoOrderID,
TransHeader.Salesperson1ID,
TransHeader.OrderOriginID,
TransHeader.InvoiceAddressID,
TransHeader.PromotionID,
TransHeader.PricingLevelID,
Transheader.DiscountPrice,
TransHeader.OrderCreatedDate,
TransHeader.SaleDate,
TransHeader.ClosedDate,
TransHeader.BuiltDate,
TransHeader.StatusText,
TransHeader.DueDate,
TransHeader.OrderOriginName,
CAST(TransHeader.Description AS VARCHAR(30)),
-- TransDetail Related Fields
GL2.TransDetailID,
TransDetail.LineItemNumber,
TransDetail.Quantity,
GL2.GoodsItemID,
GL2.GoodsItemClassTypeID,
TransDetail.GoodsItemCode,
Station.StationName,
-- Account Related Fields
GL2.AccountID,
ParentAccount.CompanyName,
ParentAccount.AccountNumber,
ParentAccount.PricingPlanTypeID,
ParentAccount.IndustryID,
ParentAccount.RegionID,
ParentAccount.OriginID,
ParentAccount.Marketing3ID,
ParentAccount.BillingAddressID ) AS fx_Return
LEFT JOIN EmployeeGroup WITH(NOLOCK) ON EmployeeGroup.ID = fx_Return.DivisionID
LEFT JOIN MarketingListItem AS Origin WITH(NOLOCK) ON Origin.ID = fx_Return.CompanyOriginID
LEFT JOIN MarketingListItem AS CompanyOriginParent WITH(NOLOCK) ON Origin.ParentID = CompanyOriginParent.ID
AND Origin.ParentClassTypeID = CompanyOriginParent.ClassTypeID
LEFT JOIN MarketingListItem AS Industry WITH(NOLOCK) ON Industry.ID = fx_Return.IndustryID
LEFT JOIN MarketingListItem AS IndustryParent WITH(NOLOCK) ON Industry.ParentID = IndustryParent.ID
AND Industry.ParentClassTypeID = IndustryParent.ClassTypeID
LEFT JOIN MarketingListItem AS OrderOrigin WITH(NOLOCK) ON fx_Return.OrderOriginID = OrderOrigin.ID
LEFT JOIN MarketingListItem AS OrderOriginParent WITH(NOLOCK) ON OrderOrigin.ParentID = OrderOriginParent.ID
AND OrderOrigin.ParentClassTypeID = OrderOriginParent.ClassTypeID
LEFT JOIN Address WITH(NOLOCK) ON fx_Return.CompanyBillingAddressID = Address.ID
LEFT JOIN CustomerGoodsItem AS Product WITH(NOLOCK) ON fx_Return.GoodsItemID = Product.ID
AND Product.ClassTypeID=fx_Return.GoodsItemClassTypeID
LEFT JOIN PricingElement AS ProductCategory WITH(NOLOCK) ON Product.CategoryID = ProductCategory.ID
AND Product.CategoryClassTypeID = ProductCategory.ClassTypeID
LEFT JOIN PricingElement AS ProductSubCategory WITH(NOLOCK) ON ProductCategory.ParentID = ProductSubCategory.ID
AND ProductCategory.ParentClassTypeID = ProductSubCategory.ClassTypeID
LEFT JOIN Employee AS Salesperson1 WITH(NOLOCK) ON fx_Return.SalesPerson1ID = Salesperson1.ID
LEFT JOIN GLAccount WITH(NOLOCK) ON fx_Return.GLAccountID = GLAccount.ID
LEFT JOIN MarketingListItem AS Region WITH(NOLOCK) ON fx_Return.RegionID = Region.ID
) AS Orders
LEFT JOIN ( SELECT SUM( CASE
WHEN #ReportOn <> 'P' THEN -GL3.Amount
WHEN GL3.GLAccountID IN (11, 12, 51) THEN GL3.Amount
WHEN GL3.GLClassificationType IN (4000, 2005) THEN -GL3.Amount
ELSE 0
END ) AS CompanyTotalAmount,
COUNT(DISTINCT TransHeader.ID) AS CompanyOrderCount,
GL3.AccountID AS TotalsAccountID
FROM #GLEntries GL3
LEFT JOIN TransHeader WITH(NOLOCK) ON (TransHeader.ID = GL3.TransHeaderID)
WHERE ( GL3.GLClassificationType in (4000) -- 5002) --Kyle/Scott, we have no clue why this was included, can't think of any expense accounts you'd ever show as a sale
OR
( #ReportOn = 'B' AND GL3.GLAccountID in (12) )
OR
( #ReportOn = 'P' AND GL3.GLAccountID in (11, 12) )
)
GROUP BY GL3.AccountID ) AS Totals ON Totals.TotalsAccountID = Orders.AccountID
WHERE OrderNumber IS NOT NULL
1) OK - so you need to create a table with the same columns and same data types as in the select list (SELECT Orders.*, Totals.*...)
2) You will have to include the insert statement before the select - something like this
insert StagingTableName
select Orders.*, Totals.*...
3) Create a stored procedure with all your code in it.
4) Execute the stored procedure using a SQL Server Agent Job. This link should help.
Related
I'll admit I don't have a lot of DB experience as my last job had a DBA but this place has none. I have an existing MASSIVE stored procedure that I need to modify (I noticed a lot of duplication and cut that out).
Right now, it pulls so much data they used a cache table or the page crashes. They just want a smaller amount of data now for a separate page. I'm trying to edit this stored procedure and merge in my new query to it.
The existing stored procedure:
ALTER PROCEDURE [dbo].[PurchasingSupplyChainNeeds]
(#maxAgeInHours INT = 24)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sqlStmt NVARCHAR(max)
DECLARE #myName NVARCHAR(max) = Object_name(##PROCID)
DECLARE #needsRefresh INT
EXEC #needsRefresh = [cache].[NeedsRefresh]
#myName,
#maxAgeInHours
IF #needsRefresh = 1
BEGIN
DECLARE #CurrentMonth INT
DECLARE #DayOfWeek INT
DECLARE #EndOfWeekDate DATETIME
DECLARE #StartOfNextWeek DATETIME
DECLARE #WorkDaysInMonth INT
DECLARE #RunningDate DATE
DECLARE #WorkDaysLeftInMonth INT
DECLARE #DayOffset INT
SELECT #CurrentMonth = DATEPART(MONTH, GETDATE())
SELECT #DayOfWeek = DATEPART(WEEKDAY, GETDATE())
IF (#DayOfWeek = 1)
BEGIN
SET #StartOfNextWeek = GETDATE()
END
ELSE
BEGIN
SET #StartOfNextWeek = DATEADD(day, 8 - #DayOfWeek, GETDATE())
END
SELECT #DayOfWeek = DATEPART(weekday, GETDATE())
IF (#DayOfWeek = 7)
BEGIN
SET #EndOfWeekDate = Getdate()
END
ELSE
BEGIN
SET #EndOfWeekDate = DATEADD(day, -#DayOfWeek, GETDATE())
END
SET #WorkDaysInMonth = 0
SET #RunningDate = CONVERT(DATE, CONVERT(VARCHAR, #CurrentMonth) + '/1/' + CONVERT(VARCHAR, Datepart(year, Getdate())))
WHILE ( Datepart(month, #RunningDate) = #CurrentMonth )
BEGIN
SET #DayOfWeek = Datepart(weekday, #RunningDate)
IF ( #DayOfWeek != 1
AND #DayOfWeek != 7 )
BEGIN
SET #WorkDaysInMonth = #WorkDaysInMonth + 1
END
SET #RunningDate = Dateadd(day, 1, #RunningDate)
END
SET #WorkDaysLeftInMonth = 0
SET #DayOffset = 0
WHILE ( Datepart(month, Dateadd(day, #DayOffset, Getdate())) = #CurrentMonth )
BEGIN
SET #DayOfWeek = Datepart(weekday, Dateadd(day, #DayOffset, Getdate()))
IF ( #DayOfWeek != 1
AND #DayOfWeek != 7 )
BEGIN
SET #WorkDaysLeftInMonth = #WorkDaysLeftInMonth + 1
END
SET #DayOffset = #DayOffset + 1
END;
WITH j
AS (SELECT Rtrim(Ltrim(imitmidx_sql.item_no)) AS ItemNo,
Rtrim(Ltrim(ISNULL(imitmidx_sql.item_desc_1, ''))) AS ItemDescription1,
Rtrim(Ltrim(ISNULL(imitmidx_sql.item_desc_2, ''))) AS ItemDescription2,
Rtrim(Ltrim(ISNULL(imitmidx_sql.activity_cd, '-'))) AS ActivityCode,
Rtrim(Ltrim(imitmidx_sql.pur_or_mfg)) AS PurchasedOrMfg,
Rtrim(Ltrim(ISNULL(imitmidx_sql.uom, '-'))) AS UOM,
/*
case statements ensure the price, avg_cost & price
are only observed from the item's primary location;
not secondary locations such as Amazon warehouses
*/
CASE
WHEN iminvloc_sql.loc = imitmidx_sql.loc THEN Rtrim(Ltrim(ISNULL(cicmpy.cmp_name, '')))
ELSE ''
END AS VendorName,
CASE
WHEN iminvloc_sql.loc = imitmidx_sql.loc THEN iminvloc_sql.avg_cost
ELSE 0
END AS AverageCost,
CASE
WHEN iminvloc_sql.loc = imitmidx_sql.loc THEN iminvloc_sql.price
ELSE 0
END AS Price,
iminvloc_sql.qty_on_hand AS QtyOnHand,
iminvloc_sql.qty_allocated AS QtyAllocated,
(SELECT ISNULL(qty_on_hand, 0)
FROM iminvloc_sql WITH (NOLOCK)
WHERE item_no = imitmidx_sql.item_no
AND loc = '3IV') AS QtyIn3IV,
(SELECT ISNULL(qty_on_hand, 0)
FROM iminvloc_sql WITH (NOLOCK)
WHERE item_no = imitmidx_sql.item_no
AND loc = '3TI') AS QtyIn3TI,
(SELECT ISNULL(qty_on_hand, 0)
FROM iminvloc_sql WITH (NOLOCK)
WHERE item_no = imitmidx_sql.item_no
AND loc = '3FA') AS QtyIn3FA,
(SELECT ISNULL(Sum(qty_ordered), 0)
FROM (SELECT y.qty_ordered
FROM oeordhdr_sql x WITH (NOLOCK)
INNER JOIN oeordlin_sql y WITH (NOLOCK)
ON x.ord_type = y.ord_type
AND x.ord_no = y.ord_no
WHERE x.ord_type = 'O'
AND x.entered_dt BETWEEN Dateadd(day, 1, Dateadd(week, -52, Cast(#EndOfWeekDate AS DATE))) AND Dateadd(week, -51, Cast(#EndOfWeekDate AS DATE))
AND y.item_no = imitmidx_sql.item_no
AND y.loc = iminvloc_sql.loc
AND x.status != 'L'
UNION ALL
SELECT y.qty_to_ship
FROM (SELECT DISTINCT ord_type,
ord_no,
entered_dt
FROM oehdrhst_sql WITH (NOLOCK)
WHERE ord_type = 'O'
AND entered_dt BETWEEN Dateadd(day, 1, Dateadd(week, -52, Cast(#EndOfWeekDate AS DATE))) AND Dateadd(week, -51, Cast(#EndOfWeekDate AS DATE))) x
INNER JOIN oelinhst_sql y WITH (NOLOCK)
ON x.ord_type = y.ord_type
AND x.ord_no = y.ord_no
WHERE y.item_no = imitmidx_sql.item_no
AND y.loc = iminvloc_sql.loc) s) AS SalesWeek1,
---Sales week 2 to 51 here
(SELECT ISNULL(Sum(qty_ordered), 0)
FROM (SELECT y.qty_ordered
FROM oeordhdr_sql x WITH (NOLOCK)
INNER JOIN oeordlin_sql y WITH (NOLOCK)
ON x.ord_type = y.ord_type
AND x.ord_no = y.ord_no
WHERE x.ord_type = 'O'
AND x.entered_dt BETWEEN Dateadd(day, 1, Dateadd(week, -1, Cast(#EndOfWeekDate AS DATE))) AND #EndOfWeekDate
AND y.item_no = imitmidx_sql.item_no
AND y.loc = iminvloc_sql.loc
AND x.status != 'L'
UNION ALL
SELECT y.qty_to_ship
FROM (SELECT DISTINCT ord_type,
ord_no,
entered_dt
FROM oehdrhst_sql WITH (NOLOCK)
WHERE ord_type = 'O'
AND entered_dt BETWEEN Dateadd(day, 1, Dateadd(week, -1, Cast(#EndOfWeekDate AS DATE))) AND #EndOfWeekDate) x
INNER JOIN oelinhst_sql y WITH (NOLOCK)
ON x.ord_type = y.ord_type
AND x.ord_no = y.ord_no
WHERE y.item_no = imitmidx_sql.item_no
AND y.loc = iminvloc_sql.loc) s) AS SalesWeek52,
(SELECT ISNULL(Sum(qty_ordered), 0)
FROM (SELECT y.qty_ordered
FROM oeordhdr_sql x WITH (NOLOCK)
INNER JOIN oeordlin_sql y WITH (NOLOCK)
ON x.ord_type = y.ord_type
AND x.ord_no = y.ord_no
WHERE x.ord_type = 'O'
AND x.entered_dt BETWEEN Cast('1/1/' + CONVERT(VARCHAR, Datepart(year, Dateadd(year, -2, Getdate()))) AS DATE) AND Cast('1/1/' + CONVERT(VARCHAR, Datepart(year, Dateadd(year, -1, Getdate()))) AS DATE)
AND y.item_no = imitmidx_sql.item_no
AND y.loc = iminvloc_sql.loc
AND x.status != 'L'
UNION ALL
SELECT y.qty_to_ship
FROM (SELECT DISTINCT ord_type,
ord_no,
entered_dt
FROM oehdrhst_sql WITH (NOLOCK)
WHERE ord_type = 'O'
AND entered_dt BETWEEN Cast('1/1/' + CONVERT(VARCHAR, Datepart(year, Dateadd(year, -2, Getdate()))) AS DATE) AND Cast('1/1/' + CONVERT(VARCHAR, Datepart(year, Dateadd(year, -1, Getdate()))) AS DATE)) x
INNER JOIN oelinhst_sql y WITH (NOLOCK)
ON x.ord_type = y.ord_type
AND x.ord_no = y.ord_no
WHERE y.item_no = imitmidx_sql.item_no
AND y.loc = iminvloc_sql.loc) s) AS SalesYear1,
(SELECT ISNULL(Sum(qty_ordered), 0)
FROM (SELECT y.qty_ordered
FROM oeordhdr_sql x WITH (NOLOCK)
INNER JOIN oeordlin_sql y WITH (NOLOCK)
ON x.ord_type = y.ord_type
AND x.ord_no = y.ord_no
WHERE x.ord_type = 'O'
AND x.entered_dt BETWEEN Cast('1/1/' + CONVERT(VARCHAR, Datepart(year, Dateadd(year, -1, Getdate()))) AS DATE) AND Cast('1/1/' + CONVERT(VARCHAR, Datepart(year, Getdate())) AS DATE)
AND y.item_no = imitmidx_sql.item_no
AND y.loc = iminvloc_sql.loc
AND x.status != 'L'
UNION ALL
SELECT y.qty_to_ship
FROM (SELECT DISTINCT ord_type,
ord_no,
entered_dt
FROM oehdrhst_sql WITH (NOLOCK)
WHERE ord_type = 'O'
AND entered_dt BETWEEN Cast('1/1/' + CONVERT(VARCHAR, Datepart(year, Dateadd(year, -1, Getdate()))) AS DATE) AND Cast('1/1/' + CONVERT(VARCHAR, Datepart(year, Getdate())) AS DATE)) x
INNER JOIN oelinhst_sql y WITH (NOLOCK)
ON x.ord_type = y.ord_type
AND x.ord_no = y.ord_no
WHERE y.item_no = imitmidx_sql.item_no
AND y.loc = iminvloc_sql.loc) s) AS SalesYear2,
(SELECT ISNULL(Sum(qty_ordered), 0)
FROM (SELECT y.qty_ordered
FROM oeordhdr_sql x WITH (NOLOCK)
INNER JOIN oeordlin_sql y WITH (NOLOCK)
ON x.ord_type = y.ord_type
AND x.ord_no = y.ord_no
WHERE x.ord_type = 'O'
AND x.entered_dt BETWEEN Cast('1/1/' + CONVERT(VARCHAR, Datepart(year, Getdate())) AS DATE) AND Cast(Getdate() AS DATE)
AND y.item_no = imitmidx_sql.item_no
AND y.loc = iminvloc_sql.loc
AND x.status != 'L'
UNION ALL
SELECT y.qty_to_ship
FROM (SELECT DISTINCT ord_type,
ord_no,
entered_dt
FROM oehdrhst_sql WITH (NOLOCK)
WHERE ord_type = 'O'
AND entered_dt BETWEEN Cast('1/1/' + CONVERT(VARCHAR, Datepart(year, Getdate())) AS DATE) AND Cast(Getdate() AS DATE)) x
INNER JOIN oelinhst_sql y WITH (NOLOCK)
ON x.ord_type = y.ord_type
AND x.ord_no = y.ord_no
WHERE y.item_no = imitmidx_sql.item_no
AND y.loc = iminvloc_sql.loc) s) AS SalesYTD,
CASE
WHEN Datediff(week, imitmidx_sql.activity_dt, Getdate()) > 52 THEN 52
ELSE Datediff(week, imitmidx_sql.activity_dt, Getdate())
END AS ActiveWeeks,
(SELECT ( ISNULL(ForecastQty, 0) / #WorkDaysInMonth ) * #WorkDaysLeftInMonth
FROM HP_PurchasingForecast
WHERE ItemNo = imitmidx_sql.item_no
AND [Month] = Datepart(month, Getdate())
AND [Year] = Datepart(year, Getdate())
AND Active = 1) AS RemainingForecastQty,
(SELECT ISNULL(ForecastQty, 0)
FROM HP_PurchasingForecast
WHERE ItemNo = imitmidx_sql.item_no
AND [Month] = Datepart(month, Getdate())
AND [Year] = Datepart(year, Getdate())
AND Active = 1) AS ForecastQty1,
---ForecastQty 2 to 11
(SELECT ISNULL(ForecastQty, 0)
FROM HP_PurchasingForecast
WHERE ItemNo = imitmidx_sql.item_no
AND [Month] = Datepart(month, Dateadd(month, 11, Getdate()))
AND [Year] = Datepart(year, Dateadd(month, 11, Getdate()))
AND Active = 1) AS ForecastQty12,
( (SELECT ISNULL(Sum(CASE
WHEN receipt_dt IS NULL THEN qty_ordered
ELSE qty_remaining
END), 0)
FROM poordlin_sql WITH (NOLOCK)
WHERE ord_status IN ( 'P', 'R' )
AND item_no = imitmidx_sql.item_no
AND promise_dt IS NOT NULL
AND promise_dt <= CONVERT(DATE, Dateadd(day, 6, #StartOfNextWeek))
AND
(
receipt_dt IS NULL
OR ISNULL(qty_remaining, 0) > 0
)
)
+ (SELECT ISNULL(Sum(y.quantity), 0)
FROM imtrnhdr_sql x WITH (NOLOCK)
INNER JOIN imtrndtl_sql y WITH (NOLOCK)
ON x.transit_no = y.transit_no
WHERE x.status IN ( 'A', 'S' )
AND y.item_no = imitmidx_sql.item_no
AND x.to_loc = iminvloc_sql.loc
AND x.due_date <= CONVERT(DATE, Dateadd(day, 6, #StartOfNextWeek))
AND NOT
(
x.from_loc = '3IV'
AND x.temp_loc = '3TI'
AND x.to_loc = iminvloc_sql.loc
)
) ) AS POQty1,
---POQty 2 to 52
( (SELECT ISNULL(Sum(CASE
WHEN receipt_dt IS NULL THEN qty_ordered
ELSE qty_remaining
END), 0)
FROM poordlin_sql WITH (NOLOCK)
WHERE ord_status IN ( 'P', 'R' )
AND item_no = imitmidx_sql.item_no
AND promise_dt IS NOT NULL
AND promise_dt BETWEEN CONVERT(DATE, Dateadd(day, 357, #StartOfNextWeek)) AND CONVERT(DATE, Dateadd(day, 363, #StartOfNextWeek))
AND
(
receipt_dt IS NULL
OR ISNULL(qty_remaining, 0) > 0
)
)
+ (SELECT ISNULL(Sum(y.quantity), 0)
FROM imtrnhdr_sql x WITH (NOLOCK)
INNER JOIN imtrndtl_sql y WITH (NOLOCK)
ON x.transit_no = y.transit_no
WHERE x.status IN ( 'A', 'S' )
AND y.item_no = imitmidx_sql.item_no
AND x.to_loc = iminvloc_sql.loc
AND x.due_date BETWEEN CONVERT(DATE, Dateadd(day, 357, #StartOfNextWeek)) AND CONVERT(DATE, Dateadd(day, 363, #StartOfNextWeek))
AND NOT
(
x.from_loc = '3IV'
AND x.temp_loc = '3TI'
AND x.to_loc = iminvloc_sql.loc
)
) ) AS POQty52
FROM imitmidx_sql imitmidx_sql WITH (NOLOCK)
LEFT OUTER JOIN iminvloc_sql iminvloc_sql WITH (NOLOCK)
ON imitmidx_sql.item_no = iminvloc_sql.item_no
AND
(
imitmidx_sql.loc = iminvloc_sql.loc /* Primary location for the item */
OR iminvloc_sql.loc = '3FA'/*Amazon Fullfillment Center*/
)
LEFT OUTER JOIN cicmpy cicmpy
ON iminvloc_sql.vend_no = cicmpy.cmp_code
AND cicmpy.cmp_type = 'S'),
i
AS (SELECT [ItemNo],
[ItemDescription1],
[ItemDescription2],
[ActivityCode],
[PurchasedOrMfg],
[UOM],
Max([VendorName]) [VendorName],
Max([AverageCost]) [AverageCost],
Max([Price]) [Price],
Sum([QtyOnHand]) [QtyOnHand],
Sum([QtyAllocated]) [QtyAllocated],
Max([QtyIn3IV]) [QtyIn3IV],
Max([QtyIn3TI]) [QtyIn3TI],
Max([QtyIn3FA]) [QtyIn3FA],
Sum([SalesWeek1]) [SalesWeek1],
---SalesWeek2 to 51
Sum([SalesWeek52]) [SalesWeek52],
Sum([SalesYear1]) [SalesYear1],
Sum([SalesYear2]) [SalesYear2],
Sum([SalesYTD]) [SalesYTD],
Avg([ActiveWeeks]) [ActiveWeeks],
Avg([RemainingForecastQty]) [RemainingForecastQty],
Avg([ForecastQty1]) [ForecastQty1],
---ForecastQty2 to 11
Avg([ForecastQty12]) [ForecastQty12],
Avg([POQty1]) [POQty1],
---POQty2 to 51
Avg([POQty52]) [POQty52]
FROM j
WHERE [PurchasedOrMfg] = 'M'
GROUP BY [ItemNo],
[ItemDescription1],
[ItemDescription2],
[ActivityCode],
[PurchasedOrMfg],
[UOM])
SELECT i.*,
CASE i.ActiveWeeks
WHEN 0 THEN 0
ELSE ( i.SalesWeek52 + i.SalesWeek51 + i.SalesWeek50 + i.SalesWeek49 + i.SalesWeek48 + i.SalesWeek47 ) /
(
CASE
WHEN i.ActiveWeeks < 6 THEN i.ActiveWeeks
ELSE 6
END
)
END AS Last6WeeksAvg,
CASE i.ActiveWeeks
WHEN 0 THEN 0
ELSE ( i.SalesWeek52 + i.SalesWeek51 + i.SalesWeek50 + i.SalesWeek49 + i.SalesWeek48 + i.SalesWeek47 + i.SalesWeek46 + i.SalesWeek45 + i.SalesWeek44 + i.SalesWeek43 + i.SalesWeek42 + i.SalesWeek41 ) /
(
CASE
WHEN i.ActiveWeeks < 12 THEN i.ActiveWeeks
ELSE 12
END
)
END AS Last12WeeksAvg,
CASE i.ActiveWeeks
WHEN 0 THEN 0
ELSE ( i.SalesWeek52 + i.SalesWeek51 + i.SalesWeek50 + i.SalesWeek49 + i.SalesWeek48 + i.SalesWeek47 + i.SalesWeek46 + i.SalesWeek45 + i.SalesWeek44 + i.SalesWeek43 + i.SalesWeek42 + i.SalesWeek41 + i.SalesWeek40 + i.SalesWeek39 + i.SalesWeek38 + i.SalesWeek37 + i.SalesWeek36 + i.SalesWeek35 + i.SalesWeek34 + i.SalesWeek33 + i.SalesWeek32 + i.SalesWeek31 + i.SalesWeek30 + i.SalesWeek29 + i.SalesWeek28 + i.SalesWeek27 + i.SalesWeek26 + i.SalesWeek25 + i.SalesWeek24 + i.SalesWeek23 + i.SalesWeek22 + i.SalesWeek21 + i.SalesWeek20 + i.SalesWeek19 + i.SalesWeek18 + i.SalesWeek17 + i.SalesWeek16 + i.SalesWeek15 + i.SalesWeek14 + i.SalesWeek13 + i.SalesWeek12 + i.SalesWeek11 + i.SalesWeek10 + i.SalesWeek9 + i.SalesWeek8 + i.SalesWeek7 + i.SalesWeek6 + i.SalesWeek5 + i.SalesWeek4 + i.SalesWeek3 + i.SalesWeek2 + i.SalesWeek1 ) / i.ActiveWeeks
END AS Last52WeeksAvg,
( ISNULL(i.RemainingForecastQty, 0) + ISNULL(i.ForecastQty2, 0) + ISNULL(i.ForecastQty3, 0) + ISNULL(i.ForecastQty4, 0) + ISNULL(i.ForecastQty5, 0) + ISNULL(i.ForecastQty6, 0) + ISNULL(i.ForecastQty7, 0) + ISNULL(i.ForecastQty8, 0) + ISNULL(i.ForecastQty9, 0) + ISNULL(i.ForecastQty10, 0) + ISNULL(i.ForecastQty11, 0) + ISNULL(i.ForecastQty12, 0) ) / 52 AS AvgWeeklyForecast,
ISNULL(i.QtyIn3FA, 0) + ISNULL(i.QtyOnHand, 0) + ISNULL(i.QtyIn3TI, 0) - ISNULL(i.QtyAllocated, 0) AS QtyAvailable
INTO #outputToCache
FROM i
SET #sqlStmt = 'select * INTO [cache].[' + #myName + '] from #outputToCache'
EXEC sp_executesql
#sqlStmt
END
SET #sqlStmt = 'select * from [cache].[' + #myName + ']'
EXEC sp_executesql
#sqlStmt
END
My query:
SELECT
tb_1.SubPart AS 'Sub Part',
SUM(tb_1.FinalItemSubPartQuantity) 'Sub Part Quantity Needed',
SUM(tb_1.FinalItemSubPartQuantity * tb_2.SalesWeek1) 'Total Sales Week 1',
--- Total Sales Week 2 to 51 here
SUM(tb_1.FinalItemSubPartQuantity * tb_2.SalesWeek52) 'Total Sales Week 52'
FROM
[009Reports].[dbo].[ANC Parts] tb_1
JOIN
[555].[cache].[PurchasingSupplyChainNeeds] tb_2 ON tb_1.FinalPartNo = tb_2.ItemNo
GROUP BY
tb_1.SubPart
Replacing this query below with mine:
AS (SELECT [ItemNo],
[ItemDescription1],
[ItemDescription2],
This is the error I get:
Msg 208, Level 16, State 1, Line 3168
Invalid object name 'i'
My query has 2 different tables in 2 different databases.
Currently, the stored procedure is using CTEs to create "temporary tables" based on (ugly and monstruous) queries and then use them to fill a table.
In general terms, a CTE is a table made from the results of a query, that's only usable by the immediate next query (this is: you create a CTE, then use it on a SELECT, INSERT, UPDATE... then the CTE gets destroyed).
What the SP is doing is this:
Creates CTE j using info and calculations from certain tables
Uses info from CTE j to create CTE i
Uses info from CTE i to create a temporary table #outputToCache
Dumps info from #outputToCache into a physical table cache.PurchasingSupplyChainNeeds
SELECTs and returns the info from cache.PurchasingSupplyChainNeeds as the resultset from the stored procedure
The error you're getting is because you're replacing the creation of CTE i with your own query, but i is still used later on to fill the temporary table.
Now, you say that what you are trying to achieve, is to retrieve a smaller amount of data from this last "cache" table for a separate page. IF I UNDERSTAND CORRECTLY (emphasized because I'm not 100% sure I got it already) you shouldn't modify this stored procedure (this is, add your query into it) because that would change the output of it, and would break anything that uses it. Not only that, your query is using info from the cache table, but the part you're trying to replace is what creates the CTE i that ultimately fills such table.
If what you really want to do is to change the resultset returned from this SP, then the query you need to replace with your own is the one that's assigned to the #sqlStmt variable at the end, so instead of
SET #sqlStmt = 'select * from [cache].[' + #myName + ']'
you would have
SET #sqlStmt = 'SELECT tb_1.SubPart AS [Sub Part], SUM(tb_1.FinalItemSubPartQuantity) [Sub Part Quantity Needed], SUM(tb_1.FinalItemSubPartQuantity * tb_2.SalesWeek1) [Total Sales Week 1],...'
*Note the change of quoted aliases to square-bracketed ones
If your query is meant to return information for a separate page, you should create another stored procedure with your query and then call this new SP from this separate page. This is of course if this cache table doesn't get emptied/deleted by a different process later on. If this is the case, then you're into a world of pain, as you would either need to duplicate this existing SP almost in its entirety into your new SP and change the output as stated above; add an optional parameter that determines wich output should this SP return (e.g. if the parameter is 1 the output is the same as now, but if the parameter is 2 the output is your query); or change this existing stored procedure to not return a value and make other(s) to calls this one and return information as needed. Probably the last option is the "least ugly" one.
I have removed while loop used before but furnishing exact results. Now everything works fine except parentkey.
How to get "parentkey" in the stored procedure perfectly??
The procedure furnishes wrong results if more than 1 same parent is addded in same/different level of bom. The results shows one parent for all childs. It should show both parents separately with childs. The following part does not furnish exact result in case explained above.
(SELECT MAX(e.idcolumn) FROM #tExplode E WHERE e.fcomponent = b.fparent AND e.fcomprev = b.fparentrev AND e.cfacilityid = b.pfacilityid AND e.idcolumn > 0 ) As parentkey
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'M2M_Std_BOM_Explosion' AND type = 'P')
DROP PROCEDURE M2M_Std_BOM_Explosion
GO
CREATE Procedure [dbo].[M2M_Std_BOM_Explosion]
#pcPartNo CHAR(25),
#pcPartRev CHAR(3),
#pcFac CHAR(20),
#plIndent Bit
As
Begin
set nocount on
if object_id('tempdb..#tExplode') is not null drop table #tExplode
declare #sql as varchar(max) = ''
create table #tExplode
(
ID int not null,
lvl int not null,
CompPath varchar(8000),
ItmPath varchar(8000),
display varchar(100),
fcomponent varchar(25),
cfacilityid varchar(20),
fcomprev varchar(3),
fparent varchar(25),
fparentrev varchar(3),
pfacilityid varchar(20),
fitem varchar(6),
fqty numeric(15,5),
fsumqty numeric(15,5),
fst_ef_dt datetime,
fend_ef_dt datetime,
bomid int,
fnoperno int,
fltooling bit,
fbommemo varchar(8000),
fprodcl varchar(20),
flfssvc bit,
idcolumn Integer,
timestamp_column timestamp,
flextend bit,
fcompudrev varchar(3),
fcparudrev varchar(3),
forder int
)
Insert into #tExplode( ID,lvl,CompPath,ItmPath,display,fcomponent,cfacilityid,fcomprev,
fparent,fparentrev,pfacilityid,fitem,fqty,fsumqty,fst_ef_dt,
fend_ef_dt,bomid,fnoperno,fltooling,fbommemo,flfssvc,flextend,
fcompudrev,fcparudrev,forder,idcolumn)
SELECT 1,
0,
Cast(Rtrim(ltrim(#pcFac))+rtrim(ltrim(#pcPartNo))+rtrim(ltrim(#pcPartRev)) as varchar(8000)),
Cast(rtrim(ltrim(#pcFac))+rtrim(ltrim(#pcPartNo))+rtrim(ltrim(#pcPartRev)) as Varchar(8000)),
cast(1 AS varchar(100)),
#pcPartNo,
#pcFac,
#pcPartRev,
'',
'',
'',
'',
1,
1,
{d '1900-01-01'},
{d '1900-01-01'},
0,
'',
0,
'',
0,
0,
'',
'',
0,
0
FROM (SELECT #pcFac fac,
#pcPartNo fpartno,
#pcPartRev frev) x
LEFT JOIN inrtgc i On i.fac=x.fac And i.fpartno=x.fpartno And i.fcpartrev=x.frev
; WITH t AS (
select ID,lvl,CompPath,ItmPath,display,fcomponent,cfacilityid,fcomprev,
fparent,fparentrev,pfacilityid,fitem,fqty,fsumqty,fst_ef_dt,
fend_ef_dt,
bomid,
fnoperno,
fltooling,
fbommemo,
flfssvc,
flextend,
fcompudrev,
fcparudrev,
forder
from #tExplode
UNION ALL
SELECT b.identity_column,
t.lvl+1,
rtrim(ltrim(t.CompPath)) + '!' + rtrim(ltrim(b.pfacilityid)) + rtrim(ltrim(b.fcomponent)) + Replicate(' ',25-Len(rtrim(ltrim(b.fcomponent))))+ rtrim(ltrim(b.fcomprev + '!')),
rtrim(ltrim(t.ItmPath)) + '!' + rtrim(ltrim(b.fitem)),
Cast(replicate(' ',2*t.lvl) + b.fcomponent as Varchar(100)),
Cast(b.fcomponent as Varchar(25)),
Cast(b.cfacilityid as Varchar(20)),
Cast(b.fcomprev as Varchar(3)),
Cast(b.fparent as Varchar(25)),
Cast(b.fparentrev as Varchar(3)),
Cast(b.pfacilityid as Varchar(20)),
Cast(b.fitem as varchar(6)),
b.fqty,
Cast(CASE
WHEN b.flextend = 1 THEN b.fqty * ISNULL(t.fsumqty, cast(1 AS numeric(15,5)))
ELSE b.fqty
END as Numeric(15,5)),
b.fst_ef_dt,
b.fend_ef_dt,
b.identity_column,
ISNULL(b.fnoperno,cast(0 AS int)),
b.fltooling,
Cast(b.fbommemo as Varchar(8000)),
b.flfssvc,
b.flextend,
Cast(b.fcompudrev as Varchar(3)),
Cast(b.fcparudrev as Varchar(3)),
0
FROM inboms b
inner join t ON b.pFacilityID = t.cFacilityID
AND b.fparent = t.fcomponent
AND b.fparentrev = t.fcomprev
)
insert into #tExplode
(ID,lvl,CompPath,ItmPath,display,fcomponent,cfacilityid,fcomprev,
fparent,fparentrev,pfacilityid,fitem,fqty,fsumqty,fst_ef_dt,
fend_ef_dt,
bomid,
fnoperno,
fltooling,fbommemo,flfssvc,
flextend,
fcompudrev,fcparudrev,forder,idcolumn)
select ID,lvl,CompPath,ItmPath,display,fcomponent,cfacilityid,fcomprev,
fparent,fparentrev,pfacilityid,fitem,fqty,fsumqty,fst_ef_dt,
fend_ef_dt,
bomid,
fnoperno,
fltooling,fbommemo,
flfssvc,
flextend,
fcompudrev,fcparudrev,forder,row_number() over (order by lvl,comppath,cfacilityid,fcomponent,fcomprev,forder) from t
Set #sql = 'select b.idcolumn,b.lvl,
b.comppath,
b.itmpath,
b.display,
CASE WHEN m.fluseudrev = 1 THEN b.fcompudrev ELSE b.fcomprev END as disprev,
b.fitem,
fsource,
b.fqty,
CASE when b.flextend = 1 then b.fsumqty ELSE ((b.fqty * ISNULL(b.fsumqty, cast(1 AS numeric(15,5))))/Isnull(i.fSpq,1)) END as fsumqty,
fmeasure,
b.fnoperno,
CASE WHEN inbomm.fpartno IS NULL THEN SPACE(1) ELSE ''*'' END as isparent, --Working
b.fst_ef_dt,
b.fend_ef_dt,
b.bomid,
b.fcomponent,
b.cfacilityid,
b.fcomprev,
m.fdescript as fdesc,
b.fparent,
b.fparentrev,
b.pfacilityid,
ISNULL(m.identity_column, CAST(0 As Int)) as partid,
fidims,
Case When m.fcstscode=''O'' Then ''Obsolete''
Else
CASE WHEN NOT ((b.fst_ef_dt IS NULL) OR (b.fst_ef_dt={d ''1900-01-01''})) AND
DATEDIFF(day,b.fst_ef_dt, GetDate()) < 0
THEN ''Future''
WHEN NOT ((b.fend_ef_dt IS NULL) OR (b.fend_ef_dt={d ''1900-01-01''})) AND
DATEDIFF(day,b.fEnd_ef_dt, GETDATE()) > 0
THEN ''Expired''
ELSE ''Current''
END
End as effectivity,
b.fltooling,
b.fbommemo,
m.fprodcl,
fllotreqd,
b.flfssvc,
b.timestamp_column,
(SELECT MAX(e.idcolumn) FROM #tExplode E WHERE e.fcomponent = b.fparent AND e.fcomprev = b.fparentrev AND e.cfacilityid = b.pfacilityid AND e.idcolumn > 0 ) As parentkey,
b.flextend,
m.fluseudrev,
b.fcompudrev,
b.fcparudrev,
b.forder
from #tExplode b LEFT OUTER JOIN inmastx m ON
b.cFacilityID = m.fac AND
b.fcomponent = m.fpartno AND
b.fcomprev = m.frev
LEFT OUTER JOIN inbomm ON
b.pfacilityid = inbomm.facilityid AND
b.fComponent = InBomm.fPartno AND
b.fCompRev = InBomm.fcPartRev
LEFT OUTER JOIN inrtgc i ON
b.pfacilityid = i.fac AND
b.fComponent = i.fPartno AND
b.fCompRev = i.fcPartRev
where ' + case when #plIndent= 1 then 'b.lvl >= 1' else 'b.lvl = 1' end + '
order by ' + case when #plIndent= 1 then 'b.comppath,b.cfacilityid,b.fcomponent,b.fcomprev,b.forder' else 'b.comppath,b.forder' end + ''
Exec(#sql)
drop table #tExplode
end
--How to get "parentkey" in the stored procedure perfectly??
--The procedure furnishes wrong results if more than 1 same parent is addded in --same/different level of bom. The results shows one parent for all childs.
I have a SQL server query with me.. When i add a Space anywhere in the Query it changes the result set to 410 rows to 38 rows.
How could this be possible?
Thanks in Advance..
Declare #ReportDate date, #Range varchar(50), #Missing bit = 1
--declare #ReportDate datetime, #Range varchar(50) = '', #Missing bit = 0
--declare #ReportDate date, #Range varchar(50)
declare #RangeId int
set #ReportDate = '30 Apr 2014'
set #Range = ''
select #RangeId = ID from fs.FundGroup where Name = #Range
declare #FundProperty table (FundId int, FundCode varchar(25), FundName varchar(255), FundRange varchar(50), ParentFundCode varchar(25), ParentFundId int, AllocationType varchar(25), SourceName varchar(255), UpdatedSourceName varchar(255), AllocationTypeId int)
if #Range = ''
insert into #FundProperty(FundId, FundCode, FundName, FundRange, AllocationType, SourceName)
select F.FundId, F.FundCode, F.FundName, FG.Name, PT.Name, S.Name
from fs.FundDataSource FDS, fs.Fund F, fs.PropertyType PT, fs.Source S, fs.FundGroup FG
where FDS.FundId = F.FundId
and FDS.PropertyTypeId = PT.Id
and FDS.SourceId = S.Id
and F.FundGroupId = FG.Id
and S.Name like '%PPMA%'
and PT.Name not like '%top10%'
else
insert into #FundProperty(FundId, FundCode, FundName, FundRange, AllocationType, SourceName)
select F.FundId, F.FundCode, F.FundName, FG.Name, PT.Name, S.Name
from fs.FundDataSource FDS, fs.Fund F, fs.PropertyType PT, fs.Source S, fs.FundGroup FG
where FDS.FundId = F.FundId
and FDS.PropertyTypeId = PT.Id
and FDS.SourceId = S.Id
and F.FundGroupId = FG.Id
and S.Name like '%PPMA%'
and PT.Name not like '%top10%'
and F.FundGroupId = #RangeId
update #FundProperty set UpdatedSourceName = SourceName
update #FundProperty set ParentFundId = F1.FundId, ParentFundCode = F1.FundCode
from fs.Fund F1, fs.FundIdentifier FI, #FundProperty FP, fs.Fund F2
where FI.FundId = FP.FundId
and F1.FundCode = FI.[Parent Fund Code]
and F2.FundId = FI.FundId
and F1.FundGroupId = F2.FundGroupId
update #FundProperty set AllocationTypeId = Id from fs.AllocationType AT, #FundProperty FP
where AT.Name = case when FP.AllocationType = 'Rating' then 'Credit Rating' else FP.AllocationType end
--select * from #FundProperty
create table #Allocations(FundCode varchar(25), FundName varchar(255), FundRange varchar(50), AllocationType varchar(50), UpdatedSourceName varchar(255), PositionsName varchar(255), ISIN varchar(50), Percentage float, PPMAName varchar(255), AssetName varchar(255), Maturity varchar(50), SnPRating varchar(25), MoodyRating varchar(25))
insert into #Allocations(FundCode,FundName,FundRange,AllocationType,UpdatedSourceName,PositionsName,ISIN,Percentage)
select distinct FP.ParentFundCode, FP.FundName, FP.FundRange, FP.AllocationType, FP.UpdatedSourceName, ALS.Name, ALS.ISIN, ALC.Percentage
from fs.Allocation ALC, fs.AllocationSecurity ALS, #FundProperty FP
where ALC.AllocationTypeId = ALS.AllocationTypeId
and ALC.SecurityId = ALS.Id
and ALC.FundId = FP.ParentFundId
and ALC.AllocationTypeId = FP.AllocationTypeId
and ALC.ReportDate = #ReportDate
insert into #Allocations(FundCode,FundName,FundRange,AllocationType,UpdatedSourceName,PositionsName,ISIN,Percentage)
select distinct FP.ParentFundCode, FP.FundName, FP.FundRange, FP.AllocationType, FP.UpdatedSourceName, ALS.Name, ALS.ISIN, ALC.Percentage
from fs.Allocation ALC, fs.AllocationSecurity ALS, #FundProperty FP
where ALC.SecurityId = ALS.Id
and ALC.FundId = FP.ParentFundId
and ALC.AllocationTypeId = FP.AllocationTypeId
and FP.FundRange = 'PRULINK PHILIPPINES'
and ALC.ReportDate = #ReportDate
update #Allocations set PPMAName = PPMA.Merrill_Industry___Level_2
from fs.PPMADataExtract PPMA, #Allocations T
where T.AllocationType = 'Sector'
and T.ISIN = PPMA.ISIN
and PPMA.ReportDate = #ReportDate
/*and case when right(PPMA.as_of_date,3) like '/%' --
then convert(datetime,REPLACE(PPMA.As_Of_Date,right(PPMA.As_Of_Date,3),'/20' + right(PPMA.As_Of_Date,2) ),103)
else convert(datetime,PPMA.As_Of_Date,103) end = #ReportDate --*/
update #Allocations set
SnPRating = PPMA.S_P_Rating,
MoodyRating = PPMA.Moody_Rating
from fs.PPMADataExtract PPMA, #Allocations T
where T.AllocationType = 'Rating'
and T.ISIN = PPMA.ISIN
and PPMA.ReportDate = #ReportDate
/*and case when right(PPMA.as_of_date,3) like '/%' --
then convert(datetime,REPLACE(PPMA.As_Of_Date,right(PPMA.As_Of_Date,3),'/20' + right(PPMA.As_Of_Date,2) ),103)
else convert(datetime,PPMA.As_Of_Date,103) end = #ReportDate --*/
update #Allocations set
PPMAName = CONVERT(date,PPMAName,103),
Maturity =
case when convert(float,datediff(day,#ReportDate,convert(date,PPMAName,103)))/365 <= 1 then '0-1 Year'
when convert(float,datediff(day,#ReportDate,convert(date,PPMAName,103)))/365 between 1 and 5 then '1-5 Years'
when convert(float,datediff(day,#ReportDate,convert(date,PPMAName,103)))/365 between 5 and 10 then '5-10 Year'
when convert(float,datediff(day,#ReportDate,convert(date,PPMAName,103)))/365 > 10 then '> 10 Years'
else 'NA'
end
where AllocationType = 'Maturity'
update #Allocations set AssetName = ALS.Name from fs.AllocationSecurity ALS, #Allocations T where T.ISIN = ALS.ISIN
and ALS.AllocationTypeId = 9 and T.FundRange in ('IOF','IOF HK')
--select * from #Allocations
update #Allocations set FundRange = 'IOF SG' where FundRange = 'IOF'
if #Missing = 0
select convert(varchar,#ReportDate,103) [ReportDate], * from #Allocations where
PPMAName is not null
and ISIN <> 'NA'
order by FundName, AllocationType
else
begin
delete from #Allocations where FundRange = 'IOF HK'
select
convert(varchar,#ReportDate,103) [ReportDate],
FundCode,
FundName,
AllocationType,
ISIN,
PositionsName,
Percentage,
PPMAName,
UpdatedSourceName,
AssetName
from #Allocations
where PPMAName is null and SnPRating is null and MoodyRating is null
and ISIN <> 'NA'
order by FundName, AllocationType
end
drop table #Allocations
I have datable where I store my dailyContent selection.
This is different for each day.
When I select more then one day, then I need to return items, which are the same for all days.
I have tried something like this:
SELECT * FROM
(
SELECT
( -- For count
SELECT COUNT(recipeId) AS [Count]
FROM DailyContentDish
WHERE
(
(weekDayId=#mon OR #mon IS NULL) OR
(weekDayId=#tue OR #tue IS NULL) OR
(weekDayId=#wed OR #wed IS NULL) OR
(weekDayId=#thu OR #thu IS NULL) OR
(weekDayId=#fri OR #fri IS NULL) OR
(weekDayId=#sat OR #sat IS NULL) OR
(weekDayId=#sun OR #sun IS NULL)
)
GROUP BY DailyContentDish.recipeId
) AS cnt,
-- End for count
DailyContentDish.dailyContentDishId,
DailyContentDish.recipeId AS Rec,
title,
150 AS calories,
defaultSmallImagePath,
activePreparationTime + passivePreparationTime AS overallPreparationTime,
CAST(
CASE WHEN EXISTS
(
SELECT DailyContentDishFavourite.dailyContentDishFavouriteId
FROM DailyContentDishFavourite
WHERE DailyContentDishFavourite.dailyContentDishId = DailyContentDish.dailyContentDishId
)
THEN 1
ELSE 0
END
AS BIT) AS isFavouriteWhenGeneratingMenu
FROM DailyContentDish
LEFT OUTER JOIN
RecipesTranslations ON RecipesTranslations.recipeId = DailyContentDish.recipeId
LEFT OUTER JOIN
RecipeAdditionalInformation ON RecipeAdditionalInformation.recipeId = DailyContentDish.recipeId
WHERE
isEnabled = 1 AND
mealId=#mealId AND
(
weekDayId=#mon OR
weekDayId=#tue OR
weekDayId=#wed OR
weekDayId=#thu OR
weekDayId=#fri OR
weekDayId=#sat OR
weekDayId=#sun
)
) p
WHERE p.cnt = #daysCount
The problem is, that nested select which should return count returns it for all rows, not just one entry (each row, that is).
Since entries with recipeId are entered more then once I would like to know how many times are they entered.
SELECT
( -- For count
SELECT COUNT(recipeId) AS [Count]
FROM DailyContentDish
WHERE
(
(weekDayId=#mon OR #mon IS NULL) OR
(weekDayId=#tue OR #tue IS NULL) OR
(weekDayId=#wed OR #wed IS NULL) OR
(weekDayId=#thu OR #thu IS NULL) OR
(weekDayId=#fri OR #fri IS NULL) OR
(weekDayId=#sat OR #sat IS NULL) OR
(weekDayId=#sun OR #sun IS NULL)
) AND Something should be here (I guess)
GROUP BY DailyContentDish.recipeId
) AS cnt,
-- End for count
This part should return COUNT of entries for each row I select - but it retuns me COUNT of all entries.
Or should I take a different path with this.
Any hint is greatly appreciated.
I am using MS SQL server 2008
EDIT:
this is whole stored procedure:
#userId int,
#languageId int,
#mealId int,
#mon int,
#tue int,
#wed int,
#thu int,
#fri int,
#sat int,
#sun int,
#orderBy nvarchar(2),
#pageSize int,
#startRowIndex int
AS
BEGIN
SET NOCOUNT ON;
DECLARE #daysCount int
SET #daysCount = 0
IF (#mon IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#tue IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#wed IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#thu IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#fri IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#sat IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#sun IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
-- Insert statements for procedure here
SELECT *
FROM (
SELECT
(
SELECT [Count] = COUNT(recipeId)
FROM dbo.DailyContentDish d
WHERE
(
ISNULL(#mon, weekDayId) = weekDayId OR
ISNULL(#tue, weekDayId) = weekDayId OR
ISNULL(#wed, weekDayId) = weekDayId OR
ISNULL(#thu, weekDayId) = weekDayId OR
ISNULL(#fri, weekDayId) = weekDayId OR
ISNULL(#sat, weekDayId) = weekDayId OR
ISNULL(#sun, weekDayId) = weekDayId
)
GROUP BY d.recipeId
) AS cnt,
d.dailyContentDishId,
d.recipeId AS Rec,
title,
150 AS calories,
defaultSmallImagePath,
activePreparationTime + passivePreparationTime AS overallPreparationTime,
CASE WHEN d2.dailyContentDishId IS NULL THEN 1 ELSE 0 END AS isFavouriteWhenGeneratingMenu
FROM dbo.DailyContentDish d
LEFT JOIN dbo.RecipesTranslations r ON r.recipeId = d.recipeId
LEFT JOIN dbo.RecipeAdditionalInformation t ON t.recipeId = d.recipeId
LEFT JOIN dbo.DailyContentDishFavourite d2 ON d.dailyContentDishId = d2.dailyContentDishId
WHERE isEnabled = 1
AND mealId = #mealId
AND (
weekDayId = #mon OR
weekDayId = #tue OR
weekDayId = #wed OR
weekDayId = #thu OR
weekDayId = #fri OR
weekDayId = #sat OR
weekDayId = #sun
)
) p
WHERE p.cnt = #daysCount
Edit1: I have uploaded diagram:
Here is sample data (for meal Id = 1, this is also selected on form), explanation:
- recipe with ID 125 will be present on Monday (weekDayId = 1) and Saturday (weekDayId = 7). So, this recipe must be returned if I select only Monday OR if I select only Saturday OR if I select Monday and Saturday. If I also select any other day then ithis record is not returned.
- recipe with ID 105 must be returned when weekDays 1, 6 and 7 (Monday, Saturday, Sunday) are selected. Same as above, if any other day is selected then this record is not returned.
Possible this help you -
ALTER PROCEDURE dbo.usp_GetDailyContentDish
#userId INT,
#languageId INT,
#mealId INT,
#mon INT,
#tue INT,
#wed INT,
#thu INT,
#fri INT,
#sat INT,
#sun INT,
#orderBy NVARCHAR(2),
#pageSize INT,
#startRowIndex INT
AS BEGIN
SET NOCOUNT ON;
DECLARE #daysCount INT
SELECT #daysCount =
CASE WHEN #mon IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN #tue IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN #wed IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN #thu IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN #fri IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN #sat IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN #sun IS NOT NULL THEN 1 ELSE 0 END
SELECT
Rec
, calories
, overallPreparationTime
, isFavouriteWhenGeneratingMenu
FROM (
SELECT
(
SELECT [Count] = COUNT(d3.recipeId)
FROM dbo.DailyContentDish d3
WHERE
(
ISNULL(#mon, weekDayId) = weekDayId OR
ISNULL(#tue, weekDayId) = weekDayId OR
ISNULL(#wed, weekDayId) = weekDayId OR
ISNULL(#thu, weekDayId) = weekDayId OR
ISNULL(#fri, weekDayId) = weekDayId OR
ISNULL(#sat, weekDayId) = weekDayId OR
ISNULL(#sun, weekDayId) = weekDayId
) AND d3.recipeId = d.recipeId
GROUP BY d3.recipeId
) AS cnt,
d.dailyContentDishId,
d.recipeId AS Rec,
title,
150 AS calories,
defaultSmallImagePath,
activePreparationTime + passivePreparationTime AS overallPreparationTime,
CASE WHEN d2.dailyContentDishId IS NULL THEN 1 ELSE 0 END AS isFavouriteWhenGeneratingMenu
FROM dbo.DailyContentDish d
LEFT JOIN dbo.RecipesTranslations r ON r.recipeId = d.recipeId
LEFT JOIN dbo.RecipeAdditionalInformation t ON t.recipeId = d.recipeId
LEFT JOIN dbo.DailyContentDishFavourite d2 ON d.dailyContentDishId = d2.dailyContentDishId
WHERE isEnabled = 1
AND mealId = #mealId
AND (
weekDayId = #mon OR
weekDayId = #tue OR
weekDayId = #wed OR
weekDayId = #thu OR
weekDayId = #fri OR
weekDayId = #sat OR
weekDayId = #sun
)
) p
WHERE p.cnt = #daysCount
END
Small off-top:
This:
AND (
weekDayId = #mon OR
weekDayId = #tue OR
weekDayId = #wed OR
weekDayId = #thu OR
weekDayId = #fri OR
weekDayId = #sat OR
weekDayId = #sun
)
Possible optimize to this:
weekDayId % #weekDay = 0
If #mon, #tue is not null and contains 1, 2, ...
SELECT *
FROM (
SELECT
( -- For count
SELECT COUNT(d.recipeId) AS [Count]
FROM DailyContentDish d
WHERE (
ISNULL(#amon, d.weekDayId) = d.weekDayId OR
ISNULL(#tue, d.weekDayId) = d.weekDayId OR
ISNULL(#wed, d.weekDayId) = d.weekDayId OR
ISNULL(#thu, d.weekDayId) = d.weekDayId OR
ISNULL(#fri, d.weekDayId) = d.weekDayId OR
ISNULL(#sat, d.weekDayId) = d.weekDayId OR
ISNULL(#sun, d.weekDayId) = d.weekDayId
) AND d.recipeId = DailyContentDish.recipeId
GROUP BY d.recipeId
) AS cnt,
-- End for count
DailyContentDish.dailyContentDishId,
DailyContentDish.recipeId AS Rec,
title,
150 AS calories,
defaultSmallImagePath,
activePreparationTime + passivePreparationTime AS overallPreparationTime,
CAST(
CASE WHEN EXISTS
(
SELECT DailyContentDishFavourite.dailyContentDishFavouriteId
FROM DailyContentDishFavourite
WHERE DailyContentDishFavourite.dailyContentDishId = DailyContentDish.dailyContentDishId
)
THEN 1
ELSE 0
END
AS BIT) AS isFavouriteWhenGeneratingMenu
FROM DailyContentDish
LEFT OUTER JOIN
RecipesTranslations ON RecipesTranslations.recipeId = DailyContentDish.recipeId
LEFT OUTER JOIN
RecipeAdditionalInformation ON RecipeAdditionalInformation.recipeId = DailyContentDish.recipeId
WHERE
isEnabled = 1 AND
mealId=#mealId AND
(
weekDayId=#mon OR
weekDayId=#tue OR
weekDayId=#wed OR
weekDayId=#thu OR
weekDayId=#fri OR
weekDayId=#sat OR
weekDayId=#sun
)
) p
WHERE p.cnt = #daysCount
UPDATE 21.05.2013(added Demo)
IF OBJECT_ID('tempdb.dbo.#weekDays') IS NOT NULL DROP TABLE dbo.#weekDays
SELECT weekDayId
INTO dbo.#weekDays
FROM(VALUES(#mon),
(#tue),
(#wed),
(#thu),
(#fri),
(#sat),
(#sun))x(weekDayId)
WHERE weekDayId IS NOT NULL
CREATE UNIQUE CLUSTERED INDEX x ON dbo.#weekDays(weekDayId)
SELECT d.dailyContentDishId,
d.recipeId AS Rec,
title,
150 AS calories,
defaultSmallImagePath,
activePreparationTime + passivePreparationTime AS overallPreparationTime,
CASE WHEN f.dailyContentDishId IS NULL THEN 1 ELSE 0 END AS isFavouriteWhenGeneratingMen
FROM DailyContentDish d
LEFT JOIN RecipesTranslations ON RecipesTranslations.recipeId = d.recipeId
LEFT JOIN RecipeAdditionalInformation ON RecipeAdditionalInformation.recipeId = d.recipeId
LEFT JOIN dbo.DailyContentDishFavourite f ON d.dailyContentDishId = f.dailyContentDishId
WHERE d.isEnabled = 1 AND d.mealId = #mealId
AND NOT EXISTS(
SELECT d3.weekDayId
FROM dbo.#weekDays d3
EXCEPT
SELECT d2.WeekDayId
FROM DailyContentDish d2
WHERE d.recipeId = d2.recipeId
AND d2.isEnabled = 1 AND d2.mealId = #mealId
)
Simple demo on SQLFiddle
only meals which are the same for that days (and meals) should be
returned
What is missing is the correlation of the outer query to the count calculation in your inner query. I.e. the following:
( DC1.WeekDayId In( #Mon, #Tue, #Wed, #Thu, #Fri, #Sat, #Sun )
Or Coalesce( #Mon, #Tue, #Wed, #Thu, #Fri, #Sat, #Sun ) Is Null )
And DC1.MealId = DC.MealId
You need to alias at least one of the tables to make this happen. Typically, it is easier to read if you alias the tables on both the inner and outer query. The other item missing is that the seven variables for each day represent ticks ("select this day") instead of the day itself. If we change that, it makes the query simpler.
Select #Mon = Case When #Mon Is Not Null Then 1 End
, #Tue = Case When #Tue Is Not Null Then 2 End
, #Wed = Case When #Wed Is Not Null Then 3 End
, #Thu = Case When #Thu Is Not Null Then 4 End
, #Fri = Case When #Fri Is Not Null Then 5 End
, #Sat = Case When #Sat Is Not Null Then 6 End
, #Sun = Case When #Sun Is Not Null Then 7 End;
Select Count(*) Over() As CountOfResults
, (
Select Count(*)
From DailyContentDish As DC1
Where DC1.weekDayId = DC.weekDayId
) As CountOfDishesOnDay
, (
Select Count(Distinct mealId)
From DailyContentDish As DC1
Where DC1.weekDayId = DC.weekDayId
) As CountOfMeals
, DC.DailyContentDishId
, DC.RecipeId As Rec
, Title
, 150 As Calories
, DefaultsMallImagePath
, ActivePreparationTime
+ PassivePreparationTime As OverallPreparationTime
, Cast (
Case
When Exists (
Select 1
From DailyContentDishFavourite As DF1
Where DF1.DailyContentDishId = DC.DailyContentDishId
) Then 1
Else 0
End
As Bit) As IsFavouriteWhenGeneratingMenu
From DailyContentDish As DC
Left Join RecipesTranslations As RT
On RT.RecipeId = DC.RecipeId
Left Join RecipeAdditionalInformation As RA
On RA.RecipeId = DC.RecipeId
Where DC.IsEnabled = 1
And DC.MealId=#MealId
And DC.WeekDayId In( #Mon, #Tue, #Wed, #Thu, #Fri, #Sat, #Sun )
Addition
If the daily variables are supposed to represent a count of results per day returned (e.g., if #Mon = 2, then we should get back two rows for Monday), then you could do something like so:
Declare #DailyParameters Table
(
DayCount int not null
, DayOfWeek int not null
)
Insert #DailyParameters( DayCount, DayOfWeek )
Select Z.Cnt, Z.DayOfWeek
From (
Select #Mon As Cnt, 1 As DayOfWeek
Union All Select #Tue, 2
Union All Select #Wed, 3
Union All Select #Thu, 4
Union All Select #Fri, 5
Union All Select #Sat, 6
Union All Select #Sun, 7
) As Z
Where Z.Cnt Is Not Null
The Where clause would then change to something like so:
Where DC.IsEnabled = 1
And DC.MealId = #MealId
And DC.WeekDayId In( Select DayOfWeek From #DailyParameters )
And (
Select Count(*)
From DailyContentDish As DC1
Where DC1.weekDayId = DC.weekDayId
) = (
Select D1.DayCount
From #DailyParameters As D1
Where D1.DayOfWeek = DC.weekDayId
)
"Since entries with recipeId are entered more then once I would like to know how many times are they entered."
Base on this statement I would just use the OVER clause with COUNT.
Something like:
SELECT
COUNT(*) OVER (PARTITION BY recipeId) AS 'cnt'
FROM DailyContentDish
I would need more details about the tables and what the output should be in order to provide more details.
Here is more info on the OVER clause in 2008: http://msdn.microsoft.com/en-us/library/ms189461(v=sql.105).aspx
Example using COUNT with OVER: http://blog.sqlauthority.com/2011/08/11/sql-server-tips-from-the-sql-joes-2-pros-development-series-advanced-aggregates-with-the-over-clause-day-11-of-35/
Here is the story: I have to implement filter. And in this filter there are certain categories I filter by.
One of the filters is "favourite" filter (#includeFavourites ).
I have this huge SQL with paging and sorting and everything.
Now, when "includeFavourites" option in filter is clicked, then I also have to select unique ID's from different table (this entries are stored in different datatable), where favourites are stored.
I have tried left outer join, but it returns "number of favourites" records for each record in primary table. Coalesce didn't help at all.
Here is my SQL:
--this is needed because stored procedure must know how many days are selected
DECLARE #daysCount int
SET #daysCount = 0
IF (#mon IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#tue IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#wed IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#thu IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#fri IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#sat IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#sun IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
-- Insert statements for procedure here
SELECT * FROM (
SELECT ROW_NUMBER() OVER
(
ORDER BY
CASE WHEN #OrderBy = 'ND' THEN title END DESC,
CASE WHEN #OrderBy = 'NA' THEN title END,
CASE WHEN #OrderBy = '' THEN title END,
CASE WHEN #OrderBy = 'RD' THEN authorRating END DESC,
CASE WHEN #OrderBy = 'RA' THEN authorRating
) AS Row,
Articles.ArticleId, Articles.userId, Articles.timestamp as datePosted, users.screenName,
defaultSmallImagePath, authorRating, ArticleCosts, title,
FROM Articles
LEFT OUTER JOIN
Users on Articles.userId = Users.userId
LEFT OUTER JOIN
ArticleAdditionalInformation ON ArticleAdditionalInformation.ArticleId = Articles.ArticleId
--JOIN FOR CONTINENT
LEFT OUTER JOIN
Codings as Continent ON Continent.codingKeyId = ArticleAdditionalInformation.continentId AND Continent.languageId = #languageId
-- JOIN FOR COUNTRY
LEFT OUTER JOIN
CodingsAssociated as Country ON Country.codingKeyId = ArticleAdditionalInformation.countryId AND Country.languageId = #languageId
-- JOIN FOR Article TRANSLATION DATA
LEFT OUTER JOIN
ArticlesTranslations ON ArticlesTranslations.ArticleId = Articles.ArticleId AND ArticlesTranslations.languageId=#languageId
LEFT OUTER JOIN
ArticleCategories ON ArticleCategories.ArticleId = Articles.ArticleId
WHERE
(
ArticleCategories.categorieId =1 OR ArticleCategories.categorieId =2 OR
ArticleCategories.categorieId =3 OR ArticleCategories.categorieId =4 OR
ArticleCategories.categorieId = 5
) AND
(ArticlesTranslations.title LIKE '%' + #searchString + '%' OR #searchString IS NULL)
-- COST filter
AND
(ArticleCosts < #cost OR #cost = 0)
AND
(ArticleCosts > 0 OR #cost = 0)
--END cost filter
-- EXCLUDE already stored for selected days
AND Articles.ArticleId -- exclude these ArticleIds
NOT IN
(
SELECT DailyContent.ArticleId
FROM DailyContent
WHERE
sectionId=#sectionId AND
(
weekDayId=#mon OR
weekDayId=#tue OR
weekDayId=#wed OR
weekDayId=#thu OR
weekDayId=#fri OR
weekDayId=#sat OR
weekDayId=#sun
)
GROUP BY
DailyContent.ArticleId
HAVING
(COUNT(sectionId) = #daysCount)
)
-- END exclude
) p
WHERE (Row > #startRowIndex AND Row <=#startRowIndex + #pageSize)
ORDER BY Row
END
So, I would only like to include unique articleIds from favourite table, when #includeFavourites parameter is not null.
Any hint would be greatly appreciated ;)
I am using SQL server 2008.
Try this one -
DECLARE #daysCount INT
SELECT #daysCount =
ISNULL(#mon, 0) + -- if #mon = 1, #tue = 2, .... 1 + (2-1)=1 + (3-2)=1 + ...
ISNULL(#tue - 1, 0) +
ISNULL(#wed - 2, 0) +
ISNULL(#thu - 3, 0) +
ISNULL(#fri - 4, 0) +
ISNULL(#sat - 5, 0) +
ISNULL(#sun - 6, 0)
SELECT *
FROM (
SELECT ROW_NUMBER() OVER
(
ORDER BY
CASE WHEN #OrderBy = 'ND' THEN title END DESC,
CASE WHEN #OrderBy IN ('NA', '') THEN title END,
CASE WHEN #OrderBy = 'RD' THEN authorRating END DESC,
CASE WHEN #OrderBy = 'RA' THEN authorRating
) AS [Row]
, a.ArticleId
, a.userId
, a.[timestamp] as datePosted
, u.screenName
, defaultSmallImagePath
, authorRating
, ArticleCosts
, title
FROM dbo.Articles a -- always use schema and alias
LEFT JOIN dbo.Users u on a.userId = u.userId -- OUTER is unnecessary
LEFT JOIN dbo.ArticleAdditionalInformation aai ON aai.ArticleId = a.ArticleId
LEFT JOIN dbo.Codings cd ON cd.codingKeyId = aai.continentId AND cd.languageId = #languageId
LEFT JOIN dbo.CodingsAssociated c ON c.codingKeyId = aai.countryId AND c.languageId = #languageId
LEFT JOIN dbo.ArticlesTranslations at ON at.ArticleId = a.ArticleId AND at.languageId = #languageId
LEFT JOIN dbo.ArticleCategories ac ON ac.ArticleId = a.ArticleId
WHERE ac.categorieId IN (1, 2, 3, 4, 5)
AND (
at.title LIKE '%' + #searchString + '%'
OR
#searchString IS NULL
)
AND (ArticleCosts < #cost OR #cost = 0)
AND (ArticleCosts > 0 OR #cost = 0)
AND a.ArticleId NOT IN (
SELECT dc2.ArticleId
FROM dbo.DailyContent dc2
WHERE sectionId = #sectionId
AND (
weekDayId % #daysCount = 0 -- possible it's works
--weekDayId = #mon OR
--weekDayId = #tue OR
--weekDayId = #wed OR
--weekDayId = #thu OR
--weekDayId = #fri OR
--weekDayId = #sat OR
--weekDayId = #sun
)
GROUP BY dc2.ArticleId
HAVING COUNT(sectionId) = #daysCount
)
) p
WHERE [Row] BETWEEN #startRowIndex AND #startRowIndex + #pageSize
--ORDER BY [Row] -- ROW_COUNT already sorted your rows