Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Khi chúng tôi áp dụng chéo và khi chúng tôi tham gia nội bộ trong SQL Server 2012

INNER JOINCROSS APPLY (tương tự với LEFT JOINOUTER APPLY ) có liên quan rất chặt chẽ. Trong ví dụ của bạn, tôi giả sử rằng công cụ sẽ tìm thấy cùng một kế hoạch thực thi.

  • Một JOIN là liên kết giữa hai tập hợp qua một điều kiện
  • một APPLY là một người khôn ngoan cuộc gọi phụ

Nhưng - như đã đề cập ở trên - trình tối ưu hóa rất thông minh và sẽ - ít nhất là trong những trường hợp dễ dàng như vậy - hiểu rằng nó hoạt động giống nhau.

  • JOIN sẽ cố gắng thu thập tập hợp con và liên kết nó vượt quá điều kiện được chỉ định
  • APPLY sẽ cố gắng gọi kết quả có liên quan với các giá trị của hàng hiện tại lặp đi lặp lại.

Sự khác biệt là trong cách gọi bảng-giá trị-hàm (phải là nội tuyến -syntax!), với XML-method .nodes() và với các tình huống phức tạp hơn.

Một ví dụ về cách người ta có thể sử dụng APPLY để mô phỏng biến

... để sử dụng kết quả của một hàng thông minh tính toán giống như bạn sử dụng một biến:

DECLARE @dummy TABLE(ID INT IDENTITY, SomeString VARCHAR(100));
INSERT INTO @dummy VALUES('Want to split/this at the two/slashes.'),('And/this/also');

SELECT d.ID
      ,d.SomeString
      ,pos1
      ,pos2
      ,LEFT(d.SomeString,pos1-1)
      ,SUBSTRING(d.SomeString,pos1+1,pos2-pos1-1)
      ,SUBSTRING(d.SomeString,pos2+1,1000)
FROM @dummy AS d
CROSS APPLY(SELECT CHARINDEX('/',d.SomeString) AS pos1) AS x
CROSS APPLY(SELECT CHARINDEX('/',d.SomeString,x.pos1+1) AS pos2) AS y

Điều này giống như sau, nhưng dễ đọc (và nhập) hơn nhiều:

SELECT d.ID
      ,d.SomeString
      ,LEFT(d.SomeString,CHARINDEX('/',d.SomeString)-1)
      ,SUBSTRING(d.SomeString,CHARINDEX('/',d.SomeString)+1,CHARINDEX('/',d.SomeString,(CHARINDEX('/',d.SomeString)+1))-(CHARINDEX('/',d.SomeString)+1))
      ,SUBSTRING(d.SomeString,CHARINDEX('/',d.SomeString,(CHARINDEX('/',d.SomeString)+1))+1,1000)
FROM @dummy AS d

Một ví dụ với XML-method .nodes()

DECLARE @dummy TABLE(SomeXML XML)
INSERT INTO @dummy VALUES
(N'<root>
  <a>a1</a>
  <a>a2</a>
  <a>a3</a>
  <b>Here is b!</b>
</root>');

SELECT All_a_nodes.value(N'.',N'nvarchar(max)')
FROM @dummy
CROSS APPLY SomeXML.nodes(N'/root/a') AS A(All_a_nodes);

Kết quả

a1
a2
a3

Và một ví dụ cho lệnh gọi hàm nội tuyến

CREATE FUNCTION dbo.TestProduceRows(@i INT)
RETURNS TABLE
AS
RETURN
    SELECT TOP(@i) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Nr FROM master..spt_values
GO

CREATE TABLE dbo.TestData(ID INT IDENTITY, SomeString VARCHAR(100),Number INT);
INSERT INTO dbo.TestData VALUES
 ('Show me once',1)
,('Show me twice',2)
,('Me five times!',5);

SELECT *
FROM TestData
CROSS APPLY dbo.TestProduceRows(Number) AS x;

GO
DROP TABLE dbo.TestData;
DROP FUNCTION dbo.TestProduceRows;

Kết quả

1   Show me once    1   1
2   Show me twice   2   1
2   Show me twice   2   2
3   Me five times!  5   1
3   Me five times!  5   2
3   Me five times!  5   3
3   Me five times!  5   4
3   Me five times!  5   5



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Thay đổi Thu thập dữ liệu hoặc Theo dõi Thay đổi - Giống như Bảng Đường mòn Kiểm toán Truyền thống?

  2. tối ưu hóa truy vấn hàng xóm gần nhất trên 70 triệu đám mây điểm không gian mật độ cực cao trên SQL Server 2008

  3. khôi phục cơ sở dữ liệu không thành công khi di chuyển

  4. OPTION (RECOMPILE) luôn nhanh hơn; Tại sao?

  5. Tính tổng số đang chạy trong SQL Server