0

我有个问题。考虑 ROLAP 系统中的以下事实和维度表,该系统收集在超市销售的食品中测量的有害物质的值。

事实表:

• Contaminants (TimeID, ShopID, FoodID, substance, quantityPerOunce)
This describes which harmful substance in which quantity was found on a given
food in a given supermarket at a given time.

维度表:

• Time (TimeID, dayNr, dayName, weekNr, monthNr, year)
• Food (FoodID, foodName, brand, foodType)
  Example data: (43, egg, Bioland, animalProduct)
• Place (ShopID, name, street1, region, country)

编写一条 SQL 语句来创建一个回答以下查询的报告:

  • 列出在德国萨克森、图林根和黑森地区每年测量的动物产品和蔬菜(均为 foodTypes)中物质“PCB”的最低含量。
  • 结果应包含年份、地区和最小值。

用同样的说法,也列出

  • 每年的最小值(即每年汇总所有区域)
  • 以及上述地区所有年份和所有地区的动物产品和蔬菜中 PCB 最低数量的总和。

SQL查询

SELECT years, regions, min(quantityPerOunce)
FROM Contaminants as c, Time as t, Food as f, Place as p
WHERE c.TimeID = t.TimeID
AND c.FoodID = f.FoodID
AND c.ShopdID = p.ShopID
AND substance = "PCB"
AND foodType = "vegetables"
AND foodType = "animalProducts"
GROUP BY regions;

我不知道如何解决这种练习。我试过了,但我不知道。即使这不是最好的方式,也应该 加入。Equi-Join

4

1 回答 1

2

你很亲密。首先,请记住,在GROUP BY查询中,您的非聚合字段SELECT也必须出现GROUP BY在行上。所以,你应该有:

GROUP BY years, regions;

此外,如果你使用这个:

foodType = 'vegetables' AND foodType = 'animalProducts'

查询不会返回任何内容,因为 foodType 不能同时是两者。

因此,您需要这个:

(foodType = 'vegetables' OR foodType = 'animalProducts')

或者:

foodType IN ('vegetables','animalProducts')

您的查询假定区域仅包含列出的三个区域。如果您对此不是 100% 确定,最好使用以下命令明确指定它们:

AND regions IN ('Sachsen', 'Thüringen', 'Hessen')

仅此一项还假设这些地区仅在德国。这可能是真的。不过可能不是,所以最安全的方法是添加:

AND country = 'Germany'

所以,沿着这些思路:

SELECT years, regions, MIN(quantityPerOunce) AS min_quantityPerOunce
FROM Contaminants as c, Time as t, Food as f, Place as p
WHERE c.TimeID = t.TimeID
AND c.FoodID = f.FoodID
AND c.ShopdID = p.ShopID
AND substance = 'PCB'
AND foodType IN ('vegetables','animalProducts')
AND regions IN ('Sachsen', 'Thüringen', 'Hessen')
AND country = 'Germany'
GROUP BY years, regions;

如果我弄错了,请原谅我,但这似乎是一项学校作业,因此考虑未来的一般原则可能会有所帮助:

  1. 识别问题陈述中的所有名词(地区名称、国家名称、食品类型名称、物质名称)并确保它们都在查询中表示。如果它们不重要,它们可能不会在问题陈述/客户请求中提及。对于专业环境和教育环境,这是一个很好的经验法则。

  2. 通常,不是聚合的字段SELECT也必须在GROUP BY. 您可以在GROUP BY中拥有不在 中的字段SELECT,但这并不常见。

  3. 对于列出来自同一字段(例如,区域)的某些项目的请求部分,使用field IN (item1,item2,...,itemX)允许OR操作员对每个项目进行操作。

作为附录,如果您有一个名为 的维度表Time,您可能希望在某些系统中将名称用双引号引起来,以避免与通常的某种系统名称混淆。

于 2022-01-20T14:45:54.930 回答