我不太确定如何称呼这个问题,但它并不完全是在计算行数。假设我们有关系:
Competition(compId, sport, playerName, medal)
假设属性奖章可以是金、银、铜或空。所以我们有以下数据:
(193, Tennis, John Doe, Gold)
(931, Skiing, Mary White, Bronze)
(193, Tennis, Arnold Black, null)
(182, Bobsledding, John Doe, Gold)
(901, Ping-Pong, Adam Brown, Silver)
(248, Bobsledding, Mary White, Silver)
我很难弄清楚如何回答这个问题:获取所有赢得超过一枚奖牌的运动员的名字。在这个数据中,答案是约翰·多伊和玛丽·怀特。我如何使用关系代数获得该关系的任意数据的答案?
(这是实际作业问题的简化版本,这种简化代表(我希望)我正在努力解决的问题的一部分。比赛、运动和运动员的数量是任意且未知的,但只有 4 个奖牌的可能性)
获取所有赢得超过一枚奖牌的运动员的姓名。
(尚不清楚这意味着什么。赢得了不止一种奖牌?或者已经获得了不止一种奖牌?您的示例答案表明是后者。此外,它将“空”视为另一种奖牌,而不是特别像SQL。)
-- rows where
THERE EXISTS compId,sport,medal,compId1,compId2,medal2 SUCH THAT
in competition [compId] of sport [sport] player [playerName] won [medal]
AND in competition [compId2] of sport [sport2] player [playerName] won [medal2]
AND (compId <> compId2 OR sport <> sport2 OR medal <> medal2)
使用语句简写:
-- rows where
THERE EXISTS compId,sport,medal,compId1,compId2,medal2 SUCH THAT
Competition(compId, sport, playerName, medal)
AND Competition(compId2, sport2, playerName, medal2)
AND (compId <> compId2 OR sport <> sport2 OR medal <> medal2)
重新排列(预计每个 σ 一次比较和每个 ∪ 一个属性集的限制):
-- rows where
THERE EXISTS compId,sport,medal,compId1,compId2,medal2 SUCH THAT
( Competition(compId, sport, playerName, medal)
AND Competition(compId2, sport2, playerName, medal2)
AND compId <> compId2)
OR ( Competition(compId, sport, playerName, medal)
AND Competition(compId2, sport2, playerName, medal2)
AND sport <> sport2)
OR ( Competition(compId, sport, playerName, medal)
AND Competition(compId2, sport2, playerName, medal2)
AND medal <> medal2)
现在替换代数:
每列/属性通过ρ重命名(重命名)。
π playerName (
σ compId <> compId2 (Competition
⋈ ρ compID2/compID ρ sport2/sport ρ medal2/medal Competition)
∪ σ sport <> sport2 (Competition
⋈ ρ compID2/compID ρ sport2/sport ρ medal2/medal Competition)
∪ σ medal <> medal2 (Competition
⋈ ρ compID2/compID ρ sport2/sport ρ medal2/medal Competition)
)
(更多信息请参阅这个答案。)
我知道这是一篇非常老的帖子,但我正在学习这个主题,并且我确实找到了另一种方法来表示练习的要求。也许它对搜索此内容的人有用。
答案:
π Lc.playerName (
ρ Lc σ medal ≠ 'null' Competition
⨝ Lc.playerName = Rc.playerName AND Lc.sport ≠ Rc.sport
ρ Rc σ medal ≠ 'null' Competition)
我假设没有人可以在同一运动项目中获得两枚奖牌,如果有人获得多于一枚奖牌,则必须是在不同的运动项目中。我还假设关系中的每个元组都代表一个奖励,所以......
上面的表达式设法获取不同运动项目中多次出现的playerName。
编辑:我处理空...... 您可以使用此工具查看它的运行情况https://dbis-uibk.github.io/relax/calc.htm
要设置数据,请在“组编辑器”选项卡中使用此代码
group:Competition
Competition = {
compId:number, sport:string , playerName:string, medal:string
193 , 'Tennis' , 'John Doe' , 'Gold'
931 , 'Skiing' , 'Mary White' , 'Bronze'
193 , 'Tennis' , 'Arnold Black' , 'null'
182 , 'Bobsledding', 'John Doe' , 'Gold'
901 , 'Ping-Pong' , 'Adam Brown' , 'Silver'
248 , 'Bobsledding', 'Mary White' , 'Silver'
}
我也有类似的问题。我决定思考如果我将每个人与自己相匹配,然后仅在属性不同时进行过滤,我会得到该属性具有多个值的人,在本例中为奖章。
Player1 = π compId,playerName,medal (ρ Player1 (Competition))
Player2 = π compId,playerName,medal (ρ Player2 (Competition))
π Player1.playerName (σ Player1.medal<>Player.medal (Player1 ⨝ Player1.compId=Player2.compId Player2))