2008-11-26 122 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) + '"%' 

编辑:

我提出另一个表,因为你可能会感到失望与此查询的性能,特别是对于大型表的原因。