2016-06-03 10 views
1

Ich habe diese Anfrage:hinzufügen bedingte Anweisung in PostgreSQL Query

WITH grouped_messages AS 
(SELECT 
    um.conversation_id, 
    array_agg(json_build_object('message', um.message, 'sent_at', um.created_at)) 
FROM user_messages um 
    INNER JOIN users_conversations c ON c.conversation_id = um.conversation_id 
WHERE c.user_id = '#{user_id}' AND um.user_id != '#{user_id}' #{ "and um.created_at >= '#{timestamp}'" IF TIMESTAMP} 
GROUP BY um.conversation_id 
), 
    senders AS 
    (SELECT 
    gm.conversation_id, 
    json_build_object('id', u.id, 'user_name', u.user_name, 'avatar', 
         ('https://my-staging.s3.amazonaws.com/public/uploads/user/' || u.id :: TEXT || 
         '/avatar.jpg')) AS sender 
    FROM grouped_messages AS gm 
    INNER JOIN users_conversations c ON c.conversation_id = gm.conversation_id 
    INNER JOIN users u ON u.id = c.user_id 
    WHERE u.id != '#{user_id}' 
) 
SELECT json_object_agg(grouped_messages.conversation_id, 
         json_build_object('new_messages', grouped_messages.array_agg, 'sender', senders.sender)) 
FROM grouped_messages 
    INNER JOIN senders ON senders.conversation_id = grouped_messages.conversation_id 

Welche gibt, zum Beispiel:

{ 
    "62": { 
     "new_messages": [ 
      { 
       "message": "some", 
       "sent_at": "2016-05-30T20:19:53.786024" 
      }, 
      { 
       "message": null, 
       "sent_at": "2016-05-30T20:19:26.408814" 
      } 
     ], 
     "sender": { 
      "id": "e4ba308b-a5cf-47ad-b8d6-d774eb325411", 
      "user_name": null, 
      "avatar": "https://my-staging.s3.amazonaws.com/public/uploads/user/e4ba308b-a5cf-47ad-b8d6-d774eb325411/avatar.jpg" 
     } 
    } 
} 

Nun, was ich brauche, ist eine bedingte Anweisung in dieser Abfrage zu haben.

Wenn der (Benutzer-) Avatar nicht NULL ist, wenden Sie diese 'https://my-staging.s3.amazonaws.com/public/uploads/user/' || u.id::text || '/avatar.jpg' an, andernfalls fügen Sie einfach ': null' ein (damit jeder JSON-Parser es als ein Null-Objekt erkennt).

Nicht sicher, wie dieses If-Else hier in Select-Anweisung und auch, wie man diesen Teil über JSON-Parser sicherstellen.

+0

Haben Sie 'Fall versucht, wenn u nicht null‚URL string'' ist? – venkatKA

+0

@venkatKA, nicht Benutzer selbst, aber Feld Avatar –

+0

Nun, u.avatar ist nicht null – venkatKA

Antwort

0

für mich gearbeitet:

 (SELECT gm.conversation_id, json_build_object('id', u.id, 'user_name', u.user_name, 
     'avatar', (
     CASE WHEN u.avatar IS NULL THEN ':null' 
     ELSE ('https://my-staging.s3.amazonaws.com/public/uploads/user/' || u.id::text || '/avatar.jpg') 
     END)) 

Sie können in SELECT Block Fall-Anweisung zur Verfügung stellen, als ob es Wert waren (mit optionalen AS).

+0

Ihre tatsächliche Antwort ist unter einem Berg von Code begraben. Würde es Ihnen etwas ausmachen, den eigentlichen * Lösungsanteil in etwas Leicht zugängliches zu verwandeln? Ich bin sicher, dass andere da draußen gerne Ihre CASE-Anweisung sehen würden. – Makoto

+0

@ Makoto guter Punkt –

0

Dies ist eine gute Verwendung der CASE Ausdruck. In diesem Szenario möchten Sie entweder eine harte URL an ihren Avatar zurückgeben, wenn das Feld avatar nicht null ist, und andernfalls NULL.

Dies wird dadurch erreicht (die anderen Abschnitte der Abfrage zur besseren Lesbarkeit weggelassen):

json_build_object('id', u.id, 'user_name', u.user_name, 
        'avatar', 
        CASE WHEN u.avatar IS NULL 
        THEN NULL 
        ELSE 
        (
         'https://my-staging.s3.amazonaws.com/public/uploads/user/' 
         || u.id :: TEXT || 
         '/avatar.jpg') END) AS sender