【发布时间】:2017-06-08 19:33:00
【问题描述】:
我在 SQL 和 Arel 方面太糟糕了。我什至不知道 Arel 是什么或如何使用它。有这方面的好资源吗?
我有一个问题,我不知道为什么我花了这么长时间。也许人们可以指出为什么这需要我这么长时间。
无论如何,我有一个Products 表和一个Restrictions 表。一个产品可以有很多限制。限制是美国的一个州。我的大部分产品没有限制,但我的一种产品有限制(它不能在“CT”销售,因为“CT”有疯狂的法律)。
我想退回所有在 CT 中没有限制的产品。但是,此查询不起作用:
Product.joins(:restrictions).where.not(restrictions: { name: "CT" }).count
所以我希望退回我的所有产品,除了那些限制 CT 的产品。但是,它什么也不返回:
Product.last.restrictions
Product Load (0.5ms) SELECT "products".* FROM "products" ORDER BY "products"."id" DESC LIMIT 1
Restriction Load (0.3ms) SELECT "restrictions".* FROM "restrictions" INNER JOIN "product_restrictions" ON "restrictions"."id" = "product_restrictions"."restriction_id" WHERE "product_restrictions"."product_id" = $1 [["product_id", 2559]]
[
#<Restriction:0x007ff0f1dfec58> {
:id => 11,
:category => "US State",
:name => "CT",
:created_at => Wed, 07 Jun 2017 17:57:42 UTC +00:00,
:updated_at => Wed, 07 Jun 2017 17:57:42 UTC +00:00
}
]
[48] pry(main)> Product.count
(0.6ms) SELECT COUNT(*) FROM "products"
2494
[49] pry(main)> Product.joins(:restrictions).where.not(restrictions: { name: "AZ" }).count
(47.8ms) SELECT COUNT(*) FROM "products" INNER JOIN "product_restrictions" ON "product_restrictions"."product_id" = "products"."id" INNER JOIN "restrictions" ON "restrictions"."id" = "product_restrictions"."restriction_id" WHERE ("restrictions"."name" != $1) [["name", "AZ"]]
1
[50] pry(main)> Product.joins(:restrictions).where.not(restrictions: { name: "CT" }).count
(6.7ms) SELECT COUNT(*) FROM "products" INNER JOIN "product_restrictions" ON "product_restrictions"."product_id" = "products"."id" INNER JOIN "restrictions" ON "restrictions"."id" = "product_restrictions"."restriction_id" WHERE ("restrictions"."name" != $1) [["name", "CT"]]
0
我希望最后一个查询返回 2493(只有最后一个产品有限制),而不是 0。我希望 AZ 查询返回 2494,而不是 0。
但是,这个 hood sql 可以工作(使用 NOT EXISTS):
state = "CT"
Product.where('NOT EXISTS ' \
'(SELECT 1 from restrictions
JOIN product_restrictions
on product_id = products.id
WHERE restrictions.name = ? AND restrictions.category = ?)', state, 'US State'
)
}
aboe 查询返回所有产品,除了 CT 中有限制的产品
问题
- 为什么我使用联接的第一个查询不起作用?
- 我怎样才能在这里变得更好?有没有关于sql的好书?
- 有没有更好的方法来编写不使用类似 SQL 字符串的解决方案?
【问题讨论】:
标签: sql ruby-on-rails activerecord