SQL函数不返回所有行

时间:2013-04-12 14:33:24

标签: sql function

我需要什么:所有交叉点,以及该年份的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

2 个答案:

答案 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