PriceLogicPriceLogic

The AI Platform for Marketplace Sellers

© Copyright 2025 PriceLogic, Inc. All Rights Reserved.

About
  • Blog
  • Contact
Product
  • Pricing
Legal
  • Terms of Service
  • Privacy Policy
  • Cookie Policy
  • Getting started with PriceLogic
    • Quick Start
    • Project Structure
    • Configuration
  • Diana API
  • Email & Password
  • Database
    • Database Overview
    • Migrations
    • Row Level Security
    • Querying Data
    • Functions & Triggers
  • OAuth
  • Features
    • Features Overview
    • Team Collaboration
    • File Uploads
  • Magic Links
  • Billing & Payments
    • Billing Overview
    • Pricing Plans
    • Webhook Integration

Querying Data

Learn how to query and filter data from your database.

Note: This is mock/placeholder content for demonstration purposes.

Efficiently query and filter data using Supabase's query builder.

Basic Queries

Select All

const { data, error } = await client
  .from('projects')
  .select('*');

Select Specific Columns

const { data, error } = await client
  .from('projects')
  .select('id, name, created_at');

Select with Related Data

const { data, error } = await client
  .from('projects')
  .select(`
    id,
    name,
    account:accounts(id, name),
    tasks(id, title, completed)
  `);

Filtering

Equal

const { data } = await client
  .from('projects')
  .select('*')
  .eq('status', 'active');

Not Equal

const { data } = await client
  .from('projects')
  .select('*')
  .neq('status', 'deleted');

Greater Than / Less Than

const { data } = await client
  .from('projects')
  .select('*')
  .gt('created_at', '2024-01-01')
  .lt('budget', 10000);

In Array

const { data } = await client
  .from('projects')
  .select('*')
  .in('status', ['active', 'pending']);

Like (Pattern Matching)

const { data } = await client
  .from('projects')
  .select('*')
  .like('name', '%website%');

Full-Text Search

const { data } = await client
  .from('projects')
  .select('*')
  .textSearch('description', 'design & development');

Ordering

Order By

const { data } = await client
  .from('projects')
  .select('*')
  .order('created_at', { ascending: false });

Multiple Order By

const { data } = await client
  .from('projects')
  .select('*')
  .order('status')
  .order('created_at', { ascending: false });

Pagination

Limit

const { data } = await client
  .from('projects')
  .select('*')
  .limit(10);

Range (Offset)

const page = 2;
const pageSize = 10;
const from = (page - 1) * pageSize;
const to = from + pageSize - 1;

const { data, count } = await client
  .from('projects')
  .select('*', { count: 'exact' })
  .range(from, to);

Aggregations

Count

const { count } = await client
  .from('projects')
  .select('*', { count: 'exact', head: true });

Count with Filters

const { count } = await client
  .from('projects')
  .select('*', { count: 'exact', head: true })
  .eq('status', 'active');

Advanced Queries

Multiple Filters

const { data } = await client
  .from('projects')
  .select('*')
  .eq('account_id', accountId)
  .eq('status', 'active')
  .gte('created_at', startDate)
  .lte('created_at', endDate)
  .order('created_at', { ascending: false })
  .limit(20);

OR Conditions

const { data } = await client
  .from('projects')
  .select('*')
  .or('status.eq.active,status.eq.pending');

Nested OR

const { data } = await client
  .from('projects')
  .select('*')
  .or('and(status.eq.active,priority.eq.high),status.eq.urgent');

Joins

Inner Join

const { data } = await client
  .from('projects')
  .select(`
    *,
    account:accounts!inner(
      id,
      name
    )
  `)
  .eq('account.name', 'Acme Corp');

Left Join

const { data } = await client
  .from('projects')
  .select(`
    *,
    tasks(*)
  `);

Null Handling

Is Null

const { data } = await client
  .from('projects')
  .select('*')
  .is('completed_at', null);

Not Null

const { data} = await client
  .from('projects')
  .select('*')
  .not('completed_at', 'is', null);

Insert Data

Single Insert

const { data, error } = await client
  .from('projects')
  .insert({
    name: 'New Project',
    account_id: accountId,
    status: 'active',
  })
  .select()
  .single();

Multiple Insert

const { data, error } = await client
  .from('projects')
  .insert([
    { name: 'Project 1', account_id: accountId },
    { name: 'Project 2', account_id: accountId },
  ])
  .select();

Update Data

Update with Filter

const { data, error } = await client
  .from('projects')
  .update({ status: 'completed' })
  .eq('id', projectId)
  .select()
  .single();

Update Multiple Rows

const { data, error } = await client
  .from('projects')
  .update({ status: 'archived' })
  .eq('account_id', accountId)
  .lt('updated_at', oldDate);

Delete Data

Delete with Filter

const { error } = await client
  .from('projects')
  .delete()
  .eq('id', projectId);

Delete Multiple

const { error } = await client
  .from('projects')
  .delete()
  .in('id', projectIds);

Upsert

Insert or Update

const { data, error } = await client
  .from('projects')
  .upsert({
    id: projectId,
    name: 'Updated Name',
    status: 'active',
  })
  .select()
  .single();

RPC (Stored Procedures)

Call Database Function

const { data, error } = await client
  .rpc('get_user_projects', {
    user_id: userId,
  });

With Complex Parameters

const { data, error } = await client
  .rpc('search_projects', {
    search_term: 'design',
    account_ids: [1, 2, 3],
    min_budget: 5000,
  });

Error Handling

Basic Error Handling

const { data, error } = await client
  .from('projects')
  .select('*');

if (error) {
  console.error('Error fetching projects:', error.message);
  throw error;
}

return data;

Typed Error Handling

import { PostgrestError } from '@supabase/supabase-js';

function handleDatabaseError(error: PostgrestError) {
  switch (error.code) {
    case '23505': // unique_violation
      throw new Error('A project with this name already exists');
    case '23503': // foreign_key_violation
      throw new Error('Invalid account reference');
    default:
      throw new Error('Database error: ' + error.message);
  }
}

TypeScript Types

Generated Types

import { Database } from '~/types/database.types';

type Project = Database['public']['Tables']['projects']['Row'];
type ProjectInsert = Database['public']['Tables']['projects']['Insert'];
type ProjectUpdate = Database['public']['Tables']['projects']['Update'];

Typed Queries

const { data } = await client
  .from('projects')
  .select('*')
  .returns<Project[]>();

Performance Tips

  1. Select only needed columns - Don't use select('*') unnecessarily
  2. Use indexes - Create indexes on frequently filtered columns
  3. Limit results - Always paginate large datasets
  4. Avoid N+1 queries - Use joins instead of multiple queries
  5. Use RPC for complex queries - Move logic to database
  6. Cache when possible - Use React Query or similar
  7. Profile queries - Use EXPLAIN ANALYZE in SQL

Best Practices

  1. Always handle errors - Check error responses
  2. Validate input - Use Zod or similar
  3. Use TypeScript - Generate and use types
  4. Consistent naming - Follow database naming conventions
  5. Document complex queries - Add comments
  6. Test queries - Unit test database operations
  7. Monitor performance - Track slow queries
  1. Basic Queries
    1. Select All
    2. Select Specific Columns
    3. Select with Related Data
    4. Filtering
    5. Ordering
    6. Pagination
    7. Aggregations
    8. Advanced Queries
    9. Joins
    10. Null Handling
    11. Insert Data
    12. Update Data
    13. Delete Data
    14. Upsert
    15. RPC (Stored Procedures)
    16. Error Handling
    17. TypeScript Types
    18. Performance Tips
    19. Best Practices