sql >> データベース >  >> RDS >> Sqlserver

SQL Server 2012で相互適用を行う場合、および内部結合を行う場合

    INNER JOIN およびCROSS APPLYLEFT JOINと同じ およびOUTER APPLY )は非常に密接に関連しています。あなたの例では、エンジンが同じ実行プランを見つけると思います。

    • JOIN 条件を介した2つのセット間のリンクです
    • APPLY 行ごとです サブコール

    しかし、前述のように、オプティマイザーは非常にスマートであり、少なくともそのような簡単なケースでは、同じ結果になることを理解します。

    • JOIN サブセットを収集してリンクしようとします 指定された条件を超えて
    • APPLY 現在の行の値で関連する結果を呼び出そうとします 何度も何度も。

    違いは、 table-valued-functionsの呼び出しにあります (インラインである必要があります -構文!)、XMLメソッド.nodes() より複雑なシナリオで。

    APPLYの使用方法の一例 変数をシミュレートする

    ...行ごとの結果を使用する 変数を使用するような計算:

    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
    

    これは以下と同じですが、読みやすく(そして入力しやすく)なります:

    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
    

    XMLメソッド.nodes()を使用した1つの例

    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);
    

    結果

    a1
    a2
    a3
    

    そしてインライン関数呼び出しの1つの例

    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;
    

    結果

    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. 内部結合を使用したSQLmax()

    2. 文字列を区切り文字として使用して、正規表現を使用して文字列を分割するにはどうすればよいですか?

    3. Oracleで大量のデータを使用して同じテーブルでフィールド比較を行う最速の方法

    4. 共通タグに基づいて関連アイテムを検索するアルゴリズム