Daten abfragen

Erfahren Sie, wie Sie Daten aus Ihrer Datenbank abfragen und filtern.

Hinweis: Dies sind Beispiel- bzw. Platzhalterinhalte zu Demonstrationszwecken.

Fragen Sie Daten effizient mit dem Query Builder von Supabase ab und filtern Sie sie.

Einfache Abfragen

Alles auswählen

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

Bestimmte Spalten auswählen

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

Mit verknüpften Daten auswählen

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

Filtern

Gleich

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

Ungleich

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

Größer als / Kleiner als

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

In einem Array

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

Like (Mustervergleich)

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

Volltextsuche

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

Sortierung

Sortieren nach

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

Nach mehreren Spalten sortieren

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

Paginierung

Limit

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

Bereich (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);

Aggregationen

Anzahl

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

Anzahl mit Filtern

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

Erweiterte Abfragen

Mehrere Filter

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);

ODER-Bedingungen

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

Verschachteltes ODER

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(*)
  `);

Umgang mit Null-Werten

Ist Null

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

Nicht Null

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

Daten einfügen

Einzelnes Einfügen

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

Mehrfaches Einfügen

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

Daten aktualisieren

Aktualisieren mit Filter

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

Mehrere Zeilen aktualisieren

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

Daten löschen

Löschen mit Filter

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

Mehrere löschen

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

Upsert

Einfügen oder aktualisieren

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

RPC (Stored Procedures)

Datenbankfunktion aufrufen

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

Mit komplexen Parametern

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

Fehlerbehandlung

Grundlegende Fehlerbehandlung

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

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

return data;

Typisierte Fehlerbehandlung

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-Typen

Generierte Typen

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'];

Typisierte Abfragen

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

Tipps zur Performance

  1. Nur benötigte Spalten auswählen – Verwenden Sie select('*') nicht unnötig
  2. Indizes verwenden – Erstellen Sie Indizes für häufig gefilterte Spalten
  3. Ergebnisse begrenzen – Paginieren Sie große Datenmengen immer
  4. N+1-Abfragen vermeiden – Verwenden Sie Joins statt mehrerer Abfragen
  5. RPC für komplexe Abfragen nutzen – Verlagern Sie Logik in die Datenbank
  6. Wenn möglich cachen – Verwenden Sie React Query oder Vergleichbares
  7. Abfragen analysieren – Verwenden Sie EXPLAIN ANALYZE in SQL

Best Practices

  1. Fehler immer behandeln – Prüfen Sie Fehlerantworten
  2. Eingaben validieren – Verwenden Sie Zod oder Vergleichbares
  3. TypeScript verwenden – Generieren und verwenden Sie Typen
  4. Einheitliche Benennung – Halten Sie sich an die Namenskonventionen der Datenbank
  5. Komplexe Abfragen dokumentieren – Fügen Sie Kommentare hinzu
  6. Abfragen testen – Schreiben Sie Unit-Tests für Datenbankoperationen
  7. Performance überwachen – Behalten Sie langsame Abfragen im Blick