gpt4 book ai didi

python - SQLAlchemy - 如何计算多列的不同

转载 作者:行者123 更新时间:2023-12-04 15:29:46 27 4
gpt4 key购买 nike

我有这个查询:

SELECT COUNT(DISTINCT Serial, DatumOrig, Glucose) FROM values;

我试图用 SQLAlchemy 重新创建它这边走:
session.query(Value.Serial, Value.DatumOrig, Value.Glucose).distinct().count()

但这转化为:
SELECT count(*) AS count_1
FROM (SELECT DISTINCT
values.`Serial` AS `values_Serial`,
values.`DatumOrig` AS `values_DatumOrig`,
values.`Glucose` AS `values_Glucose`
FROM values)
AS anon_1

它不会内联调用 count 函数,而是将 select distinct 包装到子查询中。

我的问题是:SQLAlchemy 有哪些不同的方式来计算多列上的不同选择,它们会转换成什么?

有什么解决方案可以转化为我的原始查询吗?性能或内存使用量是否有严重差异?

最佳答案

首先,我认为 COUNT(DISTINCT)支持多于 1 个表达式是 MySQL 扩展。您可以使用 ROW 在例如 PostgreSQL 中实现相同的目标。值,但行为与 NULL 不同。在 MySQL 中,如果任何值表达式的计算结果为 NULL,则该行不合格。这也导致了问题中两个查询之间的不同:

  • 如果任何 Serial , DatumOrig , 或 GlucoseCOUNT(DISTINCT) 中为 NULL查询,该行不符合条件或换句话说不计数。
  • COUNT(*)是子查询的基数anon_1 ,或者换句话说,行数。 SELECT DISTINCT Serial, DatumOrig, Glucose将包括(不同的)带有 NULL 的行。

  • 看着 EXPLAIN 2 个查询的输出看起来子查询导致 MySQL 使用临时表。这可能会导致性能差异,尤其是在磁盘上实现时。

    生产多值 COUNT(DISTINCT) SQLAlchemy 中的查询有点棘手,因为 count() 是一个通用函数,并且更接近于 SQL 标准实现。它只接受一个表达式作为它的(可选)位置参数, distinct() 也是如此。 .如果所有其他方法都失败了,您可以随时恢复到 text() 片段,例如在这种情况下:
    # NOTE: text() fragments are included in the query as is, so if the text originates
    # from an untrusted source, the query cannot be trusted.
    session.query(func.count(distinct(text("`Serial`, `DatumOrig`, `Glucose`")))).\
    select_from(Value).\
    scalar()

    这远非可读和可维护的代码,但现在可以完成工作。另一种选择是编写一个实现 MySQL 扩展的自定义构造,或者按照您的尝试重写查询。形成生成所需 SQL 的自定义构造的一种方法是:
    from itertools import count
    from sqlalchemy import func, distinct as _distinct

    def _comma_list(exprs):
    # NOTE: Magic number alert, the precedence value must be large enough to avoid
    # producing parentheses around the "comma list" when passed to distinct()
    ps = count(10 + len(exprs), -1)
    exprs = iter(exprs)
    cl = next(exprs)
    for p, e in zip(ps, exprs):
    cl = cl.op(',', precedence=p)(e)

    return cl

    def distinct(*exprs):
    return _distinct(_comma_list(exprs))

    session.query(func.count(distinct(
    Value.Serial, Value.DatumOrig, Value.Glucose))).scalar()

    关于python - SQLAlchemy - 如何计算多列的不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61460090/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com