2010-03-12 141 views
1

SELECT * FROM jobs WHERE(SELECT DISTINCT作业* FROM作业,job_requests WHERE(jobs.user_id = 1)OR (job_requests.user_id。 = 1 AND job_requests.job_id = jobs.id) )SQL查询错误:操作数应包含在轨道1列(多个)

这个SQL给我:

Mysql::Error: Operand should contain 1 column(s). 

如果我执行选择从where子句它的工作原理

SELECT DISTINCT jobs.* FROM jobs, job_requests 
WHERE (jobs.user_id = 1) OR 
     (job_requests.user_id = 1 AND job_requests.job_id = jobs.id) 

有人可以解释我为什么吗?该查询由rails activerecord生成,因此需要进行主选择。

RoR的代码:

has_many :my_jobs, :class_name=>"Job", :finder_sql => 
    'SELECT DISTINCT jobs.* ' + 
    'FROM jobs, job_requests ' + 
    'WHERE (jobs.user_id = #{id}) OR ' + 
    '(job_requests.user_id = #{id} AND job_requests.job_id = jobs.id AND job_requests.request_status IN ("requested", "confirmed"))' 
+0

你能告诉RoR的代码生成这样的查询? – klew 2010-03-12 19:40:05

+0

是的,我也添加了ror代码。基本上我想检索用户是所有者和他应用的工作(通过job_requests有工作)的工作,但我希望他们一起进一步筛选。 – dombesz 2010-03-13 00:57:52

回答

1

我根据所提供的附加信息提交我的回答。以下查询应符合您的要求。

Job.all(:conditions=> [ " 
jobs.user_id = ? OR 
EXISTS (
    SELECT * 
    FROM job_requests AS B 
    WHERE B.job_id = jobs.id AND B.user_id = ? 
)", user_id, user_id ] 
) 

如果你想要一个同样的查询的高效版本,那么你应该去与UNIONs。

sql = " 
    SELECT * 
    FROM jobs A WHERE A.user_id = ? 
UNION 
    SELECT * 
    FROM jobs A, job_requests B 
    WHERE A.id = B.job_id AND B.user_id = ? 
"  
Job.find_by_sql(Job.send(:sanitize_sql_array, [sql, user_id, user_id])) 

第一个查询可以转换为named_scope

class Job < ActiveRecord::Base 

    named_scope :for_user, lambda { |user_id| { :conditions=> [ " 
    jobs.user_id = ? OR 
    EXISTS (
     SELECT * 
     FROM job_requests AS B 
     WHERE B.job_id = jobs.id AND B.user_id = ? 
    )", user_id, user_id ] } 
    } 
end 

现在你可以使用named_scope如下:

Jobs.for_user(current_user) 
+0

看起来很有趣,但我唯一的问题是,我想进一步过滤名称范围的结果集。可以在这里应用命名范围吗? – dombesz 2010-03-14 12:00:13

+0

我已将named_scope代码添加到我的答案中。看看 – 2010-03-14 16:07:42

+0

真棒,非常感谢。 – dombesz 2010-03-15 11:27:29

0

如果我理解正确的,你就需要重新调整为

SELECT * FROM jobs 
WHERE EXISTS 
     (SELECT DISTINCT jobs.* 
      FROM jobs, job_requests 
     WHERE (jobs.user_id = 1) 
      OR (job_requests.user_id = 1 AND job_requests.job_id = jobs.id)) 

我猜你只是想从工作选择其中内部查询是真,上面会为你做这个。

+0

我正在寻找一种解决方案,可以集成在ror中。 – dombesz 2010-03-14 12:15:46

0

下面的代码将工作,如果你想获得jobsjob requests对于给定user

Job.all(:joins  => :jobs_requests, 
     :conditions => ["job_requests.user_id = ?", user_id]) 
+0

这样的事情,但问题是,在这种情况下,我不会给回用户身份不匹配的工作。条件是:或者用户是作业的所有者(jobs.user_id = user_id),或者通过作业请求(job_request.user_id = user_id和job_request.job_id = jobs.id)申请作业。希望这是有道理的。 – dombesz 2010-03-13 01:02:29

+0

我为您的问题添加了另一个答案。它应该涵盖你的场景 – 2010-03-13 01:35:25

1

SQL查询:文档

SELECT (
'95.86.122.224', NOW() , '95.86.122.224', '95.86.122.224' 
) 
FROM orders 
LEFT JOIN visitors ON visitors.ip = '95.86.122.224' 
WHERE visitors.ip IS NULL 
LIMIT 0 , 30 

MySQL表示:文件

#1241 - Operand should contain 1 column(s) 
相关问题