1

很好地阅读了类似的主题,但我不能完全 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 字段需要根据以下内容进行填充,这实际上是我卡住的部分。

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

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

我认为这很可能涉及某种形式的 JOIN、GROUP 和 DISTINCT 组合,但我不知道如何将其放入 SQL 的正确顺序中。

4

2 回答 2

0

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

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

与此相结合,如果特定名称有多个不同的值,我们使用CASE表达式插入N列,否则,它将插入。StatusPriceY

子选择每只返回一行Name,因此为了使所有名称未分组,我们将该子选择连接到主表,条件是子选择Name= 主表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

编辑:为了方便更新,您可以使用JOINs合并此查询,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

假设您的表格中有一个未填充的Status列。

于 2012-06-25T17:16:14.990 回答
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创建一个临时表,然后它突然成为可能。

于 2012-06-25T17:44:18.950 回答