On Thursday, November 5, 2015 at 1:45:26 PM UTC-8, flyer wrote:
>
>
>
> On Thursday, November 5, 2015 at 5:25:24 PM UTC-3, Jeremy Evans wrote:
>
> On Thursday, November 5, 2015 at 12:14:32 PM UTC-8, flyer wrote:
>
> Hi, I am struggling a lot trying to translate this query into Sequel DSL. 
> Suppose I have the following table schemas (only showing meaningful 
> columns):
>
>                                          Table "public.products"
>        Column        |            Type             |                     
>   Modifiers                       
>
> ---------------------+-----------------------------+-------------------------------------------------------
>  id                  | integer                     | not null default 
> nextval('products_id_seq'::regclass)
>  name                | character varying(45) 
>  product_category_id | integer                     | 
>
>
>                                         Table "public.product_categories"
>         Column         |          Type          |                         
>    Modifiers                            
>
> -----------------------+------------------------+-----------------------------------------------------------------
>  id                    | integer                | not null default nextval
> ('product_categories_id_seq'::regclass)
>  name                  | character varying(255)
>  parent_id             | integer                | 
>
> So products can have categories, and categories can have subcategories. 
> Moreover products may belong to a parent category and not necessarily to 
> subcategories. So suppose I have the following categories and products data:
>
> Categories Table
>
> id name             parent_id
> 1  Drinks
> 2  Starters
> 3  Alcohol          1
> 4  Without Alcohol  1
> 5  Cold             2
> 6  Hot              2
>
> Products Table
>
>
> id name          product_category_id
> 1  Coca-Cola     4
> 2  Water         4
> 3  Wine          3
> 4  Beer          3
> 5  Orange Juice  1
> 6  Picada Chica  2
> 7  Muzz Milanesa 6
> 8  Salpicon Ave  5
>
> So notice that some products just belong to "main_categories". What I want 
> to do is return a set ordered alphabetically first by "main_category", then 
> by "subcategory" and finally by product name. I was able to do this in 
> plain SQL executing the following query:
>
> SELECT p.name, p.id, p.product_category_id, ij.main_category, ij.subcategory 
> FROM
>   products p inner join
>   (select pc.id, coalesce(pcc.name, pc.name) main_category, case when 
> pcc.name 
> is not null THEN pc.name end subcategory FROM product_categories pc left 
> join product_categories pcc on pc.parent_id = pcc.id) ij on 
> p.product_category_id 
> = ij.id order by ij.main_category, ij.subcategory nulls first, p.name;
>
>
> Assuming you are using models, I think this will work:
>
> Product.many_to_one :category
> Category.many_to_one :parent
>
> Product.association_left_join(:category=>:parent).
>   exclude(:category__id=>nil).
>   select(:product__name, :product__id, :product__product_category_id, 
> :parent__name___main_category, :category__name___subcategory).
>   order(:parent__name___main_category, :category__name___subcategory, 
> :product__name)
>
> It works differently from your query, as it doesn't join to a subquery. 
>  Not sure which performs better, you'd have to benchmark.  If you want a 
> more direct translation of the subquery approach that doesn't use model 
> associations, please let me know.
>
> Thanks,
> Jeremy
>
>
>
> Thanks for your reply Jeremy. Yes I am using Sequel models. In your query, 
> when you qualify the products table, instead of :product shouldnt it be 
> :producs?
>
> Unfortunately your aproarch did not work. I mean, it worked, but not with 
> the expected order. I think the main problem there is with null 
> "main_category" values. And those are the products that do not belong to 
> any subcategories. Or is the same to say: products that belong to 
> "main_categories". So for example, with a local test I obtained the 
> following result executing the query:
>
>                   name                  | id | product_category_id | 
> main_category |    subcategory     
>
> ----------------------------------------+----+---------------------+---------------+--------------------
>  Agua Mineral 200 cm3 edit2             |  9 |                  11 | 
> Bebidas       | Sin alcohol
>  Agua Mineral Gasificada                | 50 |                  11 | 
> Bebidas       | Sin alcohol
>  Coca-Cola 375 cm3                      |  1 |                  11 | 
> Bebidas       | Sin alcohol
>  Tinto                                  | 21 |                   9 | 
> Bebidas       | Vinos
>  Medialunas                             |  8 |                  30 | 
> Cafetería     | Medialunas
>  Muzzarella a la Milanesa               | 44 |                  20 | 
> Entradas      | Calientes
>  Revuelto de Gramajo                    | 47 |                  20 | 
> Entradas      | Calientes
>  Tortilla de Papas                      | 52 |                  20 | 
> Entradas      | Calientes
>  Salpicon de Ave                        | 49 |                  19 | 
> Entradas      | Frias
>  Vitel Tone                             | 45 |                  19 | 
> Entradas      | Frias
>  Aquarius                               | 36 |                   1 |     
>           | Bebidas
>  Coca Zero                              | 54 |                   1 |     
>           | Bebidas
>  Crush                                  | 34 |                   1 |     
>           | Bebidas
>  Paso de los Toros                      | 35 |                   1 |     
>           | Bebidas
>  Pesi                                   | 46 |                   1 |     
>           | Bebidas
>  Sprite 375 cm3                         | 23 |                   1 |     
>           | Bebidas
>  Cafe Chico                             |  6 |                   2 |     
>           | Cafetería
>  Cafe Jarrito                           |  7 |                   2 |     
>           | Cafetería
>  Capuccino                              | 18 |                   2 |     
>           | Cafetería
>  Submarino                              | 24 |                   2 |     
>           | Cafeter
>

Yeah, the results are different in those cases.  If you want the results 
you originally posted, you will have to use a similar case statement as you 
used in your subquery approach for both the main_category and subcategory.

Something like:

Product.association_left_join(:category=>:parent).
  exclude(:category__id=>nil).
  select(:product__name, :product__id, :product__product_category_id,
    Sequel.function(:coalesce, :parent__name, 
:category__name).as(:main_category),
    Sequel.case({{:parent__name=>nil}=>nil}, 
:category__name).as(:subcategory)).
  order(4,5,1)

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