Laravel Eloquent, wobei das Feld X oder null ist

74

Ich habe einen Tisch wie diesen:

table
- field1: tinyint
- field2: varchar (nullable)
- datefield: timestamp (nullable)

Jetzt möchte ich alle Einträge erhalten, bei denen Feld1 1, Feld2 null und Datumsfeld kleiner als X oder null ist. Ich habe schon so etwas ausprobiert:

$query = Model::where('field1', 1)
            ->whereNull('field2')
            ->where('datefield', '<', $date)
            ->orWhereNull('datefield');

aber das funktioniert nicht. Ich bekomme immer jeden Eintrag, bei dem das Datumsfeld null ist. Es spielt keine Rolle, was die anderen Felder sind. Ich habe auch versucht, es in zwei Abfragen aufzuteilen: Zuerst jede Zeile abrufen, in der das Datumsfeld kleiner als X oder null ist, und dann (basierend darauf) jedes Feld abrufen, in dem Feld1 1 und Feld2 null ist.

Das Ergebnis war das gleiche. Irgendeine Idee, wie das geht?

festie
quelle

Antworten:

142

Es hört sich so an, als müssten Sie erweiterte where-Klauseln verwenden .

Angesichts der Tatsache, dass die Suche in field1und field2konstant ist, werden wir sie unverändert lassen, aber wir werden Ihre Suche in Kürze anpassen datefield.

Versuche dies:

$query = Model::where('field1', 1)
    ->whereNull('field2')
    ->where(function ($query) {
        $query->where('datefield', '<', $date)
            ->orWhereNull('datefield');
    }
);

Wenn Sie jemals eine Abfrage debuggen müssen, um festzustellen, warum sie nicht funktioniert, kann es hilfreich sein, festzustellen, welche SQL-Datei tatsächlich ausgeführt wird. Sie können ->toSql()bis zum Ende Ihrer beredten Abfrage verketten, um SQL zu generieren.

James
quelle
3
Das hat mir etwas Frust erspart! Vielen Dank.
Bhargav Nanekalva
kann es durch etwas wie gemacht werden: whereIn ('column', ['value', null])?
MASh
@MASh nicht sicher. Ich habe das vor einiger Zeit geschrieben und es war damals der beste Ansatz. Warum probieren Sie es nicht aus?
James
Ich verwende den Ansatz, den Sie hier geschrieben haben, normalerweise. Versucht und es holte nichts aus der Datenbank. Möglicherweise behandeln Datenbank-Engines null anders als value. Ich wollte wissen, ob es eine Möglichkeit gibt, die Null innerhalb des Arrays zu übergeben.
MASh
@MASh: Ja, Datenbanken behandeln Werte und NULL unterschiedlich (die Zeichenfolge "null" ist ein normaler Wert). Normale Bedingungen, unter denen Sie Werte vergleichen, haben ein definiertes Ergebnis. Vergleiche mit NULL sind undefiniert, da NULL etwas Unbekanntes darstellt und der Vergleich eines Werts mit etwas Unbekanntem nicht zu einem Ergebnis führen kann. Um zu überprüfen, ob in einer Abfrage etwas NULL ist, verwenden Sie "IS" -> "wobei Feld1 NULL ist"
kühl am
4

Sie können zwei Abfragen zusammenführen:

$merged = $query_one->merge($query_two);
kaleazy
quelle
1

Mit coalesce () wird null in 0 konvertiert:

$query = Model::where('field1', 1)
    ->whereNull('field2')
    ->where(DB::raw('COALESCE(datefield_at,0)'), '<', $date)
;
ebelendez
quelle