如果一个或另一个或两个字段匹配,如何返回SQL查询

时间:2012-09-12 12:43:50

标签: mysql sql ruby-on-rails

我正在使用Rails 3应用程序中的遗留代码。

# Contacts
contact_searchable_columns = [
  'contacts.first_name',
  'contacts.last_name',
  'contacts.title',
  'contacts.address',
  'contacts.city',
  'contacts.state',
  'contacts.zip_code',
  'contacts.note',
  'contacts.phone1',
  'contacts.phone2',
  'contacts.phone3',
  'contacts.email1',
  'contacts.email2',
  'contacts.email3'
]
contact_conditions = [ contact_searchable_columns.map{ |c| "#{c} LIKE :q" }.join(' OR '), { :q => "%#{@query}%" } ]
@contacts = current_account.contacts.paginate(:all, :include => :customer, :order => 'customers.name', :page => params[:page], :conditions => contact_conditions)

如果我的姓氏正确或名字,这将成功返回一个匹配。但是如果我在查询中有名字和姓氏,那么它就不会返回。

我如何编写它,以便如果在一组单词的查询中至少“一个单词匹配”也可以返回匹配?

使用MurifoX的答案,产生了这个SQL:

 Contact Load (1.8ms)  SELECT `contacts`.`id` AS t0_r0, `contacts`.`customer_id` AS t0_r1, `contacts`.`account_id` AS t0_r2, `contacts`.`first_name` AS t0_r3, `contacts`.`last_name` AS t0_r4, `contacts`.`title` AS t0_r5, `contacts`.`phone1` AS t0_r6, `contacts`.`phone1_type` AS t0_r7, `contacts`.`phone2` AS t0_r8, `contacts`.`phone2_type` AS t0_r9, `contacts`.`phone3` AS t0_r10, `contacts`.`phone3_type` AS t0_r11, `contacts`.`email1` AS t0_r12, `contacts`.`email1_type` AS t0_r13, `contacts`.`email2` AS t0_r14, `contacts`.`email2_type` AS t0_r15, `contacts`.`email3` AS t0_r16, `contacts`.`email3_type` AS t0_r17, `contacts`.`address` AS t0_r18, `contacts`.`city` AS t0_r19, `contacts`.`state` AS t0_r20, `contacts`.`zip_code` AS t0_r21, `contacts`.`country` AS t0_r22, `contacts`.`note` AS t0_r23, `contacts`.`primary` AS t0_r24, `contacts`.`created_at` AS t0_r25, `contacts`.`updated_at` AS t0_r26, `customers`.`id` AS t1_r0, `customers`.`account_id` AS t1_r1, `customers`.`customer_number` AS t1_r2, `customers`.`created_at` AS t1_r3, `customers`.`name` AS t1_r4, `customers`.`phone_number` AS t1_r5, `customers`.`fax` AS t1_r6, `customers`.`service_address` AS t1_r7, `customers`.`service_city` AS t1_r8, `customers`.`service_state` AS t1_r9, `customers`.`service_zip_code` AS t1_r10, `customers`.`billing_address` AS t1_r11, `customers`.`billing_city` AS t1_r12, `customers`.`billing_state` AS t1_r13, `customers`.`billing_zip_code` AS t1_r14, `customers`.`special_instructions` AS t1_r15, `customers`.`email_address` AS t1_r16, `customers`.`alt_phone_number` AS t1_r17, `customers`.`parent_id` AS t1_r18, `customers`.`qb_parent_list_id` AS t1_r19, `customers`.`password` AS t1_r20, `customers`.`list_id` AS t1_r21, `customers`.`time_created` AS t1_r22, `customers`.`time_modified` AS t1_r23, `customers`.`edit_sequence` AS t1_r24, `customers`.`full_name` AS t1_r25, `customers`.`is_active` AS t1_r26, `customers`.`parent_ref_list_id` AS t1_r27, `customers`.`sublevel` AS t1_r28, `customers`.`company_name` AS t1_r29, `customers`.`first_name` AS t1_r30, `customers`.`last_name` AS t1_r31, `customers`.`phone` AS t1_r32, `customers`.`mobile` AS t1_r33, `customers`.`pager` AS t1_r34, `customers`.`alt_phone` AS t1_r35, `customers`.`email` AS t1_r36, `customers`.`contact` AS t1_r37, `customers`.`alt_contact` AS t1_r38, `customers`.`customer_type_ref_full_name` AS t1_r39, `customers`.`terms_ref_full_name` AS t1_r40, `customers`.`sales_rep_ref_full_name` AS t1_r41, `customers`.`balance` AS t1_r42, `customers`.`total_balance` AS t1_r43, `customers`.`sales_tax_code_ref_full_name` AS t1_r44, `customers`.`item_sales_tax_ref_full_name` AS t1_r45, `customers`.`resale_number` AS t1_r46, `customers`.`account_number` AS t1_r47, `customers`.`credit_limit` AS t1_r48, `customers`.`preferred_payment_method_ref_full_name` AS t1_r49, `customers`.`job_status` AS t1_r50, `customers`.`job_start_date` AS t1_r51, `customers`.`job_projected_end_date` AS t1_r52, `customers`.`job_end_date` AS t1_r53, `customers`.`job_desc` AS t1_r54, `customers`.`job_type_ref_full_name` AS t1_r55, `customers`.`is_statement_with_parent` AS t1_r56, `customers`.`delivery_method` AS t1_r57, `customers`.`price_level_ref_full_name` AS t1_r58, `customers`.`custom_text1` AS t1_r59, `customers`.`custom_number1` AS t1_r60, `customers`.`custom_datetime1` AS t1_r61, `customers`.`custom_text2` AS t1_r62, `customers`.`custom_number2` AS t1_r63, `customers`.`custom_datetime2` AS t1_r64, `customers`.`custom_text3` AS t1_r65, `customers`.`custom_number3` AS t1_r66, `customers`.`custom_datetime3` AS t1_r67, `customers`.`custom_text4` AS t1_r68, `customers`.`custom_number4` AS t1_r69, `customers`.`custom_datetime4` AS t1_r70, `customers`.`custom_text5` AS t1_r71, `customers`.`custom_number5` AS t1_r72, `customers`.`custom_datetime5` AS t1_r73, `customers`.`custom_text6` AS t1_r74, `customers`.`custom_number6` AS t1_r75, `customers`.`custom_datetime6` AS t1_r76, `customers`.`custom_text7` AS t1_r77, `customers`.`custom_number7` AS t1_r78, `customers`.`custom_datetime7` AS t1_r79, `customers`.`custom_text8` AS t1_r80, `customers`.`custom_number8` AS t1_r81, `customers`.`custom_datetime8` AS t1_r82, `customers`.`custom_text9` AS t1_r83, `customers`.`custom_number9` AS t1_r84, `customers`.`custom_datetime9` AS t1_r85, `customers`.`custom_text10` AS t1_r86, `customers`.`custom_number10` AS t1_r87, `customers`.`custom_datetime10` AS t1_r88, `customers`.`updated_at` AS t1_r89, `customers`.`service_country` AS t1_r90, `customers`.`billing_country` AS t1_r91, `customers`.`sales_tax_code_ref_list_id` AS t1_r92, `customers`.`item_sales_tax_ref_list_id` AS t1_r93, `customers`.`custom_text11` AS t1_r94, `customers`.`custom_text12` AS t1_r95, `customers`.`custom_text13` AS t1_r96, `customers`.`custom_text14` AS t1_r97, `customers`.`custom_text15` AS t1_r98, `customers`.`custom_text16` AS t1_r99, `customers`.`custom_text17` AS t1_r100, `customers`.`custom_text18` AS t1_r101, `customers`.`custom_text19` AS t1_r102, `customers`.`custom_text20` AS t1_r103, `customers`.`created_by` AS t1_r104, `customers`.`updated_by` AS t1_r105, `customers`.`tax_id` AS t1_r106, `customers`.`which_billing_address` AS t1_r107, `customers`.`customer_type_id` AS t1_r108, `customers`.`customer_source_id` AS t1_r109 FROM `contacts` LEFT OUTER JOIN `customers` ON `customers`.`id` = `contacts`.`customer_id` WHERE (`contacts`.account_id = 1) AND (contacts.first_name||' '||contacts.last_name LIKE '%David Crocker%') ORDER BY customers.name LIMIT 30 OFFSET 0

1 个答案:

答案 0 :(得分:1)

要解决您的问题,您可以在搜索条件中执行一些sql hax:

创建一个将两个名称合并为一个列的列。

contact_searchable_columns = [
  "contacts.first_name||' '||contacts.last_name",
  ...
]

这样查询就是这样的:

SELECT * FROM contacts WHERE contacts.first_name||' '||contacts.last_name LIKE '%David Crocker%' ... 

这个想法很简单,所以我相信你可以适应你自己的领域。

编辑:

尝试使用concat()而不是||像这样:

contact_searchable_columns = [
  "concat('contacts.first_name', ' ', 'contacts.last_name')",
  ...
]

我没试过这个,所以我认为语法可能包含错误。