2016-08-18 4 views
1

を存在に基づいて、「間違った」値を生成するSQL適用である:ROW_NUMBERはここ句

-- Schema 
DECLARE @ModelItem TABLE (
    ModelItemId UNIQUEIDENTIFIER, 
    MetamodelItemId UNIQUEIDENTIFIER 
) 
DECLARE @MetamodelItemAncestor TABLE (
    MetamodelItemId UNIQUEIDENTIFIER, 
    ParentMetamodelItemId UNIQUEIDENTIFIER, 
    AncestorLevel INT 
) 
DECLARE @SolutionMetamodelItem TABLE (
    MetamodelItemId UNIQUEIDENTIFIER, 
    SolutionId UNIQUEIDENTIFIER 
) 

INSERT INTO @ModelItem VALUES ('EC6AC6A9-684E-E611-8117-00155D026308', '2AB1F075-684E-E611-8117-00155D026308') 
INSERT INTO @MetamodelItemAncestor 
VALUES ('2AB1F075-684E-E611-8117-00155D026308', '2AB1F075-684E-E611-8117-00155D026308', 0), 
('2AB1F075-684E-E611-8117-00155D026308', 'AA12E380-CA4D-E611-8117-00155D026308', 1) 
INSERT INTO @SolutionMetamodelItem 
VALUES ('2AB1F075-684E-E611-8117-00155D026308', 'f612a333-ca4d-e611-8117-00155d026308'), 
('AA12E380-CA4D-E611-8117-00155D026308', 'fc160f3e-ca4d-e611-8117-00155d026308') 

-- query 
DECLARE @ModelItemId TABLE (EntityId UNIQUEIDENTIFIER) 
DECLARE @SolutionId TABLE (EntityId UNIQUEIDENTIFIER) 

INSERT INTO @ModelItemId 
VALUES ('EC6AC6A9-684E-E611-8117-00155D026308') 

INSERT INTO @SolutionId 
VALUES ('f612a333-ca4d-e611-8117-00155d026308'), ('fc160f3e-ca4d-e611-8117-00155d026308') 

SELECT mia.* 
FROM (
    SELECT M.EntityId AS ModelItemId, S.EntityId AS SolutionId 
    FROM @ModelItemId AS M 
    CROSS JOIN @SolutionId AS S 
) AS m 
CROSS APPLY (
    SELECT 
     MI.ModelItemId, 
     OTA.ParentMetamodelItemId AS [MetamodelItemId], 
     ROW_NUMBER() OVER (PARTITION BY [MI].[ModelItemId] ORDER BY [OTA].[AncestorLevel] ASC) AS [AspectRank] 
    FROM @ModelItem AS MI 
    INNER JOIN @MetamodelItemAncestor AS OTA 
     ON MI.MetamodelItemId = OTA.MetamodelItemId 
    WHERE 
     MI.ModelItemId = m.ModelItemId 
     AND EXISTS (
      SELECT 1 
      FROM @SolutionMetamodelItem AS MSMI 
      WHERE MSMI.MetamodelItemId = OTA.ParentMetamodelItemId 
       AND MSMI.SolutionId = m.SolutionId 
     ) 
) mia 

SELECT mia.* 
FROM @ModelItemId AS m 
CROSS APPLY (
    SELECT 
     MI.ModelItemId, 
     OTA.ParentMetamodelItemId AS [MetamodelItemId], 
     ROW_NUMBER() OVER (PARTITION BY [MI].[ModelItemId] ORDER BY [OTA].[AncestorLevel] ASC) AS [AspectRank] 
    FROM @ModelItem as MI 
    INNER JOIN @MetamodelItemAncestor AS OTA 
     ON MI.MetamodelItemId = OTA.MetamodelItemId 
    WHERE 
     MI.ModelItemId = m.EntityId 
     AND EXISTS (
      SELECT 1 
      FROM @SolutionMetamodelItem MSMI 
      WHERE MSMI.MetamodelItemId = OTA.ParentMetamodelItemId 
       AND MSMI.SolutionId IN (SELECT s.EntityId FROM @SolutionId AS s) 
     ) 
) mia 

お知らせAspectRank。 2番目のクエリでは、パーティションに基づいて値が正しく増加しています。

実行計画を見ると、最初のクエリでは、row_number(シーケンスプロジェクト)が@solutionテーブルのスキャンと同時に実行されているようですが、まだ行番号の値が増えていないそこに重複した項目があるからです。

誰かがこれを説明できますか?交差適用クエリは実際にはModelItemIdSolutionIdをパラメータとするUDFであるため、最初のアプローチを使用する必要があります。

答えて

1

外部問合せの各行に対して、相互適用が個別に実行されると仮定します。 - 戻された各行は、第1(かつ唯一)の行です。

なぜ、実際にデータがある場合は、外側のクエリではなく、クロス適用内のロー番号を持つ必要がありますか?

+0

最後に、私のデータとともに 'WHERE'節に' AspectRank = 1'が必要でした。 – Umair

+0

また、行番号( 'APPLY'内のすべて)はUDF内にあります。 – Umair

+0

これで、外側のクエリにrow_number()を追加し、それを派生テーブル内にラップしてAspectRank = 1句を追加します。他の行のデータが何であるかを知ることができないので、なぜUDF内にrow_numberを持たせたいのか理解できません。 –