MySQL 并非所有列都是 DISTINCT
MySQL DISTINCT for not all columns
CREATE TABLE IF NOT EXISTS FRUITS (
ID INT(11) NOT NULL AUTO_INCREMENT,
owner VARCHAR(45) DEFAULT NULL,
fruit VARCHAR(45) DEFAULT NULL,
colour VARCHAR(45) DEFAULT NULL,
comments VARCHAR(45) DEFAULT NULL,
incident_date DATE DEFAULT NULL,
PRIMARY KEY (ID)
) ENGINE=MyISAM;
INSERT INTO `your_db`.`FRUITS` (ID, owner, fruit, colour, comments, incident_date) VALUES
(NULL, 'Sam', 'apple', 'green', 'bought', '2016-11-01'),
(NULL, 'John', 'lemon', 'yellow', 'borrowed', '2016-11-02'),
(NULL, 'Oscar', 'lemon', 'yellow', 'found', '2016-11-03'),
(NULL, 'Oscar', 'apple', 'green', 'stolen', '2016-11-04'),
(NULL, 'Sam', 'kiwi', 'green', 'inherited', '2016-11-05'),
(NULL, 'Oscar', 'apple', 'green', 'eaten', '2016-11-06'),
(NULL, 'Oscar', 'apple', 'yellow', 'grown', '2016-11-09');
我有一个包含人员及其财产的数据表,该数据表从 MySQL 查询中获取数据,我需要过滤掉 Oscar 处理过的苹果。我不在乎它们是否被发现、被盗或被吃掉,但我需要得到最后一个事件(它是在 11 月 6 日被吃掉的)。基本上只有2行:
Oscar | apple | green | eaten | 2016-11-06
Oscar | apple | yellow | grown | 2016-11-09
这个:
SELECT DISTINCT * FROM FRUITS
WHERE owner LIKE 'Osc%' AND fruit LIKE 'apple' AND colour LIKE '%%'
ORDER BY owner ASC
returns3排(绿色的被盗吃过),我只需要后者
如果能像这样分隔不同的列就好了:
SELECT comments, incident_date, DISTINCT owner, fruit, colour
FROM FRUITS WHERE owner LIKE 'Osc%' AND fruit LIKE 'apple' AND colour LIKE '%%'
ORDER BY owner ASC
不存在这种可能性。还有其他的吗?
(真实案例场景是杂志上的广告提案是给客户的,有些提案是在不同时间对同一区域(例如1/2页)在不同时间进行的。我只需要过滤掉那些向该客户提出的针对此广告尺寸的提议在该日期被拒绝。两次不同的拒绝令人困惑。)
这是非常常见的 greatest-n-per-group 问题的变体。
如何获取给定 owner/fruit/colour 组合的最新行?
换句话说,尝试将这样的一行(称为 F1)连接到具有相同 owner/fruit/colour 和更新的 ID 的另一行(称为 F2)。如果未找到匹配项,则外部联接将为 F2.*
.
return 所有 NULL
SELECT F1.* FROM FRUITS AS F1
LEFT OUTER JOIN FRUITS AS F2
ON F1.owner = F2.owner
AND F1.fruit = F2.fruit
AND F1.colour = F2.colour
AND F1.ID < F2.ID
WHERE F2.ID IS NULL AND F1.owner = 'Oscar' AND F1.fruit = 'apple';
一种方法是为每个独特的所有者、水果颜色和最大事件日期生成一组数据 w/o 评论,然后加入回基础集以包含评论。
SELECT *
FROM fruits F
INNER JOIN (SELECT max(Incident_date) mID, Owner, Fruit, Color
FROM Fruits
GROUP BY Owner, Fruit, Color) FM
on FM.Owner = F.Owner
and Fm.Fruit = F.Fruit
and FM.Color = F.Color
and FM.Mid = F.Incident_Date
WHERE F.Owner = 'Oscar' and F.Fruit = 'apple'
如果您不关心引擎选择的评论,mySQL 中的简单分组就可以了...
mySQL 扩展分组依据,因此引擎选择的评论将不确定,因为它不在分组依据中。
SELECT Owner, Fruit, Color, comment, max(Incident_date)
FROM Fruit
GROUP BY Owner, Fruit, Color
CREATE TABLE IF NOT EXISTS FRUITS (
ID INT(11) NOT NULL AUTO_INCREMENT,
owner VARCHAR(45) DEFAULT NULL,
fruit VARCHAR(45) DEFAULT NULL,
colour VARCHAR(45) DEFAULT NULL,
comments VARCHAR(45) DEFAULT NULL,
incident_date DATE DEFAULT NULL,
PRIMARY KEY (ID)
) ENGINE=MyISAM;
INSERT INTO `your_db`.`FRUITS` (ID, owner, fruit, colour, comments, incident_date) VALUES
(NULL, 'Sam', 'apple', 'green', 'bought', '2016-11-01'),
(NULL, 'John', 'lemon', 'yellow', 'borrowed', '2016-11-02'),
(NULL, 'Oscar', 'lemon', 'yellow', 'found', '2016-11-03'),
(NULL, 'Oscar', 'apple', 'green', 'stolen', '2016-11-04'),
(NULL, 'Sam', 'kiwi', 'green', 'inherited', '2016-11-05'),
(NULL, 'Oscar', 'apple', 'green', 'eaten', '2016-11-06'),
(NULL, 'Oscar', 'apple', 'yellow', 'grown', '2016-11-09');
我有一个包含人员及其财产的数据表,该数据表从 MySQL 查询中获取数据,我需要过滤掉 Oscar 处理过的苹果。我不在乎它们是否被发现、被盗或被吃掉,但我需要得到最后一个事件(它是在 11 月 6 日被吃掉的)。基本上只有2行:
Oscar | apple | green | eaten | 2016-11-06
Oscar | apple | yellow | grown | 2016-11-09
这个:
SELECT DISTINCT * FROM FRUITS
WHERE owner LIKE 'Osc%' AND fruit LIKE 'apple' AND colour LIKE '%%'
ORDER BY owner ASC
returns3排(绿色的被盗吃过),我只需要后者
如果能像这样分隔不同的列就好了:
SELECT comments, incident_date, DISTINCT owner, fruit, colour
FROM FRUITS WHERE owner LIKE 'Osc%' AND fruit LIKE 'apple' AND colour LIKE '%%'
ORDER BY owner ASC
不存在这种可能性。还有其他的吗?
(真实案例场景是杂志上的广告提案是给客户的,有些提案是在不同时间对同一区域(例如1/2页)在不同时间进行的。我只需要过滤掉那些向该客户提出的针对此广告尺寸的提议在该日期被拒绝。两次不同的拒绝令人困惑。)
这是非常常见的 greatest-n-per-group 问题的变体。
如何获取给定 owner/fruit/colour 组合的最新行?
换句话说,尝试将这样的一行(称为 F1)连接到具有相同 owner/fruit/colour 和更新的 ID 的另一行(称为 F2)。如果未找到匹配项,则外部联接将为 F2.*
.
SELECT F1.* FROM FRUITS AS F1
LEFT OUTER JOIN FRUITS AS F2
ON F1.owner = F2.owner
AND F1.fruit = F2.fruit
AND F1.colour = F2.colour
AND F1.ID < F2.ID
WHERE F2.ID IS NULL AND F1.owner = 'Oscar' AND F1.fruit = 'apple';
一种方法是为每个独特的所有者、水果颜色和最大事件日期生成一组数据 w/o 评论,然后加入回基础集以包含评论。
SELECT *
FROM fruits F
INNER JOIN (SELECT max(Incident_date) mID, Owner, Fruit, Color
FROM Fruits
GROUP BY Owner, Fruit, Color) FM
on FM.Owner = F.Owner
and Fm.Fruit = F.Fruit
and FM.Color = F.Color
and FM.Mid = F.Incident_Date
WHERE F.Owner = 'Oscar' and F.Fruit = 'apple'
如果您不关心引擎选择的评论,mySQL 中的简单分组就可以了... mySQL 扩展分组依据,因此引擎选择的评论将不确定,因为它不在分组依据中。
SELECT Owner, Fruit, Color, comment, max(Incident_date)
FROM Fruit
GROUP BY Owner, Fruit, Color