【问题标题】:Multiple aggregate queries using the sequel gem使用 sequel gem 的多个聚合查询
【发布时间】:2014-05-16 05:05:03
【问题描述】:

是否可以使用 sequel 来执行这样的查询:

select (select count(*) from users where blah = 'blah') as "users",
       (select count(*) from contacts where blah = 'blah') as "contacts"

我知道我可以使用 sequel 一次执行这些查询,但我想同时执行它们。

【问题讨论】:

    标签: ruby sequel sequel-gem


    【解决方案1】:

    您可以在不编写原始 SQL 的情况下执行该查询:

    dataset = DB.select {[ 
      DB[:users].where(blah: 'blah').select { count('*') }.as(:users),
      DB[:contacts].where(blah: 'blah').select { count('*') }.as(:contacts) 
    ]}
    
    dataset.first
    # => { users: X, contacts: Y }
    
    dataset.sql
    # => "SELECT (SELECT count('*') FROM \"users\" WHERE (\"blah\" = 'blah')) AS \"users\", 
    #            (SELECT count('*') FROM \"contacts\" WHERE (\"blah\" = 'blah')) AS \"contacts\""
    

    【讨论】:

      【解决方案2】:

      是的,你可以使用 sequel gem 做到这一点。

      require 'sequel'
      
      DB = Sequel.sqlite # memory database
      
      DB.create_table :users do
        primary_key :id
        String :name
      end
      
      users = DB[:users] # Create a dataset
      users.insert(:name => 'jim')
      
      DB.create_table :contacts do
        primary_key :id
        String :name
      end
      contacts = DB[:contacts] # Create a dataset
      contacts.insert(:name => 'first')
      
      
      DB['select (select count(*) from users where name = "jim") as users, 
                 (select count(*) from contacts where name = "first") as contacts'].each do |row|
        puts row
      end
      
      
      #{:users=>1, :contacts=>1}
      

      但是应该注意的是,在 sequel 方法中包含原始字符串并不是一个好主意。 它们可以按如下方式提取:

      DB['select (select count(*) from users where name = ?) as users, 
                 (select count(*) from contacts where name = ?) as contacts, 'jim', 'first'].each do |row|
        puts row
      end
      

      还如另一个答案中所述,您可以完全表达此查询,而无需求助于更符合模块精神的 SQL。 :

      dataset = DB.select {[
        DB[:users].where(name: 'jim').select { count('*') }.as(:users),
        DB[:contacts].where(name: 'first').select { count('*') }.as(:contacts)
      ]}
      
      dataset.sql
      
      # SELECT (SELECT count('*') FROM `users` WHERE (`name` = 'jim')) AS 'users', (SELECT count('*') FROM `contacts` WHERE (`name` = 'first')) AS 'contacts'
      
      dataset.first
      
      # {:users=>1, :contacts=>1}
      

      【讨论】:

      • 虽然您的示例有效,但它不是一个很好的 sequel 示例,也不是使用原始字符串的 gem 精神,因为可以并且应该使用 sequel 方法来组合查询。
      • @AndrewHacking 是的,但该问题专门询问该查询是否可行。
      • 有一个连续的好到坏的答案,我认为@hjing 的另一个答案是你如何在续集中编写查询的典型,而你的不代表正常方法。由于 SO 被许多人阅读,因此最好的答案上升到顶部并且不太好的下降到底部是很重要的,因此我的反对意见和解释。
      • 好点。我再次尝试改进我的答案。我从这个问题中学到了很多东西。
      • 我现在赞成你的回答说明了“肮脏”和干净的方法,但如果可能的话,你应该和@hjing 分享这些观点。
      【解决方案3】:

      您可以按照上面提到的执行,您的查询没有问题。 我已经执行了相同的操作,并且执行时没有任何问题..

      下面是我执行的操作

           select( SELECT count(*) FROM `abcde` where `User_ID`=4001) as "aa",
           (SELECT count(*) FROM `abcdef` where `User_ID`=4018) as "bbb"
      

      结果:

         aa   bbb
         181  364
      

      【讨论】:

        【解决方案4】:

        你需要在 select 之后添加 * from 并且可能是一些括号:

        select * from ((select count(*) from users where blah = 'blah') as "users",
           (select count(*) from contacts where blah = 'blah') as "contacts")
        

        【讨论】:

        • 对不起,我的意思是使用 sequel ruby​​ gem
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-16
        • 2017-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-14
        • 1970-01-01
        相关资源
        最近更新 更多