我需要什么:所有交叉点,以及该年份的AppData记录(如果有的话,则为null)。应该总是返回38,244条记录。
发生了什么:如果我在2012年运行它,我会得到所有行;如果我在2013年运行它,我只能获得19248行。
在第一个应用程序中,记录被插入到AppData表中。可能会有一些没有年度记录的过境点。在第二次或第三次申请时,它是一个更新记录;总是会有一个与过境相关的记录。
我已经好几天了。任何帮助非常感谢!!
表数据 过境表 - CRID,int
AppData表 AppID,AppDate,AppYear。
ALTER FUNCTION [dbo].[fnGetAppData2]
(
-- Add the parameters for the function here
@app as varchar(4),
@year as varchar(4)
)
RETURNS
@SCLApps TABLE
-- Add the column definitions for the TABLE variable here
(AppCRID int,
AppDate date,
AppNbr int,
AppTruck varchar(10),
Spray bit,
Cut bit,
Inspect bit,
Invoice date,
AppYear int)
AS
BEGIN
--for 1st app
-- Fill the table variable with the rows for your result set
If @app = 1
INSERT @SCLApps (AppCRID,AppDate,AppTruck,Cut,Inspect,Spray,Invoice,AppNbr)
SELECT Crossings.CRID,
--application date
(CASE WHEN @app = 1 THEN
App1Date
WHEN @app = 2 THEN
App2Date
WHEN @app = 3 THEN
App3Date
ELSE
Null
END),
--application truck
(CASE WHEN @app = 1 THEN
App1Truck
WHEN @app = 2 THEN
App2Truck
WHEN @app = 3 THEN
App3Truck
ELSE
Null
END),
--app cut
(CASE WHEN @app = 1 THEN
App1Cut
WHEN @app = 2 THEN
App2Cut
WHEN @app = 3 THEN
App3Cut
ELSE
Null
END),
--app inspect
(CASE WHEN @app = 1 THEN
App1Inspect
WHEN @app = 2 THEN
App2Inspect
WHEN @app = 3 THEN
App3Inspect
ELSE
Null
END),
--app spray
(CASE WHEN @app = 1 THEN
App1Spray
WHEN @app = 2 THEN
App2Spray
WHEN @app = 3 THEN
App3Spray
ELSE
Null
END),
--invoice
(CASE WHEN @app = 1 THEN
App1InvDate
WHEN @app = 2 THEN
App2InvDate
WHEN @app = 3 THEN
App3InvDate
ELSE
Null
END),
--AppNbr
(CASE WHEN @app = 1 THEN
1
WHEN @app = 2 THEN
2
WHEN @app = 3 THEN
3
ELSE
Null
END)
FROM AppData full OUTER JOIN Crossings ON AppData.CRID = Crossings.CRID
WHERE (AppYear = @year or AppYear is null)
ELSE
--for 2nd and 3rd app--------------------------------------
INSERT @SCLApps (AppCRID,AppDate,AppTruck,Cut,Inspect,Spray,Invoice, AppNbr)
SELECT Crossings.CRID,
--application date
(CASE WHEN @app = 1 THEN
App1Date
WHEN @app = 2 THEN
App2Date
WHEN @app = 3 THEN
App3Date
ELSE
''
END),
--application truck
(CASE WHEN @app = 1 THEN
App1Truck
WHEN @app = 2 THEN
App2Truck
WHEN @app = 3 THEN
App3Truck
ELSE
''
END),
--app cut
(CASE WHEN @app = 1 THEN
App1Cut
WHEN @app = 2 THEN
App2Cut
WHEN @app = 3 THEN
App3Cut
ELSE
''
END),
--app inspect
(CASE WHEN @app = 1 THEN
App1Inspect
WHEN @app = 2 THEN
App2Inspect
WHEN @app = 3 THEN
App3Inspect
ELSE
''
END),
--app spray
(CASE WHEN @app = 1 THEN
App1Spray
WHEN @app = 2 THEN
App2Spray
WHEN @app = 3 THEN
App3Spray
ELSE
''
END),
--invoice
(CASE WHEN @app = 1 THEN
App1InvDate
WHEN @app = 2 THEN
App2InvDate
WHEN @app = 3 THEN
App3InvDate
ELSE
''
END),
--AppNbr
(CASE WHEN @app = 1 THEN
1
WHEN @app = 2 THEN
2
WHEN @app = 3 THEN
3
ELSE
''
END)
FROM AppData full OUTER JOIN Crossings ON AppData.CRID = Crossings.CRID
WHERE AppYear = @year
RETURN
END
答案 0 :(得分:1)
即使您正在进行FULL OUTER JOIN,此部分也将消除没有匹配AppData的Crossings:
WHERE AppYear = @year
将最后一部分更改为:
FROM Crossings LEFT JOIN
(SELECT *
FROM AppData
WHERE WHERE AppYear = @year) AS AppData
ON Crossings.CRID = AppData.CRID
作为旁注,case语句有两种格式。您可以使用以下内容进行简化:
CASE @app
WHEN 1 THEN App1Truck
WHEN 2 THEN App2Truck
WHEN 3 THEN App3Truck
ELSE Null END
答案 1 :(得分:0)
首先,您应该使用内联表值函数,而不是使用值为UDF的多语句表。其次,您的UDF有两个主要分支,一个用于@app = 1,另一个用于@app的任何其他值。然而在每个分支中,case语句区分@app = 1,2,3的值。这很明显不正确 其次,正如@jBrooks所指出的,AppYear上的过滤器(如果放在Where子句中)将消除所有在appyear表中没有匹配的行。为了防止这种情况,这个谓词必须是Join On子句的一部分。
试试这个:
CREATE FUNCTION dbo.fnGetAppData2
( @app as varchar(4), @year as varchar(4))
Returns Table
As
Return
(
Select c.CRID,
Case When @app = 1 Then App1Date When @app = 2 Then App2Date
When @app = 3 Then App3Date Else '' End,
Case When @app = 1 Then App1Truck When @app = 2 Then App2Truck
When @app = 3 Then App3Truck Else '' End,
Case When @app = 1 Then App1Cut When @app = 2 Then App2Cut
When @app = 3 Then App3Cut Else '' End,
Case When @app = 1 Then App1Inspect When @app = 2 Then App2Inspect
When @app = 3 Then App3Inspect Else '' End,
Case When @app = 1 Then App1Spray When @app = 2 Then App2Spray
When @app = 3 Then App3Spray Else '' End,
Case When @app = 1 Then App1InvDate When @app = 2 Then App2InvDate
When @app = 3 Then App3InvDate Else '' End,
Case When @app In (1,2,3) Then @app Else '' End
From AppData a Full Join Crossings c
On c.CRID = a.CRID
And AppYear = Coalesce(@year, AppYear)
)
GO