2017-03-20 7 views
7

私のCTEに関して正しいロジックに到達するのには苦労しています。CTE行番号の分割

いくつかの背景情報:

タスクが販売役割を持っているすべてのメンバーのためのシステムで生成されます。これは基本的に私のTaskテーブルに複数のレコードを挿入します。 [タスク]タブには、AssignedToRequestedByという列があります。AssignedToには、それぞれの販売メンバーIDがあります。誰もがそれを主張していないため、現在、すべての営業担当者は、タスクを見ることができます:

今すぐタスクは、各営業担当者、そのうちの一つ、に反応することができ、重要ではありませんのために生成されたことを
ApprovalStatusId EntityType  EntityId AssignedTo  RequestedBy 
18    | FooBar  | 281  | 4    | 6 
18    | FooBar  | 281  | 9    | 6 
18    | FooBar  | 281  | 17   | 6 
18    | FooBar  | 281  | 26   | 6 
18    | FooBar  | 281  | 39   | 6 

AssignedToだけでなく、タスクのステータスを変更しますタスク、:

ApprovalStatusId EntityType EntityId AssignedTo RequestedBy 
18    | FooBar  | 281  | 4   | 6 
18    | FooBar  | 281  | 9   | 6 
18    | FooBar  | 281  | 17  | 6 
18    | FooBar  | 281  | 26  | 6 
18    | FooBar  | 281  | 39  | 6 
17    | FooBar  | 281  | 26  | 6 
1    | FooBar  | 281  | 6   | 6 

あなたは上記の表からわかるように、使用者26がタスクに反応して、ステータスを変更しました。これが完了すると、システムはタスクを元の要求されたユーザー6にリダイレクトしました。ステータスもこのアクションを示すように変更されました。

問題:

へ:現在

  1. 、一つだけのユーザ(同上4)は、私が試したどのようなすべての販売ユーザー

に割り当てられたタスクを見て住所#1:

;WITH cte AS 
(
    SELECT task.*, stat.Name AS StatusName, 
     ROW_NUMBER() OVER (PARTITION BY EntityId, EntityType ORDER BY ModifiedData DESC) AS rn 
    FROM dbo.Task task 
    INNER JOIN dbo.ApprovalStatus stat on task.ApprovalStatusId = stat.ApprovalStatusId 
) 

SELECT * 
FROM cte  
WHERE AssignedTo = @resourceId 
AND StatusName like 'Pending%' 
AND rn = 1 

したがって、このSQLの問題の1つはAND rn = 1です。これがポイント1で発生した問題の原因ですが、削除してステータスを変更すると、最新のタスク項目が取得されません。一方、この問題も発生します。

パーティショニングをPARTITION BY EntityId, EntityType, AssignedTo ORDER BY ModifiedData DESCに変更しようとしましたが、問題は、ほとんどの場合rnが1になります。これは売上に基づいて正しい結果を生成しませんグループ。

[更新]:

タスクテーブル定義: enter image description here

サンプルデータ:

Comments  InsertDate      ModifiedData    CommentUserId ApprovalStatusId EntityType  EntityId  TenantId AssignedTo RequestedBy 
...   | 2017-03-20 11:18:06.343| 2017-03-20 11:18:06.343| NULL   | 18    | FooBar  | 75  |7    |4    |42 
...   | 2017-03-20 11:18:06.343| 2017-03-20 11:18:06.343| NULL   | 18    | FooBar  | 75  |7    |6    |42 
...   | 2017-03-20 11:18:06.343| 2017-03-20 11:18:06.343| NULL   | 18    | FooBar  | 75  |7    |9    |42 
...   | 2017-03-20 11:18:06.343| 2017-03-20 11:18:06.343| NULL   | 18    | FooBar  | 75  |7    |17    |42 
...   | 2017-03-20 11:18:06.343| 2017-03-20 11:18:06.343| NULL   | 18    | FooBar  | 75  |7    |26    |42 
...   | 2017-03-20 11:18:06.343| 2017-03-20 11:18:06.343| NULL   | 18    | FooBar  | 75  |7    |39    |42 
...   | 2017-03-20 11:18:06.343| 2017-03-20 11:18:06.343| NULL   | 18    | FooBar  | 75  |7    |67    |42 
...   | 2017-03-20 11:18:06.343| 2017-03-20 11:18:06.343| NULL   | 18    | FooBar  | 75  |7    |10073   |42 
...   | 2017-03-20 11:18:06.343| 2017-03-20 11:18:06.343| NULL   | 18    | FooBar  | 75  |7    |10164   |42 

