F
F
footballer2017-08-22 10:21:34
SQL
footballer, 2017-08-22 10:21:34

Why was it necessary to invent OUTER \ CROSS APPLY, if there is a JOIN?

Can someone explain why such a hypothetical syntax could fail (which should work purely logically, but causes an error at the point A.BId "failed to bind the composite identifier A.BId", such as because it cannot be obtained there access to table A):

SELECT BB.B1,
     BB.B2,
       A.A1
  FROM [dbo].[A] as A
  cross join (select top 1 B.B1, B.B2 from [dbo].[B] as B where A.BId = B.Id) as BB

that T-SQL developers had to come up with such a replacement for it:
SELECT BB.B1,
     BB.B2,
       A.A1
  FROM [dbo].[A] as A
  cross apply (select top 1 B.B1, B.B2 from [dbo].[B] as B where A.BId = B.Id) as BB

?
Similarly for OUTER APPLY, why is it needed when it could be done through JOIN (after all, everyone knows what JOIN is, but knows much less about APPLY, and most in such situations will start writing a query with a join, as in the first example, which will not work).
And it also turns out that there is no way to do Right Join through APPLY, but what if it is necessary?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander Kuznetsov, 2017-08-22
@DarkRaven

Here - https://stackoverflow.com/questions/1139160/when-s...
In words - it might be faster. It can also apply a parameterized function to each row and append its result.

I
iLeschikov, 2019-02-05
@iLeschikov

CROSS / OUTER APPLY allows you to cram a table function into the query
, for example, there is a function that parses a string into parts:

CREATE FUNCTION dbo.f_GTDparse (
  @id  INT,
  @gtd VARCHAR(100)
)
RETURNS @data_out TABLE (
  id               INT,
  CustomsCode      VARCHAR(25),
  RegistrationDate VARCHAR(25),
  GTDNumber        VARCHAR(25),
  GoodsNumeric     VARCHAR(25)
) AS
BEGIN

DECLARE @data TABLE (
  id          INT,
  [Selection] VARCHAR(100) NULL
)

INSERT INTO @data (id)
VALUES (@id)
;
WITH Data_RowNumber
AS (
  SELECT id,
         split.value,
         ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) AS RowNumber
    FROM @data
    CROSS APPLY STRING_SPLIT(TRIM(@gtd), '/') AS split
)

INSERT INTO @data_out 
SELECT id,
       [1] AS CustomsCode,
       [2] AS RegistrationDate,
       [3] AS GTDNumber,
       ISNULL([4], '0') AS GoodsNumeric
  FROM Data_RowNumber
  PIVOT (
  MAX([value])
  FOR [RowNumber] IN ([1], [2], [3], [4])
  ) AS p

RETURN
END
GO

And now, to call it in the request, we use
SELECT t.*, f.* FROM table t
OUTER APPLY dbo.f_GTDparse(t.Id, t.[ГТД]) f

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question