如何解决 MySql 中的 PARTITION BY 语法错误

Posted

技术标签:

【中文标题】如何解决 MySql 中的 PARTITION BY 语法错误【英文标题】:How to get around PARTITION BY syntax error in MySql 【发布时间】:2017-01-15 16:22:24 【问题描述】:

mysql 引发ProgrammingError 运行此sql

SELECT parents.uuid AS parents_uuid, children.uuid AS children_uuid,
children.parent_uuid AS children_parent_uuid, 
count(*) OVER (PARTITION BY parents.uuid) AS children_count
FROM parents, children
WHERE children.parent_uuid = parents.uuid ORDER BY children_count DESC

错误:

sqlalchemy.exc.ProgrammingError: (_mysql_exceptions.ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(PARTITION BY parents.uuid)' at line 1") [SQL: 'SELECT parents.uuid AS parents_uuid, children.uuid AS children_uuid, children.parent_uuid AS children_parent_uuid, count(*) OVER (PARTITION BY parents.uuid)']

对于Parent 可以有多个children 的架构,而Child 有单个parent

Base = declarative_base()
class Parent(Base):
    __tablename__ = 'parents'
    uuid = Column(String(64), primary_key=True, unique=True)
    def __init__(self):  
        self.uuid = uuid.uuid4()   

class Child(Base):
    __tablename__ = 'children'
    uuid = Column(String(64), primary_key=True, unique=True)
    parent_uuid = Column(String(64), ForeignKey('parents.uuid'))
    def __init__(self, parent_uuid=None):  
        self.uuid = uuid.uuid4()   
        self.parent_uuid = parent_uuid

【问题讨论】:

MySQL 不支持窗口函数。 【参考方案1】:

MySQL 不支持窗口函数。要解决此问题,请使用相关子查询来获取计数。

SELECT 
p.uuid AS parents_uuid, 
c.uuid AS children_uuid,
c.parent_uuid AS children_parent_uuid, 
(SELECT COUNT(*) FROM children WHERE parent_uuid = p.uuid) AS children_count
FROM parents p
JOIN children c ON c.parent_uuid = p.uuid 
ORDER BY children_count DESC

或者使用派生表来获取计数并将join它提供给现有查询。

SELECT 
p.uuid AS parents_uuid, 
c.uuid AS children_uuid,
c.parent_uuid AS children_parent_uuid, 
counts.children_count
FROM parents p
JOIN (SELECT parent_uuid,COUNT(*) as children_count
      FROM children 
      GROUP BY parent_uuid) counts ON counts.parent_uuid = p.uuid 
JOIN children c ON c.parent_uuid = p.uuid 
ORDER BY counts.children_count DESC

【讨论】:

【参考方案2】:

从 MySQL 8.0 开始支持窗口函数 https://dev.mysql.com/doc/refman/8.0/en/window-functions-usage.html

【讨论】:

以上是关于如何解决 MySql 中的 PARTITION BY 语法错误的主要内容,如果未能解决你的问题,请参考以下文章

rank() over(partition by A order by B) MySQL里可以partition多个字段嘛

Spark如何写入HBase/Redis/MySQL/Kafka

mysql分区交换exchange partition

docker容器中修改kafka中的partition配置

如何在 MYSQL 中选择具有 MAX(列值)和 PARTITION 的行?

如何在 Mysql 中使用 rank() 而不是 PARTITION BY