我一直在使用 PostgreSQL ,现在正在迁移到 MySQL 。
在我的查询中,我正在使用 PostgreSQL 的SELECT DISTINCT ON (col1, col2, col3)
,我想知道 MySQL 中是否存在此声明的任何对应部分。
答案 0 :(得分:36)
对于将使用SELECT DISTINCT ON的Postgresql查询转换为MySQL,并不完全等效。
Postgresql SELECT DISTINCT ON
在Postgresql中,以下查询将消除表达式(col1, col2, col3)
匹配的所有行,并且它将仅保留"第一个col4,col5行"对于每组匹配的行:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
所以如果你的表是这样的:
col1 | col2 | col3 | col4 | col5
--------------------------------
1 | 2 | 3 | 777 | 888
1 | 2 | 3 | 888 | 999
3 | 3 | 3 | 555 | 555
我们的查询只为(1,2,3)保留一行,为(3,3,3)保留一行。结果行将是:
col4 | col5
-----------
777 | 888
555 | 555
请注意"第一行"每一组都是不可预测的,我们的第一行也可能是(888,999),除非我们指定一个ORDER BY:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
(表达式上的DISTINCT必须与最左边的ORDER BY表达式匹配,但ORDER BY可以包含其他表达式。)
对GROUP BY的MySQL扩展
MySQL扩展了GROUP BY的使用,以便我们可以选择GROUP BY子句中未命名的非聚合列。每当我们选择非聚合列时,服务器可以自由选择该列中每个组的任何值,因此结果值将不确定。
所以这个Postgresql查询:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
可以被认为等同于这个MySQL查询:
SELECT col4, col5
FROM tablename
GROUP BY col1, col2, col3
Postgresql和MySQL都将返回"第一行"对于每个(col1,col2,col3),并且在两种情况下返回的行都是不可预测的,因为我们没有指定和order by子句。
很多人都很想用ORDER BY转换这个Postgresql查询:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
这一个:
SELECT col4, col5
FROM (
SELECT col1, col2, col3, col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
) s
GROUP BY col1, col2, col3
这里的想法是将ORDER BY应用于子查询,以便当MySQL按col1,col2,col3分组时,它将保留col4和col5的第一个遇到的值。 这个想法很好,但是错了! MySQL可以自由选择col4和col5的任何值,而且我们不知道哪些是遇到的第一个值,它取决于优化器。所以我会纠正它:
SELECT t1.col4, t1.col5
FROM tablename t1 INNER JOIN (SELECT col1, col2, col3, MIN(col4) as m_col4
FROM tablename
GROUP BY col1, col2, col3) s
ON t1.col1=s.col1
AND t1.col2=s.col2
AND t1.col3=s.col3
AND t1.col4=s.m_col4
GROUP BY
t1.col1, t1.col2, t1.col3, t1.col4
但这开始变得更加复杂。
<强>结论强>
作为一般规则,没有将Postgresql查询转换为MySQL查询的确切方法,但是有很多变通方法,结果查询可能与原始查询一样简单,也可能变为非常复杂,但这取决于查询本身。
答案 1 :(得分:0)
使用子查询来确定顺序,使用外部查询对它们进行分组。
就像@a_horse_with_no_name指出的那样,这是有效的,因为MySQL允许部分group by
,与其他DBMS不同。
例如:
CREATE TABLE customer_order
(`customer` varchar(5), `item` varchar(6), `date` datetime)
;
INSERT INTO customer_order
(`customer`, `item`, `date`)
VALUES
('alice', 'widget', '2000-01-05 00:00:00'),
('bob', 'widget', '2000-01-02 00:00:00'),
('alice', 'widget', '2000-01-01 00:00:00'),
('alice', 'wodget', '2000-01-06 00:00:00')
;
查询每个客户的第一个订单:
select *
from
(select customer, item, date
from customer_order
order by date) c
group by customer
结果:
| CUSTOMER | ITEM | DATE |
|----------|--------|--------------------------------|
| alice | widget | January, 01 2000 00:00:00+0000 |
| bob | widget | January, 02 2000 00:00:00+0000 |
答案 2 :(得分:-4)
您无法从多列中选择不同的值。同时选择使用这样的查询
select distinct col1, col2 from table
答案 3 :(得分:-6)
您应该迁移到 PDO 或 MSYQLI ,而不是 MYSQL ,因为它已被弃用。
关于你可以做的问题
SELECT DISTINCT col1, col2, col3
或
SELECT col1, col2, col3
........
GROUP BY col1 --//--- or whatever column you want to be distinct