it "exists_sample1" do o = Arel::Table.new(:orders) o.table_alias = "o" od = Arel::Table.new(:order_details) od.table_alias = "od" q1 = od. where(od[:order_no].eq(o[:order_no])). where(od[:quantity].gt(10)). project(Arel.sql("1")) q = o. where(q1.exists). project(o[Arel.star]) q.to_sql.should eq "SELECT `o`.*" + " FROM `orders` `o` " + " WHERE EXISTS (SELECT 1" + " FROM `order_details` `od` " + " WHERE `od`.`order_no` = `o`.`order_no`" + " AND `od`.`quantity` > 10)" end it "not_exists_sample1" do o = Arel::Table.new(:orders) o.table_alias = "o" od = Arel::Table.new(:order_details) od.table_alias = "od" q1 = od. where(od[:order_no].eq(o[:order_no])). where(od[:quantity].gt(10)). project(Arel.sql("1")) # 'not_exists' does not exists. We use 'not' for 'exists'. q = o. where(q1.exists.not). project(o[Arel.star]) q.to_sql.should eq "SELECT `o`.*" + " FROM `orders` `o` " + " WHERE NOT (EXISTS (SELECT 1" + " FROM `order_details` `od` " + " WHERE `od`.`order_no` = `o`.`order_no`" + " AND `od`.`quantity` > 10))" end it "between_sample1" do i = Arel::Table.new(:items) i.table_alias = "i" date = Date.new(2013,7,24) # Arel does not support BETWEEN expression directly. # So we have to use Arel.sql. # We can use 'ActiveRecord::Base.sanitize' method for sanitize data. # The Model class, for example Item, can be used instead of ActiveRecord::Base. # ex.) Item.sanitize(date) q = i. where(Arel.sql("#{ActiveRecord::Base.sanitize(date)} BETWEEN i.start_date AND i.end_date")). project(i[Arel.star]) q.to_sql.should eq "SELECT `i`.*" + " FROM `items` `i` " + " WHERE '2013-07-24' BETWEEN i.start_date AND i.end_date" end it "max_min_avg_alias_sample1" do od = Arel::Table.new(:order_details) od.table_alias = "od" q = od. group(od[:order_no]). project(od[:order_no], od[:quantity].maximum.as("max_qty"), od[:quantity].minimum.as("min_qty"), od[:quantity].average.as("avg_qty")) q.to_sql.should eq "SELECT `od`.`order_no`," + " MAX(`od`.`quantity`) AS max_qty," + " MIN(`od`.`quantity`) AS min_qty," + " AVG(`od`.`quantity`) AS avg_qty" + " FROM `order_details` `od` " + " GROUP BY `od`.`order_no`" end it "skip_take_sample1" do o = Arel::Table.new(:orders) o.table_alias = "o" q = o. project(o[Arel.star]). skip(30).take(10) q.to_sql.should eq "SELECT `o`.*" + " FROM `orders` `o` " + " LIMIT 10 OFFSET 30" end it "in_subquery_sample1" do i = Arel::Table.new(:items) i.table_alias = "i" i2 = Arel::Table.new(:items) i2.table_alias = "i2" q1 = i2. where(i2[:item_no].eq(i[:item_no])). where(i2[:start_date].lteq(Date.new(2013,7,24))). project(i2[:start_date].maximum.as("max_start_date")) # This case can be written as 'start_date = (SELECT MAX(start_date)...) in SQL' # But Arel does not support eq(q1) and we write the statement using 'in'. q = i. where(i[:start_date].in(q1)). project(i[Arel.star]) q.to_sql.should eq "SELECT `i`.*" + " FROM `items` `i` " + " WHERE `i`.`start_date` IN (SELECT MAX(`i2`.`start_date`) AS max_start_date" + " FROM `items` `i2` " + " WHERE `i2`.`item_no` = `i`.`item_no`" + " AND `i2`.`start_date` <= '2013-07-24')" end
Tuesday, April 30, 2013
Arel Sample (4)
I continue to write sample code for Arel.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment