Clear ORM
  • Welcome to Clear
  • Introduction
    • Setup
  • Model
    • Defining your model
      • Describing your columns
      • Primary Keys
      • Converters
    • Associations
      • belongs_to
      • has_many
      • has_many through
      • has_one
    • Lifecycle
      • Persistence
      • Validations
      • Triggers
    • Batchs operations
      • Bulk update
      • Bulk insert & delete
    • Transactions & Save Points
      • Transaction & Savepoints
      • Connection pool
    • Locks
  • Querying
    • The collection object
      • Filter the query
        • Filter the query – The Expression Engine
        • Find, First, Last, Offset, Limit
        • Aggregation
        • Ordering & Group by
      • Fetching the query
        • Each and Fetch
        • Cursored fetching
        • Model extra attributes
      • Joins
      • Eager Loading
      • Window and CTE
      • Scopes
    • Writing low-level SQL
      • Select Clause
      • Insert Clause
      • Delete Clause
  • Migrations
    • Manage migrations
    • Call migration script
    • Migration CLI
  • Additional and advanced features
    • JSONB
    • Symbol vs String
    • Enums
    • BCrypt
    • Full Text Search
    • Handling multi-connection
  • Other resources
    • API Documentation
    • Inline documentation
    • Github repository
    • Credits
    • Benchmark
Powered by GitBook
On this page
  • Common Table Expressions (CTE)
  • Window
  1. Querying
  2. The collection object

Window and CTE

PreviousEager LoadingNextScopes

Last updated 6 years ago

Common Table Expressions (CTE)

PostgreSQL offers writing of . Common Table Expressions are useful to define temporary SQL query used in a bigger query.

For this example, let's assume we want to count the new user creation per day during the month of September. One way would be to Group by EXTRACT('day' FROM created_at) , but days without new user will return not rows, where we want it to return zero.

In this case, using joins onto a generated series of day is the way to go. CTE makes it very simple to write and manage:

dates_in_september = Clear::SQL.select({
    day_start: "generate_series(date '2018-09-01', date '2018-09-30', '1 day'::interval)",
    day_end: "generate_series(date '2018-09-01', date '2018-09-30', '1 day'::interval) + '1 day'::interval";
})

Clear::SQL.select({
    count: "COUNT(users.*)",
    day: "dates.day_start"
})
  .with_cte(dates: dates_in_septembers)
  .from("dates")
  .left_joins(User.table){ (users.created_at >= day_start) & (users.created_at < day_end) }
  .group_by("dates.day_start")
  .order_by("dates.day_start")
  .fetch do |hash|
      puts "users created the #{hash["day"]}: #{hash["count"]}"
  end

Since all model collections are SQL query, you can pass collection as parameter of with_cte block.

Window

Clear::SQL
    .select("sum(salary) OVER w", "avg(salary) OVER w")
    .from("empsalary")
    .window({w: "(PARTITION BY depname ORDER BY salary DESC)"})

You can using window method:

Common Table Expressions (CTE)
pass window