【问题标题】:what is the query equivalence in postgresqlpostgresql中的查询等价是什么
【发布时间】:2018-07-03 15:21:10
【问题描述】:

postgresql 上的等价查询是什么?

建立数据库和表格

CREATE DATABASE IF NOT EXISTS lemonade;

use lemonade;

CREATE TABLE users (
    id int PRIMARY KEY NOT NULL auto_increment,
    name varchar(50) NOT NULL,
    email varchar(50) NOT NULL
);

CREATE TABLE memories (
    id int PRIMARY KEY NOT NULL auto_increment,
    content varchar(50) NOT NULL, 
    userID int,
    FOREIGN KEY (userID) REFERENCES users(id)
);

INSERT INTO users (name, email) VALUES ("Ruan", "ruan@gmail.com");
INSERT INTO users (name, email) VALUES ("Pereira", "pereira@gmail.com");

INSERT INTO memories (content, userID) VALUES ("memoria 1", 1);
INSERT INTO memories (content, userID) VALUES ("memoria 2", 1);
INSERT INTO memories (content, userID) VALUES ("memoria 3", 2);
INSERT INTO memories (content, userID) VALUES ("memoria 4", 2);

mysql查询:

select ANY_VALUE(m.id), ANY_VALUE(m.content), m.userID, ANY_VALUE(u.id), ANY_VALUE(u.name), ANY_VALUE(u.email) from memories m inner join users u on m.userID = u.id group by userID;

结果: image with result of my query

对 postgresql 的查询:

?

结果:期望结果等于上图

【问题讨论】:

  • 您标记了 MySQL 和 Postgresql - 为什么标记 MySQL?到目前为止,您尝试了什么?
  • 我认为我不应该标记 mysql 标签。我尝试了很多我什至不记得的东西。

标签: mysql postgresql


【解决方案1】:

当查询正在执行GROUP BY 聚合时,使用 MySQL 中的 ANY_VALUE 函数,但选择了 GROUP BY 子句中未提及且未出现在聚合函数中的列。在查询的上下文中,这意味着可以选择的唯一列是 userID 或聚合函数内的另一列,如 MAXSUM。从技术上讲,您也可以从users 表中选择其他列,假设它们在功能上依赖于userId。顾名思义,ANY_VALUE 告诉 MySQL 从每组记录中返回该列的任何值。

据我所知/预期,您从 ANY_VALUE 获得的值不能保证是确定性的,因此在逻辑上等同于从每组记录中为该列选择一个随机值。假设您不关心返回的值,在 Postgres 中您可以任意选择每个用户最早的内存:

SELECT
    memory_id, content, id, name, email
FROM
(
    SELECT m.id AS memory_id, m.content, u.id, u.name, u.email,
        ROW_NUMBER() OVER (PARTITION BY u.id ORDER BY m.id) rn
    FROM memories m
    INNER JOIN users u
        ON m.userID = u.id
) t
WHERE rn = 1;

我认为一般来说你应该避免在 MySQL 中使用ANY_VALUE,除非你绝对别无选择。一个更好的长期解决方案是清理 MySQL 查询并使其符合 ANSI。那么如何将它移植到另一个数据库就很简单了。

【讨论】:

【解决方案2】:

我认为您需要DISTINCT ON ( expression ...) 子句。 新代码是

select distinct on(u.id)
m.id, m.content, m.userID, u.id, u.name, u.email 
from memories m 
inner join users u on m.userID = u.id;

注意:DISTINCT ON 是非标准 SQL 子句。

表格更多信息see

【讨论】:

  • 请同时引用链接页面中最相关的部分,因为链接可能会过期:)
【解决方案3】:

我刚刚遇到了这个问题,并通过使用min 函数简单地解决了它。它也适用于字符串列。在你的情况下,它会给:

SELECT
  m.userID, 
  min(m.id) as id, 
  min(m.content) as content, 
  min(u.id) as uid, 
  min(u.name) as name, 
  min(u.email) as email 
FROM memories m 
INNER JOIN users u on m.userID = u.id 
GROUP BY userID;

如果您准备好使用any_value,那么这意味着您不在乎返回哪个值。取最小值是那些随机值之一。

【讨论】:

    猜你喜欢
    • 2021-08-04
    • 2011-01-13
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 2012-10-29
    • 2013-11-02
    相关资源
    最近更新 更多