2016-04-13 8 views
0

Ich möchte wissen, schreiben p.amount is null bei case .. when Funktion ist besser, oder schreiben Sie es bei WHERE Klausel?Setzen Sie eine Bedingung auf CASE .. WANN vs WHERE-Klausel?

ONE:

select *, 
    case when p.amount is null then '1' 
      else (select count(1) 
        from Money_paid mp 
       where mp.post_id = p.id and mp.user_id = :user_id limit 1) 
    end paid 
from Posts p 
where p.id = :post_id 

ZWEI:

select *, 
     (select count(1) 
     from Money_paid mp 
      where mp.post_id = p.id and 
       mp.user_id = :user_id and 
       p.amount is not null 
     limit 1) paid 
from Posts p 
where p.id = :post_id 

So welche?

+1

warum alle mit LIMIT 1 auf ? – Quassnoi

+0

Was möchten Sie zurückgeben? Die Zahl, die bezahlt haben oder eine Flagge? Außerdem sind die Rückgabewerte nicht gleich, wenn "p.amount null ist" (der erste gibt 1 und der zweite 0 zurück). –

+0

@GordonLinoff Nein, ich will nicht die Nummer, die bezahlt haben, ich will nur überprüfen, gibt es eine Zeile? (gerade vorhanden) – stack

Antwort

1

Ob die IS NULL Check in COALESCE oder in der WHERE Klausel verwenden, keinen praktischen Unterschied, jedoch hat man COUNT mit EXISTS ersetzen sollten, wenn Sie nur ein benötigen Datensatz geprüft:

SELECT *, 
     CASE WHEN p.amount IS NULL THEN 1 
     ELSE 
     EXISTS 
     (
     SELECT NULL 
     FROM money_paid 
     WHERE post_id = p.id 
       AND user_id = :user_id 
     ) 
     END 
FROM posts p 
WHERE p.id = :post_id 
+0

Warum 'SELECT NULL ..'? Ich möchte diese Ausgaben: "1", wenn der Benutzer bezahlt hat oder die Post ist kostenlos oder "0", wenn es nicht kostenlos ist und der Benutzer nicht bezahlt hat. – stack

+0

@stack: das ist, was 'EXISTS' behandelt. Es spielt keine Rolle, was in 'EXISTS' steht, Sie können' SELECT * 'oder' SELECT 1' oder so ziemlich alles verwenden, was Sie wollen. Ich benutze 'SELECT NULL', weil ich daran gewöhnt bin. – Quassnoi

+0

Nur zu meiner Information, können Sie mir bitte sagen, ist es möglich, dies über 'Join' anstelle von Unterabfrage zu implementieren? – stack

1

Weder. Der bessere Weg, dies zu schreiben verwendet exists:

select p.*, 
     (case when p.amount is null then 0 -- 0 seems more reasonable than 1 
      when exists (select 1 
          from Money_paid mp 
          where mp.post_id = p.id and mp.user_id = :user_id 
         ) 
      then 1 else 0 
     end) as IsPaidFlag 
from Posts p 
where p.id = :post_id; 

Meine Tendenz mit dem separaten case Zustand zu gehen wäre. Die zwei Versionen optimieren wahrscheinlich zum selben Ergebnis. Die externe Korrelation könnte jedoch auch den Optimierer verwirren.

+0

In Ihrer Abfrage, wenn Post frei ist, dann Ausgabe ist" 0 ", wenn Post nicht frei ist und der Benutzer hat es nicht bezahlt, dann ist Ausgabe" 0 " , wenn die Post nicht frei ist und der Nutzer sie bezahlt, dann "1" ...! Diese Struktur ist schwer zu handhaben. Ich möchte dieses '1, 0, 1' * (Ihres ist' 0, 0, 1') *. Also kann ich einfach so damit umgehen: 'if ($ result ['paid'] == 1) {show it} sonst {dont show it}' – stack

+0

@stack. . . Wie in der Antwort gesagt, können Sie einfach "1" für die erste Bedingung setzen. Ich finde das nur peinlich. Und die Frage selbst ist bezüglich des Wertes in diesem Fall mehrdeutig. –

Verwandte Themen