2008-11-26 53 views
2

我在我的數據庫中有兩個簡單的表。一張包含卡片ID,名稱和文本的「卡片」表格,以及包含卡片ID的「裁決」表格以及詳細說明卡片裁決的文本。如何爲我的數據創建交叉引用表/查詢?

在裁決文本通常不夠,還有在數據庫中另一張卡的參考。在文本中很容易找到它,因爲每張卡都被封裝在文本中的引號內。在裁決文本中引用多張牌並不罕見。

我想要做的是能夠創建一個交叉引用表(或過程,如果它足夠有效),以便當我提交一個卡的查詢時,我可以找到所有直接引用的規則記錄通過Id獲取卡片並獲得卡片名稱在文本中引用的所有統計記錄。

什麼是最好的方法來解決這個問題?我的環境是SQL 2005,但任何一種「數據庫不可知」解決方案在這裏都很受歡迎。

回答

4

這似乎是一個相當簡單和常見的關係問題,可以通過交叉引用表來解決。例如:

CREATE TABLE dbo.Cards (
    id  INT   NOT NULL, 
    name  VARCHAR(50) NOT NULL, 
    card_text VARCHAR(4000) NOT NULL, 
    CONSTRAINT PK_Cards PRIMARY KEY CLUSTERED (id) 
) 
GO 
CREATE TABLE dbo.Card_Rulings (
    card_id  INT   NOT NULL, 
    ruling_number INT   NOT NULL, 
    ruling_text VARCHAR(4000) NOT NULL, 
    CONSTRAINT PK_Card_Rulings PRIMARY KEY CLUSTERED (card_id, ruling_number) 
) 
GO 
CREATE TABLE dbo.Card_Ruling_Referenced_Cards (
    parent_card_id INT NOT NULL, 
    ruling_number  INT NOT NULL, 
    child_card_id  INT NOT NULL, 
    CONSTRAINT PK_Card_Ruling_Referenced_Cards PRIMARY KEY CLUSTERED (parent_card_id, ruling_number, child_card_id) 
) 
GO 
ALTER TABLE dbo.Card_Rulings 
ADD CONSTRAINT FK_CardRulings_Cards FOREIGN KEY (card_id) REFERENCES dbo.Cards(id) 
GO 
ALTER TABLE dbo.Card_Ruling_Referenced_Cards 
ADD CONSTRAINT FK_CardRulingReferencedCards_CardRulings FOREIGN KEY (parent_card_id, ruling_number) REFERENCES dbo.Card_Rulings (card_id, ruling_number) 
GO 
ALTER TABLE dbo.Card_Ruling_Referenced_Cards 
ADD CONSTRAINT FK_CardRulingReferencedCards_Cards FOREIGN KEY (child_card_id) REFERENCES dbo.Cards(id) 
GO 

要獲得所有卡的裁決爲證:

SELECT C.* 
FROM dbo.Card_Rulings CR 
INNER JOIN dbo.Card_Ruling_Referenced_Cards CRRC ON CRRC.parent_card_id = CR.card_id 
INNER JOIN dbo.Cards C ON C.id = CRRC.child_card_id 
WHERE CR.card_id = @card_id 

這是所有關閉:

SELECT * 
FROM dbo.Cards C 
INNER JOIN dbo.Card_Rulings CR ON CR.card_id = C.id 
WHERE C.id = @card_id 

由給定的卡要獲得裁決中引用的所有卡我的頭頂部沒有經過測試,所以可能有語法錯誤等

你的前端將負責˚F或保持參考。這可能是可取的,因爲它避免了某人忘記在裁決文本中圍繞卡名引號等問題。

1

我會建議您創建另一個表,存儲您的參考。然後,創建一個插入和更新觸發器來維護此表。這樣,您將有更快的查詢來返回您正在查找的數據。

我承認,最初填充此表可能會有點困難,這就是爲什麼我顯示了一些樣本數據(和查詢)以下時,你可以用它來讓你開始。

Declare @Card Table(Id Int, Name VarChar(20), CardText VarChar(8000)) 

Declare @Ruling Table(CardId Int, CardRuling VarChar(8000)) 

Insert Into @Card Values(1, 'Card 1', 'This is the card ID = 1') 
Insert Into @Card Values(2, 'Card 2', 'This is the card id = 2.') 
Insert Into @Card Values(3, 'Card 3', 'This is the card id = 3.') 

Insert Into @Ruling Values(1, 'This is the ruling for 1 which references "2"') 
Insert Into @Ruling Values(2, 'This is the ruling for 2 which references nothing') 
Insert Into @Ruling Values(3, 'This is the ruling for 3 which references "1" and "2"') 

Declare @CardId Int 
Set @CardId = 1 

Select * 
From @Card As Card 
     Inner Join @Ruling As Ruling 
      On Card.Id = Ruling.CardId 
     Left Join @Card As CardReferences 
      On Ruling.CardRuling Like '%"' + Convert(VarChar(10), CardReferences.Id) + '"%' 

編輯:

我提出另一個表,因爲你可能會感到失望與此查詢的性能,特別是對於大型表的原因。