Rails 求一个 Rails 方式查询数据!

kai209209 · 发布于 2017年05月10日 · 最后由 kai209209 回复于 2017年05月12日 · 938 次阅读
9401

各位老爷们,大家好,我现在遇到一个问题,描述如下 有2个model package 和 main_combine_package_item 然后现在系统需要将符合某些条件的package合并起来,然后我就通过一个main_combine_package_item关联package。 现在我想找出符合某些条件的main_combine_package_item数据,现在这里有一个sql语句能找到我所需要的

SELECT  i.main_package_id, mp.state, i.combined_package_id, cp.state FROM main_combine_package_items i, packages mp, packages cp WHERE i.main_package_id = mp.id AND i.combined_package_id = cp.id AND (mp.state NOT IN (9, 10) OR cp.state NOT IN (9, 10)) AND mp.warehouse_id = 1

然后我就直接通过sql来查出数据

MainCombinePackageItem.find_by_sql("SELECT  i.main_package_id, mp.state, i.combined_package_id, cp.state FROM main_combine_package_items i, packages mp, packages cp WHERE i.main_package_id = mp.id AND i.combined_package_id = cp.id AND (mp.state NOT IN (9, 10) OR cp.state NOT IN (9, 10)) AND mp.warehouse_id = 1")

现在我想问的是,如何写一个rails风格的代码,让rails生成这样的查询语句呢? 注意是风格!!!

共收到 13 条回复
17727

类似拆订单那种业务?

9401

是的,公司是电商,是用到这样的

10570

not in的写法效率好差,用不到索引,数据量大不建议这样用.业务必须这样写吗,有没有考虑从业务上做拆分,或者分几次查询

27940
MainCombinePackageItem.joins(:packages).where("packages.state not in (?) and packages.warehouse_id = (?)", [9, 10], 1 )

是要这个样子吗?

23529

rails在joins和eager_load同一个表的时候会加上别名的:

MainCombinedPackageItem.joins(:main_package, :combined_package)
SELECT "main_combined_package_items".* FROM "main_combined_package_items" INNER JOIN "packages" ON "packages"."id" = "main_combined_package_items"."main_package_id" INNER JOIN "packages" "combined_packages_main_combined_package_items" ON "combined_packages_main_combined_package_items"."id" = "main_combined_package_items"."combined_package_id"

第二个packages表加了combined_packages_main_combined_package_items的别名,可以直接在where用,但是我觉得这样不好,干脆直接写sql或者用把sql拆成手写的joins() where()

9401
10570michael0015 回复

估计每天有十几二十单这样的吧,不是很多

9401
27940yu7272yu 回复

不是的

9401
23529mizuhashi 回复

我就是想拆成你说的,就只是不知道应该怎么来拆

23529
9401kai209209 回复

MainCombinePackageItem.joins('INNER JOIN packages main_package ON main_package.id = main_combine_package_items.main_package_id')
                      .joins('INNER JOIN packages combined_package ON combined_package.id = main_combine_package_items.combined_package_id')
                      .where('main_package.state NOT IN ? or combined_package.state NOT IN ?', [9, 10], [9, 10])
                      .where(warehouse_id: 1)

像楼上说的not in如果用不到索引的话,可以改成in,一共有哪些状态是知道的

9401
23529mizuhashi 回复

not in查询效率这么差吗?我对sql跟数据库不是很熟悉

27940
9401kai209209 回复

那我就没懂了。。。

17727
9401kai209209 回复

main和combine放在一个表里,用AR风格的话还要考虑别名的转换,太蛋疼了

追求风格的话应该从表结构、model结构开始,不然真的很别扭……当然,我不知道你表结构是否真的有必要定成这样,以及改起来是否很大风险……

9401

有的时候只是想写的代码好看些

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册