【问题标题】:Relational algebra - sql (common operators)关系代数 - sql(常用运算符)
【发布时间】:2020-06-24 20:27:44
【问题描述】:

我有这些关系方案:

Participate (FestivalName, Artist)
Attend(ID, FestivalName)
Prefer (ID, FestivalName)
Like (ID, Artist) 

我想列出只参加节日的人 不是他们的偏好,同时,在其中之一 节日,至少有两位他们喜欢的艺术家参加(所以,2 或 更多的)。最后,出示身份证和节日。

我想通过使用通用运算符来解决这个问题:

selection operator, projection operator, union operator, difference operator and cartesian product

这是一个例子:

ATTEND TABLE
147|HannaBalusa |
147|FestivalTOP |
147|BestFestival|

PREFER TABLE
147|FestivalTOP|

LIKE TABLE
147|PaulMackarney|
147|BobDeylan    |

PARTICIPATE TABLE
HannaBalusa |PaulMackarney |
HannaBalusa |BobMurley     |
FestivalTOP |BobDeylan     |
BestFestival|PaulMackarney |
BestFestival|BobDeylan     |

所以,我应该得到这个输出:

147|BestFestival

我可以通过使用 SQL 来解决这种情况,但是我在使用关系代数时遇到了麻烦。

可以帮助我吗?

【问题讨论】:

标签: relational-algebra


【解决方案1】:

执行您想要的操作的惯用 SQL 查询可能如下所示,它使用的 SQL 功能比您列出的要多。

SELECT A.ID, A.FestivalName
FROM Attend A
JOIN Participate P 
ON A.FestivalName = P.FestivalName --Adds rows with artists for each attended festival
JOIN Like L 
ON L.ID = A.ID AND L.Artist = P.Artist --Leaves only rows with `Like`d artists
WHERE NOT EXISTS (
  SELECT 1 
  FROM Prefer Pr 
  WHERE Pr.ID = A.ID AND Pr.FestivalName = A.FestivalName
) --Removes people who have ever attended a prefered festival
GROUP BY A.ID, A.FestivalName --Allows to count liked artists per festival 
HAVING COUNT(L.Artist) >= 2 --Leaves only festivals with 2 or more liked artists 

要使用您描述的操作,它可能看起来像这样

SELECT DISTINCT S1.ID, S1.FestivalName
FROM (
  SELECT A.ID, A.FestivalName, P.Artist
  FROM Attend A
  CROSS JOIN Participate P  
  CROSS JOIN Like L 
  WHERE A.FestivalName = P.FestivalName --Rows with artists for each attended festival 
  AND L.ID = A.ID AND L.Artist = P.Artist --Leaves only rows with `Like`d artists
) S1
CROSS JOIN ( -- Copy of the first subquery
  SELECT A.ID, A.FestivalName, P.Artist
  FROM Attend A
  CROSS JOIN Participate P  
  CROSS JOIN Like L 
  WHERE A.FestivalName = P.FestivalName
  AND L.ID = A.ID AND L.Artist = P.Artist 
) S2
WHERE S1.ID = S2.ID 
AND S1.FestivalName = S2.FestivalName 
AND S1.Artist != S2.Artist --Removes festivals with only 1 liked artist

MINUS -- Remove all rows with people who ever attended prefered festivals

SELECT ID, FestivalName 
FROM ( --People who attended prefered festivals
  SELECT DISTINCT A.ID
  FROM Attend A
  CROSS JOIN Prefer P
  WHERE A.ID = P.ID AND A.FestivalName = P.FestivalName
) 
CROSS JOIN ( -- All existent festivals
  SELECT FestivalName
  FROM Attend
)

【讨论】:

  • 嗨,Alex,非常感谢您的回复。是的,我有类似的东西,但问题是我想翻译它并使用关系代数,这就是我遇到麻烦的地方。
  • @Student_new 阅读更新。对我来说是深夜,所以我可能在某个地方犯了错误。必须记住我很好的旧关系代数课
  • 嘿亚历克斯;我正在检查你的代码..有些东西对我来说没有意义..我使用这些符号:投影 (Π)、选择 (σ)、并集 (U)、差异 (-) 和笛卡尔积 (X)
  • @Student_new 你首先使 R1 = σ(FROM Attend X Participate X Like, WHERE A.FestivalName = P.FestivalName AND L.ID = A.ID AND L.Artist = P.Artist)。然后取 R2 = Π(R1, COLUMNS: A.ID, A.FestivalName, P.Artist)。然后重命名 R3 = R2,然后 R4 = σ(从 R2 X R3,其中 R2.ID = R3.ID AND R2.FestivalName = R3.FestivalName AND R2.Artist != R3.Artist)。然后使 R5 = σ(FROM Attend X Prefer, WHERE A.ID = P.ID AND A.FestivalName = P.FestivalName), R6 = Π(R5, A.ID) 和 R7 = Π(Attend, FestivalName)。答案是 R4 - (R6 X R7)。那里可能也犯了一些错误
  • 对不起,Alex:这里要做什么:Π(R1, COLUMNS: A.ID, A.FestivalName, P.Artist)?
猜你喜欢
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多