有一个很好的阅读相似的主题,但我不能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的正确顺序感到茫然。
答案 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创建一个临时表,然后突然就可以了。