2009-07-02 11 views
2

私のアプリケーションのユーザーが多数の(たとえば)電子メールアドレスを定義できるようにしたいと思います。次に、これらのアドレスを並べ替える機能を提供したいので、プライマリアドレスが上、二次などに表示されます。並べ替え順序を更新するためのシーケンスデータベースフィールドとクエリ

ユーザー(UserId)とユーザー(UserId)をリンクするデータベースにUserEmailAddressesテーブルがあるとします。電子メールアドレス(EmailAddressId)。

1)これらの電子メールアドレスを並べ替える順序を保持するフィールドに、どのデータ型(int、floatなど)を使用する必要がありますか?

2)ユーザーがポジションを再配置したときにこれらのシーケンス番号を変更すると、どのようなクエリが効率的になりますか?複数のレコードを変更する必要がありますか?

(私はC#とLinqを使用していますが、擬似コードはようこそ)。

答えて

3

電子メールアドレスのソート順を格納する整数フィールドを追加する必要があります。

新しい電子メールアドレスが追加されると、次のソート順IDが割り当てられます。アドレスを既存のアドレスよりも上にソートする必要がある場合は、更新ステートメントを使用して、すべての電子メールアドレスをソート順IDで更新し、ソート順インデックスを更新して、ソート順インデックスを更新します。

Table Schema 
----------------------- 
EmailID INT primary Key //Auto increment 
EmailAddress Varchar(N) 
SortOrderIdx INT //This would control your display order 
UserID INT //This would be the owner of this particular email list 

Email Create Statement 
----------------------- 
SELECT @NewSortOrdrIdx = MAX(SortOrderIdx)+1 
FROM EmailTable 
WHERE UserId = @UserID 

INSERT INTO EmailTable (EmailAddress, SortOrderIdx, UserID) 
VALUES (@EmailAddress, @NewSortOrdrIdx, @UserID) 

Email Reorder Statement 
----------------------- 
UPDATE EmailTable 
SET SortOrderIdx = SortOrderIdx + 1 
WHERE SortOrderIdx >= @desired_Sort_Order_Idx AND UserID = @UserID 

UPDATE EmailTable 
SET SortOrderIdx = @desired_Sort_Order_Idx 
WHERE EmailID = @resorted_Email_ID AND UserID = @UserID 

Email Select Statement 
----------------------- 
SELECT EmailAddress 
FROM EmailTable 
WHERE UserID = @UserID 
ORDER BY SortOrderIdx ASC 
+0

を私はあまりにも新しいアドレスを追加する前に、最大のシーケンス番号を照会する必要がありますとします。このメソッドが機能するためには1つのだけの行を更新する必要があります。私はこのようにデータベースから馬鹿げたものをタギングしているようだ...この機能の単なる値段ですか? – Feckmore

1

「衝突」の処理を簡略化したシンプルなデザインです。

UserEmailAddresses Table 
------------------------ 
YourPKHere  <whatever you have, identity?> 
UserId   <whatever you have> 
EmailAddressId <whatever you have> 
DisplaySeq  INT 
LastChgDate  datetime 


SELECT * FROM UserEmailAddresses ORDER BY DisplaySeq ASC, LastChgDate DESC 

EDITサンプルコード

DECLARE @UserEmailAddresses table 
(
    YourPKHere  int identity(1,1) primary key 
    ,UserId   int 
    ,EmailAddressId varchar(100) 
    ,DisplaySeq  INT 
    ,LastChgDate  datetime 
) 

--existing data 
INSERT INTO @UserEmailAddresses values (1,'[email protected]',1,'1/1/2009') 
INSERT INTO @UserEmailAddresses values (1,'[email protected]',2,'2/2/2009') 
INSERT INTO @UserEmailAddresses values (1,'[email protected]',3,'3/3/2009') 
INSERT INTO @UserEmailAddresses values (2,'[email protected]',1,'1/1/2009') 
INSERT INTO @UserEmailAddresses values (2,'[email protected]',2,'2/2/2009') 

--application updates one row, no locking or blocking 
update @UserEmailAddresses set DisplaySeq=1,LastChgDate=getdate() where UserId=1 and EmailAddressId='[email protected]' --could say WHERE YourPKHere=n, but you don't give your complete table schema 


--display the emails in proper order, with displayable continuous row numbers 
SELECT 
    *, ROW_NUMBER() over(partition by UserId order by DisplaySeq ASC,LastChgDate DESC) AS ActualDuisplaySeq 
    FROM @UserEmailAddresses 
    WHERE UserId=1 

--display the e-mails in proper order 
SELECT * FROM @UserEmailAddresses Where UserId=1 ORDER BY DisplaySeq ASC, LastChgDate DESC 
+0

これはかなり賢いです...しかし、2つのアドレスが "トップ"アドレスになるように変更したとしましょう。それぞれのアドレスはDisplaySeq = 1ですが、区別する時間は異なります。 ここで、第2位に3番目の住所を配置したいとしましょう(最初の2つの間に)...私はあなたの提案でそれを行う方法がありません。 – Feckmore

+0

これはユーザーインターフェイスによって異なります。各電話番号がそれぞれの行にあり、ソート値をテキストボックスに入力させ、同時に複数の重複値が必要なテーブルを表示する場合は、記述したとおりにソートされます。彼らが一意にそれらに入るなら問題はない。プログラムでシーケンスの順序を修正したい場合は、常に追加の更新プログラムを実行する必要があります。 –

関連する問題