SQL函数未返回所有行
我需要的是:所有交叉点,以及当年的AppData记录(如果有,否则为空)。应始终返回38244条记录 发生了什么:如果我在2012年运行它,我会得到所有的行;如果我在2013年运行它,我只得到19248行 在第一个应用程序中,一条记录被插入到AppData表中。可能会有一些过境点没有这一年的记录。在第二次或第三次申请时,它是一个更新记录;始终存在与交叉口相关联的记录 我已经干了好几天了。非常感谢您的帮助 表数据 交叉口表- 国际广播电台 应用数据表 AppID、AppDate、AppYearSQL函数未返回所有行,sql,function,Sql,Function,我需要的是:所有交叉点,以及当年的AppData记录(如果有,否则为空)。应始终返回38244条记录 发生了什么:如果我在2012年运行它,我会得到所有的行;如果我在2013年运行它,我只得到19248行 在第一个应用程序中,一条记录被插入到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
首先,应该使用内联表值函数,而不是多语句表值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
即使您正在进行完全外部联接,此部分也将消除没有匹配AppData的交叉:
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
不返回所有行意味着与SELECT语句或数据本身相关。对于SELECT语句,请检查条件;对于数据本身,请检查数据是否已按您的要求存在于表中,否则您可以获取表中没有的数据。非常感谢!这正是我所需要的。你是救命恩人!祝你周末愉快!