【问题标题】:Count rows with Slick 1.0.0使用 Slick 1.0.0 计算行数
【发布时间】:2013-02-12 16:01:37
【问题描述】:

我正在尝试使用Slick 1.0.0 创建一个查询,该查询返回的行数等同于以下 SQL 语句:

SELECT COUNT(*) FROM table;

到目前为止我所拥有的是:

val query = for {
  row <- Table
} yield row
println(query.length)

这打印出scala.slick.ast.FunctionSymbol$$anon$1@6860991f。此外,query.length 似乎属于scala.slick.lifted.Column 类型。我找不到执行查询的方法。我可以在文档和其他任何地方找到的所有示例都不能在 Column 上运行,或者适用于 ScalaQuery 并且不再运行。

我能做些什么来执行这个?

【问题讨论】:

    标签: scala slick


    【解决方案1】:

    这些都可以解决问题:

    Query(MyTable).list.length
    

    (for{mt <- MyTable} yield mt).list.length
    

    (for{mt <- MyTable} yield mt.count).first
    

    更新:

    打印 H2 数据库日志显示了最后一个查询,这看起来是最佳的:

     03:31:26.560 [main] DEBUG h2database - jdbc[2]
     /**/PreparedStatement prep10 = conn1.prepareStatement("select select count(1) from \"MYTABLE\" s5", 1003, 1007);
    

    【讨论】:

    • 好吧,这将在计数之前创建一个包含完整结果集的列表。当然,它确实有效,但对于非常大的表,这是不切实际的,因为长度将在时间和空间的 O(n) 复杂度中计算。
    • 我又添加了一个,但这可能会生成与 thikonom 答案中相同的选择语句。虽然略有不同
    • 对于您的第三个版本,我收到了MySQLSyntaxErrorException
    • 这真的很奇怪。我也在使用 1.0.0 并且没有问题。
    • @notan3xit 我打印了H2数据库的日志,最后查询得到了最优解。
    【解决方案2】:

    虽然我无法检查生成的 sql,但您可以通过删除 .list 获得更短的源代码:

    Query(MyTable.length).first
    

    【讨论】:

    • 这对我来说似乎是最干净的解决方案,但它似乎仍然会生成计算 MyTable 中所有字段的 SQL,并且不如 SELECT COUNT(*) FROM "MyTable"; 高效
    【解决方案3】:

    用途:

    val query = for(row <- Table) yield row 
    println(Query(query.count).first)
    

    count 相当于“SELECT COUNT(*) FROM Table”。 为了获得第一行也是唯一的行,您必须使用first 来获取计数。

    【讨论】:

    • 简短说明:count 已被 length 取代。
    • 对于scala.slick.lifted.Column 类型的值如何处理length 之类的方法返回的值有什么想法吗?您的解决方案确实有效,但会生成一个包含三个 SELECTs 的冗长语句。对于没有任何进一步要求的简单计数来说,这似乎是一个可怕的数目:select x2.x3 from (select count(1) as x3 from (select x4.'id', x4.'value' from 'table' x4) x5) x2
    猜你喜欢
    • 2016-08-19
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 2011-07-25
    相关资源
    最近更新 更多