SQL / ActiveRecord查询多列上的多行

时间:2015-09-22 22:18:35

标签: sql ruby-on-rails activerecord

假设我有两个ActiveRecord模型(或SQL数据库中的两个表,如果你愿意的话)。我有一个User班和一个Poll班。 User has_many PollsPoll当用户选择apples时,会询问他们是否喜欢bananascherriesUserPolls对每个事物的响应都记录在一个布尔列中。

我有兴趣了解哪些用户已经apples并且已经回复了他们在任何时候都喜欢bananascherriesPoll的所有内容(不是必须在同一时间)。换句话说,他们不需要说他们喜欢一个apples期间的所有三个水果,他们只需要说他们喜欢这些东西在某个时刻,即他们需要说他们喜欢Poll中至少有bananasPoll至少有一个cherriesPoll至少有一个Motor MotorType CalibrationValueX CalibrationValueY A Car 1.2343 2.33343 B Boat 1.2455 2.55434 B1 Boat 1.4554 2.11211 C Car 1.4323 4.56555 D Car 1.533 4.6666 ..... 500 entries

以一般方式做这件事的正确方法是什么? ActiveRecord或SQL查询都会有所帮助。

2 个答案:

答案 0 :(得分:2)

假设您的polls表格包含布尔列applesbananascherries。然后,对于每个用户,您希望查看相应的轮询并计算每个水果列上的聚合OR函数,仅保留每个水果返回true的行。

User.joins(:polls)
    .group('users.id')
    .having('BOOL_OR(polls.apples) = ? AND BOOL_OR(polls.bananas) = ? AND BOOL_OR(polls.cherries) = ?', true, true, true)

答案 1 :(得分:1)

或许您的表格如下http://sqlfiddle.com/#!15/c0967/10

create table polls (userid char(10), pollid char(10), questionid char(10), response boolean);

insert into polls (userid, pollid, questionid, response)
values ('1','1','APPLES',true),
       ('1','1','BANANAS',false),
       ('1','1','CHERRIES',true),
       ('1','2','APPLES',false),
       ('1','2','BANANAS',false),
       ('1','2','CHERRIES',true),
       ('1','3','APPLES',false),
       ('1','3','BANANAS',true),
       ('1','3','CHERRIES',true),
       ('2','1','APPLES',false),
       ('2','1','BANANAS',false),
       ('2','1','CHERRIES',true),
       ('2','2','APPLES',false),
       ('2','2','BANANAS',true),
       ('2','2','CHERRIES',true),
       ('2','3','APPLES',false),
       ('2','3','BANANAS',false),
       ('2','3','CHERRIES',true),
       ('3','1','APPLES',true),
       ('3','1','BANANAS',false),
       ('3','1','CHERRIES',false),
       ('3','2','APPLES',false),
       ('3','2','BANANAS',true),
       ('3','2','CHERRIES',false),
       ('3','3','APPLES',false),
       ('3','3','BANANAS',false),
       ('3','3','CHERRIES',true),
       ('4','1','APPLES',false),
       ('4','1','BANANAS',false),
       ('4','1','CHERRIES',false),
       ('4','2','APPLES',true),
       ('4','2','BANANAS',true),
       ('4','2','CHERRIES',true),
       ('4','3','APPLES',false),
       ('4','3','BANANAS',false),
       ('4','3','CHERRIES',false)
;

在这种情况下,您可以创建一个临时视图,将用户问题与真实响应分组,然后计算该视图中的记录,如下所示:

with counts as (
  select userid, questionid
  from polls
  where response = true
  and questionid in ('APPLES','BANANAS','CHERRIES')
  group by userid, questionid
  )
select userid
from counts
group by userid
having count(*) = 3