2017-02-07 2 views
0
SELECT n.type, n.type_id, n.data, 
(CASE WHEN (n.type='users') THEN users.u_name ELSE NULL END) AS user_name, 
(CASE WHEN (n.type='blogs') THEN blogs.b_name ELSE NULL END) AS blog_name 
FROM notifications AS n 
LEFT JOIN users ON (CASE 
        WHEN (n.type='users') AND n.type_id=users.id THEN 1 
        ELSE 0 
        END = 1) 
LEFT JOIN blogs ON (CASE 
        WHEN (n.type='blogs') AND n.type_id=blogs.id THEN 1 
        ELSE 0 
        END = 1) 
WHERE n.receiver_id = 1 
ORDER BY n.id DESC LIMIT 20 

Es funktioniert, aber verwendet: Mit temporären; Verwenden von filesort, Verwenden von Join-Buffer (flach, BNL-Join), Verwenden von Join-Buffer (inkrementell, BNL-Join). Das sieht nicht gut aus.MySQL: Verbesserte Abfrage mit bedingten Joins

Weiter mehr, tritt in dem linken Innen sein sollte, aber mit innerem es kein Ergebnis wird zeigen ... (und die gleichen temporarys, filesorts, Puffer, etc.)

I tryied eine andere Syntax (wahrscheinlich falsch) mit gleichen Ergebnissen:

(CASE WHEN (n.type='blogs') THEN n.type_id=blogs.id ELSE NULL END) 

ich zwei Abfragen tun könnte, aber ich versuche, es in einem zu tun :)

Antwort

3
SELECT n.type, n.type_id, n.data, 
     users.u_name as user_name, 
     blogs.b_name AS blog_name 
FROM notifications AS n 
LEFT JOIN users ON n.type='users' AND n.type_id=users.id 
LEFT JOIN blogs ON n.type='blogs' AND n.type_id=blogs.id 
WHERE n.receiver_id = 1 
ORDER BY n.id DESC 
LIMIT 20 

Sie die Fälle nicht brauchen. Und left join ist der richtige Ansatz, da eine Benachrichtigung entweder von Benutzern oder Blogs und nicht von beiden erfolgt.

+0

Es gibt mir keine Ergebnisse und "Extra: Impossible WHERE" und alle anderen erklären Felder NULL. – Vixxs

+0

Das ist wirklich seltsam. Fügen Sie Beispieldaten und erwartete Ausgaben zu Ihrer Frage hinzu. –

+0

Der n.Typ kann sich vom Benutzer oder Blog unterscheiden, kann von Aktionen sein, die keinen Benutzer- oder Blognamen erfordern – Vixxs

0

Versuchen unter Abfrage:

Diese nutzt innere Verknüpfung und geradlinig Bedingungen beizutreten. Bitte beachten Sie, dass es in der SELECT-Klausel eine zusätzliche Spalte n.id gibt.

SELECT n.id, n.type, n.type_id, n.data, u.u_name AS user_name, NULL AS blog_name 
FROM notification n INNER JOIN users u ON n.receiver_id = 1 AND n.type = 'users' AND n.type_id = u.id 
UNION ALL 
SELECT n.id, n.type, n.type_id, n.data, NULL AS user_name, b.b_name AS blog_name 
FROM notification n INNER JOIN blogs b ON n.receiver_id = 1 AND n.type = 'blogs' AND n.type_id = b.id 
ORDER BY 1 DESC LIMIT 20; 
0

Try this:

SELECT n.type, n.type_id, n.data, 
    (select u.u_name from users as u where u.id = n.type_id and n.type = 'users'), 
    (select b.b_name from blogs as b where b.id = n.type_id and n.type = 'blogs') 
FROM notifications AS n 
WHERE n.receiver_id = 1 
ORDER BY n.id DESC LIMIT 20