On Thursday, October 22, 2015 at 10:46:43 AM UTC-7, James wrote:
>
> Say you have the following simplified tables and data:
>
> Category
> - id
> - parent_id
> - name
>
> Product
> - id
> - category_id
> - name
> - price
>
> Category Data
> 1, NULL, 'GPS'
> 2, 1, 'Vehicle GPS'
> 3, 1, 'Handheld GPS'
> 4, NULL, 'GPS Accessories'
>
> Products Data
> 1, 2, 'Nuvi', 99.99
> 2, 3, 'eTrex', 99.99
> 3, 3, 'Montana', 99.99
> 4, 4, 'Carrying Case', 29.99
>
> Say I want to display only top level categories (parent_id IS NULL), where 
> a particular product matches a certain filter (e.g. price < $100).  So 
> because I'm an amateur I first try something like:
>
> SELECT categories.name
> FROM categories
> WHERE id IN (SELECT category_id FROM products WHERE price < 100.0)
> AND categories.parent_id IS NULL
>
> I quickly realize this will never work because no Products are associated 
> with root category id's.  If I know the exact number of levels, I could add 
> another category table.  However, I'm wondering if there's a way to do this 
> with recursive CTE and the rcte_plugin that will work no matter how many 
> levels down the products are?  I have been reading up on CTE, and while I 
> think I know in general what I need to do, I'm having a hard time 
> understanding CTE's or how to go about this.  Any guidance would be greatly 
> appreciated.
>

I've tested this, it appears to work:

DB.create_table(:categories) do
  Integer :id, :primary_key=>true
  foreign_key :parent_id, :categories
  String :name, :null=>false
end
DB[:categories].import([:id, :parent_id, :name], [[1, nil, 'GPS'], [2, 1, 
'Vehicle GPS'], [3, 1, 'Handheld GPS'], [4, nil, 'GPS Accessories']])

DB.create_table(:products) do
  Integer :id, :primary_key=>true
  foreign_key :category_id, :categories, :null=>false
  String :name, :null=>false
  Float :price, :null=>false
end
DB[:products].import([:id, :category_id, :name, :price], [[1, 2, 'Nuvi', 
99.99], [2, 3, 'eTrex', 99.99], [3, 3, 'Montana', 99.99], [4, 4, 'Carrying 
Case', 29.99]])

cte = DB[:c].
  with_recursive(:c,
    DB[:categories].
      select(:id, :parent_id).
      where(:id=>DB[:products].where{price < 100.0}.select(:category_id)),
    DB[:c].join(:categories, :id=>:parent_id).select(:categories__id, 
:categories__parent_id))
   
DB[:categories].
  where(:parent_id=>nil).
  where(:id=>cte.select(:id))

Thanks,
Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to