简体   繁体   中英

Why wouldn't we use INNER JOIN on a Table Valued Function?

After searching online I have not been able to find anything that suggests you can or should use INNER JOIN with a table valued function and I'm curious, why? For example, there is a very common TVF that SSRS report developers use for multi-valued parameters in reports, so they can parse the results as a table.

CREATE FUNCTION [dbo].[ParmSplit] (
    @List nvarchar(MAX),
    @SplitOn nchar(1) )

RETURNS @RtnValue TABLE (
    SplitValue nvarchar(250) )
AS
BEGIN
    WHILE (CHARINDEX(@SplitOn,@List) > 0)
    BEGIN
        INSERT INTO @RtnValue (SplitValue)
        SELECT SplitValue = LTRIM(RTRIM(SUBSTRING(@List,1,CHARINDEX(@SplitOn,@List) - 1)))
        SET @List = SUBSTRING(@List,CHARINDEX(@SplitOn,@List) + LEN(@SplitOn), LEN(@List))
    END

    INSERT INTO @RtnValue (SplitValue)
    SELECT SplitValue = LTRIM(RTRIM(@List))
    RETURN
END

Ok so lets imagine we have a states table, and in our report we have a states multi-valued parameter. We want to match the states passed in the parameter to states in a table. Here is the states table definition:

CREATE TABLE #StateTable (
    StatID int IDENTITY (1,1)
    ,StateCode char(2) );

Insert some records:

INSERT INTO #StateTable 
SELECT 'AL';        
INSERT INTO #StateTable 
SELECT 'AK';        
INSERT INTO #StateTable 
SELECT 'AZ';        
INSERT INTO #StateTable 
SELECT 'AR';        
INSERT INTO #StateTable 
SELECT 'CA';        
INSERT INTO #StateTable 
SELECT 'CO';        
INSERT INTO #StateTable 
SELECT 'CT';        
INSERT INTO #StateTable 
SELECT 'DE';        
INSERT INTO #StateTable 
SELECT 'DC';        
INSERT INTO #StateTable 
SELECT 'FL';        
INSERT INTO #StateTable 
SELECT 'GA';        
INSERT INTO #StateTable 
SELECT 'GU';        
INSERT INTO #StateTable 
SELECT 'HI';        
INSERT INTO #StateTable 
SELECT 'ID';        
INSERT INTO #StateTable 
SELECT 'IL';        
INSERT INTO #StateTable 
SELECT 'IN';        
INSERT INTO #StateTable 
SELECT 'IA';        
INSERT INTO #StateTable 
SELECT 'KS';        
INSERT INTO #StateTable 
SELECT 'KY';        
INSERT INTO #StateTable 
SELECT 'LA';        
INSERT INTO #StateTable 
SELECT 'ME';        
INSERT INTO #StateTable 
SELECT 'MD';   

Now query using the TVF and an INNER JOIN

DECLARE @MultiValuedParameter varchar(500) = 'IA, KS, KY, LA, ME, MD, IN, IL'

SELECT
    StateCode
FROM #StateTable s
INNER JOIN dbo.ParmSplit(@MultiValuedParameter, ',')  p ON s.StateCode = p.SplitValue​

The same query using CROSS APPLY.

DECLARE @MultiValuedParameter varchar(500) = 'IA, KS, KY, LA, ME, MD, IN, IL'

SELECT
    StateCode
FROM #StateTable
CROSS APPLY dbo.ParmSplit(@MultiValuedParameter, ',')
WHERE SplitValue = StateCode 

The CROSS APPLY requires a WHERE clause which effectively creates an INNER JOIN.

I was always curious about this. Even though this example only returns a single column, you could still apply this to a multi-column table result. Why when we talk about TVF are we only supposed to use CROSS APPLY?

In reality, you wouldn't/shouldn't do this. You are applying a TVF with a static value. APPLY (CROSS or OUTER) should be used when the parameter will be dynamic from your dataset.

Any who says you need/should to use APPLY with a TVF? You showed it using a JOIN and I can also see the value is using it as a sub-query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM