我有一个包含客户订单列表的表(s84_Schedule)。我有第二个表,对订单有评论(s84_ScheduleNotes)。当我从s84_Schedule中提取订单列表时,我会执行左外连接以获取s84_ScheduleNotes的最新评论,因为并不总是对每个订单都有评论。
问题:我还有一个SQL函数,它将逗号分隔的ProductID列表转换为临时表;这个功能似乎没有正常工作。我不明白这些是如何相关的,但是......如果我只使用一个产品ID(意思是,ProductVal变量中没有逗号),则左外连接永远不会从s84_ScheduleNotes中提取最新的注释。但是,如果我在ProductVal中提供以逗号分隔的2个ProductID,则会显示最新的评论。
以下是将CSV转换为临时表的代码(很久以前在某个地方偷了这个)...
CREATE FUNCTION [dbo].[CSVToTable] (@InStr VARCHAR(MAX))
RETURNS @TempTab TABLE
(id int not null)
AS
BEGIN
;-- Ensure input ends with comma
SET @InStr = REPLACE(@InStr + ',', ',,', ',')
DECLARE @SP INT
DECLARE @VALUE VARCHAR(1000)
WHILE PATINDEX('%,%', @INSTR ) <> 0
BEGIN
SELECT @SP = PATINDEX('%,%',@INSTR)
SELECT @VALUE = LEFT(@INSTR , @SP - 1)
SELECT @INSTR = STUFF(@INSTR, 1, @SP, '')
INSERT INTO @TempTab(id) VALUES (@VALUE)
END
RETURN
END
GO
这是我的程序,它提取订单和评论......
CREATE PROCEDURE dbo.GetFilteredSchedule
(
@InstallDateOperator INT,
@InstallDateRange1 DATETIME,
@InstallDateRange2 DATETIME,
@InstallDateDynRange1 INT,
@InstallDateDynRange2 INT,
@CustExpectedOperator INT,
@CustExpectedRange1 DATETIME,
@CustExpectedRange2 DATETIME,
@CustExpectedDynRange1 INT,
@CustExpectedDynRange2 INT,
@CompletedDateOperator INT,
@CompletedDateRange1 DATETIME,
@CompletedDateRange2 DATETIME,
@CompletedDateDynRange1 INT,
@CompletedDateDynRange2 INT,
@ProdInStoreDateOperator INT,
@ProdInStoreDateRange1 DATETIME,
@ProdInStoreDateRange2 DATETIME,
@ProdInStoreDateDynRange1 INT,
@ProdInStoreDateDynRange2 INT,
@InvoiceNumVal VARCHAR(2000),
@InstallerVal VARCHAR(2000),
@CustomerVal VARCHAR(2000),
@SubdivisionVal VARCHAR(2000),
@ProductVal VARCHAR(2000),
@LotNumVal VARCHAR(2000),
@EstimateNumVal VARCHAR(2000),
@SONumVal VARCHAR(2000),
@ProdInStoreVal BIT,
@OrderProcessedVal BIT,
@StatusVal VARCHAR(2000),
@FieldRepVal VARCHAR(2000),
@WorkOrderNumVal VARCHAR(2000),
@WindowVal VARCHAR(2000),
@StoreVal VARCHAR(2000),
@DriverVal VARCHAR(2000),
@YardEmployeeVal VARCHAR(2000),
@TruckTypeVal VARCHAR(2000),
@LotNumExact INT,
@StatusIDExact INT,
@SearchText VARCHAR(2000),
@CustomerIdRestriction VARCHAR(2000),
@OrderBy1 INT,
@OrderBy2 INT
)
AS
BEGIN
SELECT sch.ScheduleID, sch.InstallDate, sch.CustomerExpectedDate, sch.CompletedDate, sch.InvoiceNumber,
sch.InstallerID, sch.CustomerID, sch.SubdivisionID, sch.ProductID, sch.LotNumber, sch.EstimateNumber, sch.SONumber,
sch.ProductInStore, sch.ProductInStoreDate, sch.OrderProcessed, sch.HomeownerInfo, sch.StatusID, sch.FieldRepID,
sch.WindowID, sch.StoreID, sch.ConnectedToProject, sch.DriverEmailAddress, sch.YardEmployeeEmailAddress, sch.TruckTypeID,
installer.InstallerName AS 'InstallerName',
customer.CustomerName AS 'CustomerName',
subdivision.SubdivisionName AS 'SubdivisionName',
product.ProductName AS 'ProductName',
fieldRep.FieldRepName AS 'FieldRepName',
window.WindowName AS 'WindowName',
store.StoreName AS 'StoreName',
stat.StatusName AS 'StatusName',
driver.LastName AS 'DriverLastName', driver.FirstName AS 'DriverFirstName',
yardEmployee.LastName AS 'YardEmployeeLastName', yardEmployee.FirstName AS 'YardEmployeeFirstName',
truckType.TruckTypeName AS 'TruckTypeName',
sch.ScheduleID AS id,
Cast(customer.CustomerName AS VARCHAR(2000)) + ' - ' + Cast(sch.LotNumber AS VARCHAR(2000)) + ' - ' + Cast(subdivision.SubdivisionName AS VARCHAR(2000)) + ' - ' + Cast(product.ProductName AS VARCHAR(2000)) AS 'title',
CONVERT(VARCHAR(50), sch.CustomerExpectedDate, 101) + ' ' + CONVERT(VARCHAR, DATEPART(hh, sch.CustomerExpectedDate)) + ':' + RIGHT('0' + CONVERT(VARCHAR, DATEPART(mi, sch.CustomerExpectedDate)), 2) AS 'start',
CONVERT(VARCHAR(50), DATEADD(hh, 1, sch.CustomerExpectedDate), 101) AS 'end',
stat.StatusColor AS 'backgroundColor',
note.NoteText AS 'NoteText'
FROM s84_Schedule sch
LEFT OUTER JOIN dbo.s84_ScheduleNotes AS note ON note.ScheduleID = (SELECT MAX(n.ScheduleNoteID) FROM dbo.s84_ScheduleNotes n WHERE n.ScheduleID = sch.ScheduleID)
JOIN dbo.s84_Installer AS installer ON sch.InstallerID = installer.InstallerID
JOIN dbo.s84_Customer AS customer on sch.CustomerID = customer.CustomerID
JOIN dbo.s84_Subdivision AS subdivision ON sch.SubdivisionID = subdivision.SubdivisionID
JOIN dbo.s84_Product AS product ON sch.ProductID = product.ProductID
JOIN dbo.s84_FieldRep AS fieldRep ON sch.FieldRepID = fieldRep.FieldRepID
JOIN dbo.s84_Window AS window ON sch.WindowID = window.WindowID
JOIN dbo.s84_Store AS store ON sch.StoreID = store.StoreID
JOIN dbo.s84_Status AS stat ON sch.StatusID = stat.StatusID
JOIN dbo.s84_TruckType AS truckType ON sch.TruckTypeID = truckType.TruckTypeID
LEFT OUTER JOIN dbo.s84_Employee AS driver ON ((@DriverVal IS NOT NULL) AND (driver.EmailAddress = @DriverVal))
LEFT OUTER JOIN dbo.s84_Employee AS yardEmployee ON ((@YardEmployeeVal IS NOT NULL) AND (yardEmployee.EmailAddress = @YardEmployeeVal))
WHERE
(@InvoiceNumVal IS NULL OR (sch.InvoiceNumber LIKE '%' + @InvoiceNumVal + '%')) AND
(@InstallerVal IS NULL OR (installer.InstallerID = @InstallerVal)) AND
(@CustomerVal IS NULL OR (customer.CustomerName LIKE '%' + @CustomerVal + '%')) AND
(@SubdivisionVal IS NULL OR (subdivision.SubdivisionName LIKE '%' + @SubdivisionVal + '%')) AND
(@ProductVal IS NULL OR ( sch.ProductID IN (SELECT * FROM dbo.CSVToTable(@ProductVal)) )) AND
(@LotNumVal IS NULL OR (sch.LotNumber LIKE '%' + @LotNumVal + '%')) AND
(@EstimateNumVal IS NULL OR (sch.EstimateNumber LIKE '%' + @EstimateNumVal + '%')) AND
(@SONumVal IS NULL OR (sch.SONumber LIKE '%' + @SONumVal + '%')) AND
(@ProdInStoreVal IS NULL OR (sch.ProductInStore = @ProdInStoreVal)) AND
(@OrderProcessedVal IS NULL OR (sch.OrderProcessed = @OrderProcessedVal)) AND
(@FieldRepVal IS NULL OR (fieldRep.FieldRepID = @FieldRepVal)) AND
(@WorkOrderNumVal IS NULL OR (sch.ScheduleID LIKE '%' + @WorkOrderNumVal + '%')) AND
(@WindowVal IS NULL OR (window.WindowName LIKE '%' + @WindowVal + '%')) AND
(@StoreVal IS NULL OR (store.StoreName LIKE '%' + @StoreVal + '%')) AND
(@DriverVal IS NULL OR ((driver.FirstName LIKE '%' + @DriverVal + '%') OR (driver.LastName LIKE '%' + @DriverVal + '%'))) AND
(@YardEmployeeVal IS NULL OR ((yardEmployee.FirstName LIKE '%' + @YardEmployeeVal + '%') OR (yardEmployee.LastName LIKE '%' + @YardEmployeeVal + '%'))) AND
(@TruckTypeVal IS NULL OR (truckType.TruckTypeName LIKE '%' + @TruckTypeVal + '%')) AND
(@LotNumExact IS NULL OR (sch.LotNumber = @LotNumExact)) AND
(@StatusIDExact IS NULL OR (sch.StatusID = @StatusIDExact)) AND
(@CustomerIdRestriction IS NULL OR ( sch.CustomerID IN (SELECT * FROM dbo.CSVToTable(@CustomerIdRestriction)) )) AND
(@StatusVal IS NULL OR
( sch.StatusID IN (SELECT * FROM dbo.CSVToTable(@StatusVal)) OR
(
('9999' IN (SELECT * FROM dbo.CSVToTable(@StatusVal)) ) AND
( sch.StatusID NOT IN (SELECT * FROM (VALUES ('1'), ('2'), ('3'), ('4')) AS X(id)) )
)
)
) AND
(((@InstallDateOperator IS NULL) OR (@InstallDateOperator = 99)) OR
(@InstallDateOperator = 1 AND sch.InstallDate = @InstallDateRange1) OR
(@InstallDateOperator = 2 AND sch.InstallDate <= @InstallDateRange1) OR
(@InstallDateOperator = 3 AND sch.InstallDate >= @InstallDateRange1) OR
(@InstallDateOperator = 4 AND sch.InstallDate >= @InstallDateRange1 AND sch.InstallDate <= @InstallDateRange2) OR
(@InstallDateOperator = 5 AND sch.InstallDate BETWEEN DATEADD(mm,-@InstallDateDynRange1,GETDATE()) AND DATEADD(mm,@InstallDateDynRange2,GETDATE()))
) AND
(((@CustExpectedOperator IS NULL) OR (@CustExpectedOperator = 99)) OR
(@CustExpectedOperator = 1 AND sch.CustomerExpectedDate = @CustExpectedRange1) OR
(@CustExpectedOperator = 2 AND sch.CustomerExpectedDate <= @CustExpectedRange1) OR
(@CustExpectedOperator = 3 AND sch.CustomerExpectedDate >= @CustExpectedRange1) OR
(@CustExpectedOperator = 4 AND sch.CustomerExpectedDate >= @CustExpectedRange1 AND sch.CustomerExpectedDate <= @CustExpectedRange2) OR
(@CustExpectedOperator = 5 AND sch.CustomerExpectedDate BETWEEN DATEADD(mm,-@CustExpectedDynRange1,GETDATE()) AND DATEADD(mm,@CustExpectedDynRange2,GETDATE()))
) AND
(((@CompletedDateOperator IS NULL) OR (@CompletedDateOperator = 99)) OR
(@CompletedDateOperator = 1 AND sch.CompletedDate = @CompletedDateRange1) OR
(@CompletedDateOperator = 2 AND sch.CompletedDate <= @CompletedDateRange1) OR
(@CompletedDateOperator = 3 AND sch.CompletedDate >= @CompletedDateRange1) OR
(@CompletedDateOperator = 4 AND sch.CompletedDate >= @CompletedDateRange1 AND sch.CompletedDate <= @CompletedDateRange2) OR
(@CompletedDateOperator = 5 AND sch.CompletedDate BETWEEN DATEADD(mm,-@CompletedDateDynRange1,GETDATE()) AND DATEADD(mm,@CompletedDateDynRange2,GETDATE()))
) AND
(((@ProdInStoreDateOperator IS NULL) OR (@ProdInStoreDateOperator = 99)) OR
(@ProdInStoreDateOperator = 1 AND sch.ProductInStoreDate = @ProdInStoreDateRange1) OR
(@ProdInStoreDateOperator = 2 AND sch.ProductInStoreDate <= @ProdInStoreDateRange1) OR
(@ProdInStoreDateOperator = 3 AND sch.ProductInStoreDate >= @ProdInStoreDateRange1) OR
(@ProdInStoreDateOperator = 4 AND sch.ProductInStoreDate >= @ProdInStoreDateRange1 AND sch.ProductInStoreDate <= @ProdInStoreDateRange2) OR
(@ProdInStoreDateOperator = 5 AND sch.ProductInStoreDate BETWEEN DATEADD(mm,-@ProdInStoreDateDynRange1,GETDATE()) AND DATEADD(mm,@ProdInStoreDateDynRange2,GETDATE()))
) AND
((@SearchText IS NULL) OR
( sch.InvoiceNumber LIKE '%' + @SearchText + '%' OR
installer.InstallerName LIKE '%' + @SearchText + '%' OR
customer.CustomerName LIKE '%' + @SearchText + '%' OR
subdivision.SubdivisionName LIKE '%' + @SearchText + '%' OR
product.ProductName LIKE '%' + @SearchText + '%' OR
sch.LotNumber LIKE '%' + @SearchText + '%' OR
sch.EstimateNumber LIKE '%' + @SearchText + '%' OR
sch.SONumber LIKE '%' + @SearchText + '%' OR
stat.StatusName LIKE '%' + @SearchText + '%' OR
fieldRep.FieldRepName LIKE '%' + @SearchText + '%' OR
sch.ScheduleID LIKE '%' + @SearchText + '%' OR
window.WindowName LIKE '%' + @SearchText + '%' OR
store.StoreName LIKE '%' + @SearchText + '%'
))
ORDER BY
CASE @OrderBy2
WHEN 1 THEN sch.InstallDate
WHEN 2 THEN sch.CustomerExpectedDate
WHEN 3 THEN sch.CustomerExpectedDate
WHEN 4 THEN sch.CompletedDate
WHEN 5 THEN sch.InvoiceNumber
WHEN 6 THEN installer.InstallerName
WHEN 7 THEN customer.CustomerName
WHEN 8 THEN subdivision.SubdivisionName
WHEN 9 THEN product.ProductName
WHEN 10 THEN sch.LotNumber
WHEN 11 THEN sch.EstimateNumber
WHEN 12 THEN sch.SONumber
WHEN 13 THEN sch.ProductInStore
WHEN 14 THEN sch.ProductInStoreDate
WHEN 15 THEN sch.OrderProcessed
WHEN 16 THEN stat.StatusName
WHEN 17 THEN fieldRep.FieldRepName
WHEN 18 THEN window.WindowName
WHEN 19 THEN store.StoreName
WHEN 20 THEN driver.LastName
WHEN 21 THEN yardEmployee.LastName
ELSE sch.CustomerExpectedDate
END,
CASE @OrderBy1
WHEN 1 THEN sch.InstallDate
WHEN 2 THEN sch.CustomerExpectedDate
WHEN 3 THEN sch.CustomerExpectedDate
WHEN 4 THEN sch.CompletedDate
WHEN 5 THEN sch.InvoiceNumber
WHEN 6 THEN installer.InstallerName
WHEN 7 THEN customer.CustomerName
WHEN 8 THEN subdivision.SubdivisionName
WHEN 9 THEN product.ProductName
WHEN 10 THEN sch.LotNumber
WHEN 11 THEN sch.EstimateNumber
WHEN 12 THEN sch.SONumber
WHEN 13 THEN sch.ProductInStore
WHEN 14 THEN sch.ProductInStoreDate
WHEN 15 THEN sch.OrderProcessed
WHEN 16 THEN stat.StatusName
WHEN 17 THEN fieldRep.FieldRepName
WHEN 18 THEN window.WindowName
WHEN 19 THEN store.StoreName
WHEN 20 THEN driver.LastName
WHEN 21 THEN yardEmployee.LastName
ELSE sch.CustomerExpectedDate
END;
END;
GO
当我为dbo.GetFilteredSchedule程序提供值时,这些是我设置的变量......
这是我的桌子看起来像的打印屏幕......
答案 0 :(得分:1)
这看起来不对:
LEFT OUTER JOIN dbo.s84_ScheduleNotes AS note
ON note.ScheduleID = (SELECT MAX(n.ScheduleNoteID) FROM dbo.s84_ScheduleNotes n WHERE n.ScheduleID = sch.ScheduleID)
我相信note.ScheduleID应该是note.ScheduleNoteID