MySQL根据DISTINCT有条件地填充第3列,涉及一个表中的2个其他列

时间:2012-06-25 17:07:28

标签: mysql

有一个很好的阅读相似的主题,但我不能a)找到一个符合我的情况,或b)了解其他人足以适应/定制/调整我的情况。

我有一张桌子,重要的字段是;

+------+------+--------+--------+
| ID   | Name | Price  |Status  |
+------+------+--------+--------+
|    1 | Fred |   4.50 |        |
|    2 | Fred |   4.50 |        |
|    3 | Fred |   5.00 |        |
|    4 | John |   7.20 |        |
|    5 | John |   7.20 |        |
|    6 | John |   7.20 |        |
|    7 | Max  |   2.38 |        |
|    8 | Max  |   2.38 |        |
|    9 | Sam  |  21.00 |        |
+------+------+--------+--------+ 

ID是一个自动递增值,因为记录会在一天内添加。 NAME是主键字段,可以在整个表中重复1到3次。 每个NAME都有一个PRICE值,每个NAME可能相同也可能不相同。

还有一个STATUS字段需要根据以下内容填充,这实际上是我坚持的部分。

Status ='Y'如果每个DISTINCT名称只附加一个价格。 如果每个DISTINCT名称附加了多个价格,则Status ='N'。

使用上表,ID的1,2和3应为'N',而4,5,6,7,8和9应为'Y'。

我认为这可能涉及JOIN,GROUP和DISTINCT的某种形式的组合,但我对如何将其放入SQL的正确顺序感到茫然。

2 个答案:

答案 0 :(得分:0)

为了获得每个名称的不同Price值的计数,我们必须在GROUP BY字段上使用Name,但是因为您还希望显示所有未分组的名称但是另外Status字段,我们必须首先在FROM子句中创建一个子选择,该子选项按名称分组,并确定名称是否具有多个价格值。

当我们在子选择中GROUP BY Name时,COUNT(DISTINCT price)将计算每个特定名称的 不同 价格值的数量。如果没有DISTINCT关键字,它只会计算价格不为空的行数。

与此相关,如果特定名称的值不止一个CASE,我们会使用N表达式将Status插入Price列,否则,它将插入Y

子选择每个Name只返回一行,所以要取消所有名称,我们将子选择加入主表,条件是子选择Name =主表的{{1} }:

Name

修改:为了便于更新,您可以使用SELECT b.ID, b.Name, b.Price, a.Status FROM ( SELECT Name, CASE WHEN COUNT(DISTINCT Price) > 1 THEN 'N' ELSE 'Y' END AS Status FROM tbl GROUP BY Name ) a INNER JOIN tbl b ON a.Name = b.Name 中的JOIN合并此查询,如下所示:

UPDATE

假设您的表格中有一个未填充的UPDATE tbl a INNER JOIN ( SELECT Name, CASE WHEN COUNT(DISTINCT Price) > 1 THEN 'N' ELSE 'Y' END AS Status FROM tbl GROUP BY Name ) b ON a.Name = b.Name SET a.Status = b.Status 列。

答案 1 :(得分:0)

如果您想更新状态列,可以执行以下操作:

UPDATE mytable s 
SET status = (
    SELECT IF(COUNT(DISTINCT price)=1, 'Y', 'N') c 
    FROM   (
            SELECT * 
            FROM mytable
           ) s1 
    WHERE  s1.name = s.name 
    GROUP BY name
    );

从技术上讲,没有必要这样做:

     FROM (
            SELECT * 
            FROM mytable
           ) s1

但是有一个mysql限制阻止您从正在更新的表中进行选择。通过将其包装在括号中,我们强制mysql创建一个临时表,然后突然就可以了。