如何有条件地连接并从连接表中获取数据?

qoefvg9y  于 2021-06-15  发布在  Mysql
关注(0)|答案(2)|浏览(241)

我有两张table, Product 以及 ProductNewsletter . 一个产品可以有很多 product_newsletters 因此,在rails中 has_many 产品方面的关系,以及 belongs_to 在product\u newsletter一侧,带有product\u id。这些表类似于:

products
id title... etc

product_newsletters
id product_id date

我想获取包含日期范围内的产品新闻稿的产品,并从查询中找到的产品新闻稿中选择日期。因此,如果一个产品有两个产品新闻稿,日期分别为2018年3月11日、2018年3月20日和2018年4月4日,那么查询日期介于2018年3月1日和2018年3月30日之间的产品时,应该显示两次该产品,一次显示日期为2018年3月11日,另一次显示日期为2018年3月20日。一开始,我用一个子查询尝试了这个连接:

SELECT *
     , news.date AS newsletter_date 
  FROM products 
  JOIN 
     ( SELECT newsletter_products.* 
         FROM newsletter_products 
        WHERE newsletters.date BETWEEN '2018-01-03' AND '2018-01-20'
     ) news 
    ON  products.id = news.product_id

但是这种连接会导致产品的id与子查询中的新闻稿相同,而不是子查询中的新闻稿 product_id 正如我在子查询中所期望的那样。我正在使用rubyonrails和mysql。我的想法是使用这个查询的结果来简单地做一个ruby products.group_by(&:newsletter_date) 最后得到一个很好的散列,日期作为键,产品作为值,每个日期都没有额外的查询或过滤,这是我当前的实现。

jaxagkaj

jaxagkaj1#

下面将为您提供预期的输出,

Product.joins(:product_newsletters).where(product_newsletters: { date: ['19-01-2013'.to_datetime..'19-02-2013'.to_datetime] })

如果两个product\u newsletters对象落在日期范围内,并且两个对象都具有相同的product\u id,对于上述查询,您仍将得到 2 counts 对于相同的产品id。

qf9go6mv

qf9go6mv2#

您应该这样编写查询:

SELECT p.*, n.date AS newsletter_date
FROM products p INNER JOIN 
     newsletter_products np
     ON p.id = n.product_id
WHERE np.date BETWEEN '2018-01-03' AND '2018-01-20';

笔记:
不要使用 select * . 你会得到两次新信的日期。
子查询是不必要的,可能会妨碍优化。
使用表别名使查询更易于编写和读取。
我不喜欢 between 但这就是你的逻辑。它是安全的当 date 没有时间成分。

相关问题