【发布时间】:2019-05-25 15:48:20
【问题描述】:
我正在尝试从一个表中的列中获取值,并将它们与另一个表中多个列的最大值组合在一起,其中第一个表的值作为外键多次出现。我还需要将 SELECT 返回的出现次数限制为 1。
我的(简化的)表格如下所示:
名称: +--+------+ |PK|姓名| +--+------+ | 1|弗雷德| | 2|鲍勃| | 3|乔治| +--+------+ 价值观: +--+----+----+----+--+ |PK|val1|val2|val3|FK| +--+----+----+----+--+ | 1| 1| 2| 5| 2| | 2| 2| 0| 2| 1| | 3| 1| 1|空| 1| | 4| 7| 0|空| 2| | 5| 0| 3| 3| 3| | 6| 5| 2| 2| 3| | 7| 6| 3| 0| 1| | 8| 1| 2| 5| 3| | 9| 0| 2|空| 2| +--+----+----+----+--+
我目前的要求是:
SELECT Name.name, GREATEST(Vals.val1, COALESCE(val2, 0), COALESCE(val3, 0))
FROM Name INNER JOIN (Vals) ON Name.PK = Vals.FK;
目的是获取每个名称出现的最大值。结果应如下所示: 最大值:
+------+---+ |名称|最大| +------+----+ |弗雷德| 6| |鲍勃| 7| |乔治| 5| +--------+---+
但目前我看到的是:
+------+---+ |名称|最大| +------+----+ |弗雷德| 2| |弗雷德| 1| |弗雷德| 6| |鲍勃| 5| |鲍勃| 7| |鲍勃| 2| |乔治| 3| |乔治| 5| |乔治| 5| +--------+---+
我在哪里获得每次出现的名称键的平均值。我不确定是否需要 'WHERE' 或 'GROUP BY' 来解决这个问题,但每次我都尝试过时,我都会遇到错误。例如:
SELECT Name.name, GREATEST(Vals.val1, COALESCE(val2, 0), COALESCE(val3, 0))
FROM Name INNER JOIN (Vals) ON Name.PK = Vals.FK GROUP BY Name.name;
SELECT Name.name, GREATEST(Vals.val1, COALESCE(val2, 0), COALESCE(val3, 0)) WHERE Vals.FK = Name.PK
FROM Name INNER JOIN (Vals) ON Name.PK = Vals.FK;
【问题讨论】:
-
这种问题可能是设计不佳的症状。任何时候你发现自己有枚举的列名(例如,2),警钟应该开始响起。也就是说,
MAX(GREATEST...) ... GROUP BY应该可以解决您的问题 -
由于任务的性质,这些值对应于每个需要跟踪的离散事件(想想每个人进行科学实验时的值)。根据说明,每个值必须以上述方式记录在同一张表中。我很乐意听取如何根据我自己的知识改进设计,但不幸的是,这是不可避免的。
-
通常,您会将值表一分为二。让我们假设它是一张订单表。因此,一张表将保存 order_id 和 customer_id,而另一张表将保存所订购商品的详细信息,可能是 order_id、item_id、数量。看?每个项目都有自己的行;不是它自己的列。
-
顺便说一句,我怀疑你在这里需要 COALESCE。
-
是的,这就是我认为在更实际的情况下会去的地方。在这种情况下是否有替代 COALESCE 来忽略 NULL 的方法?在此之前,The GREATEST 在它们所在的任何行上都返回 NULL。如果有帮助,数据类型是 TINYINT UNSIGNED。