如何将任何给定的 SQL/HQL 选择查询动态转换为等效计数查询?

Posted

技术标签:

【中文标题】如何将任何给定的 SQL/HQL 选择查询动态转换为等效计数查询?【英文标题】:How to dynamically convert any given SQL/HQL select query to equivalent count query? 【发布时间】:2018-11-28 08:47:11 【问题描述】:

我想将任何给定的选择查询转换为等效的计数查询。选择查询可以是有效的 SQL 或 HQL 查询。以下是我的尝试。

    /// <summary>
    /// Converts select query into equivalent count query
    /// </summary>
    protected string ConvertToCountQuery(string selectQuery)
    
        if (string.IsNullOrWhiteSpace(selectQuery))
        
            return string.Empty;
        

        string[] selectParts = selectQuery.ToLower().Split(new string[]  "select" , StringSplitOptions.RemoveEmptyEntries);
        string[] fromParts = selectParts[0].Split(new string[]  "from" , StringSplitOptions.RemoveEmptyEntries);
        selectParts[0] = string.Format("select count(*) from0", fromParts[1]);
        return string.Concat(selectParts);
    

它适用于 SQL 查询,因为它们不区分大小写,但是对于 HQL 查询,它会丢失大小写。如何在获得等效计数查询的同时保留案例。

SQL 的示例测试数据:

select u.username, u.email, u.first_name, u.last_name from users u where u.username like '% %';

SQL 的预期输出:

select count(*) from users u where u.username like '% %';

HQL 的示例测试数据:

select u.Username, u.Email, u.FirstName, u.LastName from User u where u.Username like '% %';

HQL 的预期输出:

select count(*) from Users u where u.Username like '% %';

注意 HQL 查询中区分大小写。

【问题讨论】:

【参考方案1】:

好的,我自己找到了解决方案。

    /// <summary>
    /// Converts select query into equivalent count query
    /// </summary>
    public static string ConvertToCountQuery(string selectQuery)

    if (string.IsNullOrWhiteSpace(selectQuery) || !selectQuery.ToLower().Contains("select"))
    
        return string.Empty;
    

    return string.Concat(
            "select count(*)",
            selectQuery.Substring(selectQuery.ToLower().IndexOf(" from")));

【讨论】:

查询有group by子句时不起作用。当它在 select 子句中包含子查询时(使用另一个 from 子句,但不是您要查找的 from 子句),它也不起作用。 @StefanSteinegger 我明白你所说的分组是什么意思,你能解释一下'select 子句(带有另一个 from 子句..')是什么意思吗?你能给出一个测试查询吗?跨度> 在参考文档中(搜索子查询):select cat.id, (select max(kit.weight) from cat.kitten kit) from Cat as cat【参考方案2】:

我会尝试将给定的查询放入子查询中:

var countQuery = string.Format("select count(*) from (0)", selectQuery);

它会变成这样的查询:

select count(*) from (select ... from User u where u.Username like '% %');

我不知道它是否有效。 Oracle 需要支持这一点(FROM 子句中的子查询)。 HQL 也需要支持它(它通常在很多事情上都非常透明,所以有希望)。如果不是,我会认为通过合理的努力和可接受的可靠性是不可能的。

考虑对这类任务使用 linq 或 query over,因为这些 API 在运行时可靠地构建查询方面更加灵活。 AFAIK,两者都内置了计数支持。

【讨论】:

以上是关于如何将任何给定的 SQL/HQL 选择查询动态转换为等效计数查询?的主要内容,如果未能解决你的问题,请参考以下文章

Powershell根据给定的计数选择一个随机字母,并动态地将每个字母分配给一个唯一的变量?

Mysql查询根据两列动态将行转换为列

Hibernate HQL,Criteria和SQL

如何仅使用 CSS 过滤器将黑色转换为任何给定的颜色

将表单提交中指定的任何日期转换为给定格式

SQLAlchemy 查询 - 动态类选择