所望の出力:タスクは唯一であるべき主張

販売ユーザーそれを見ることができる人。言い換えれば、販売ユーザーは(第2のテーブルの例で見ることができる)このレコードを見ることができるはず - 他のすべての販売ユーザーが何も見えないはずです

17    | FooBar  | 281  | 26  | 6 
+0

ここで作業しているスキーマといくつかのテストデータを追加できますか?あなたの質問は、例えば、あなたのサンプルデータのどこにでも 'ModifiedData'カラムを持っていません。あなたは、サンプルデータに基づいて、それを説明しようとするのではなく、望ましい出力を追加してください。 – iamdave

+0

ちょっと@iamdave、返事のおかげで。正直言って、それはかなり関わっているので、私はできる限りベストを打ち破ろうとします。 –

+0

ここの日付の値が同じで、このデータをどのように注文していますか?これはあなたの部分の誤植ですか? – iamdave

答えて

2

あなたが望む結果を示した場合は、あなたの質問は、良いだろうが、私は複数のレコードが最初にあなたのtaskテーブルに挿入されたとき、あなたが代わりにあなたのCTEが返すので、row_number()以外の異なるrankingウィンドウ関数、などdense_rank()

;WITH cte AS 
(
    SELECT task.*, stat.Name AS StatusName, 
     dense_rank() OVER (PARTITION BY EntityId, EntityType ORDER BY ModifiedData DESC) AS dr 
    FROM dbo.Task task 
    INNER JOIN dbo.ApprovalStatus stat on task.ApprovalStatusId = stat.ApprovalStatusId 
) 

SELECT * 
FROM cte  
WHERE AssignedTo = @resourceId 
AND StatusName like 'Pending%' 
AND dr = 1 

の使用を検討されてやりたいかもしれないものだと思う:

+------------------+------------+----------+------------+-------------+----+ 
| ApprovalStatusId | EntityType | EntityId | AssignedTo | RequestedBy | rn | 
+------------------+------------+----------+------------+-------------+----+ 
|    18 | FooBar  |  281 |   4 |   6 | 1 | 
|    18 | FooBar  |  281 |   9 |   6 | 2 | 
|    18 | FooBar  |  281 |   17 |   6 | 3 | 
|    18 | FooBar  |  281 |   26 |   6 | 4 | 
|    18 | FooBar  |  281 |   39 |   6 | 5 | 
+------------------+------------+----------+------------+-------------+----+ 

それは返します:

+------------------+------------+----------+------------+-------------+----+ 
| ApprovalStatusId | EntityType | EntityId | AssignedTo | RequestedBy | dr | 
+------------------+------------+----------+------------+-------------+----+ 
|    18 | FooBar  |  281 |   4 |   6 | 1 | 
|    18 | FooBar  |  281 |   9 |   6 | 1 | 
|    18 | FooBar  |  281 |   17 |   6 | 1 | 
|    18 | FooBar  |  281 |   26 |   6 | 1 | 
|    18 | FooBar  |  281 |   39 |   6 | 1 | 
+------------------+------------+----------+------------+-------------+----+ 

だから、唯一のユーザーのは、保留中のタスクを見ている問題#1を、解決するだろう。

+0

聖なる煙草... 'dense_rank()'について知りませんでした - 実装がビジーであるかどうかを確認することができました - ありがとう –

+0

@RichardBailey助けて嬉しいです! – SqlZim

関連する問題