2013-09-01 24 views
10

Mam tabeli o nazwie notifications:Łączenie różnych tabel na podstawie wartości kolumny

CREATE TABLE `notifications` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `user_id` int(11) DEFAULT NULL, 
    `type` varchar(20) NOT NULL DEFAULT '', 
    `parent_id` int(11) DEFAULT NULL, 
    `parent_type` varchar(15) DEFAULT NULL, 
    `type_id` int(11) DEFAULT NULL, 
    `etc` NULL 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8; 

Każdy notification związana jest z innej tabeli, wartość parent_type pole określa nazwę tabeli, który chcę * join tabela z. Wszystkie tabele docelowe mają kilka podobnych kolumny:

CREATE TABLE `tablename` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `is_visible` tinyint(1) NOT NULL,  
    `etc` NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; 

Obecnie używam tej kwerendy wyboru notifcations że ich partner wiersz w tabeli docelowej istnieje i ich is_visible pole jest 1:

SELECT n.id, 
FROM notifications n 
LEFT JOIN books b ON n.parent_id = b.id AND n.parent_type = 'book' AND b.is_visible = 1 
LEFT JOIN interviews i ON n.parent_id = i.id AND n.parent_type = 'interview' AND i.is_visible = 1 
LEFT JOIN other tables... 
WHERE n.user_id = 1 
GROUP BY n.id 

Ale ponieważ to jest LEFT JOIN zwraca powiadomienie, jeśli pasuje do dowolnej tabeli lub nie, jak mogę przepisać to tak, aby nie zwracało powiadomień, które nie pasują do żadnego wiersza w tabeli docelowej? Próbowałem też bezskutecznie oświadczenia CASE.

+0

czy próbowałeś już bez 'LEFT' i używając' JOIN' Only? –

+0

Głosowałem za udzieleniem strasznie zawiłego pytania (przypuszczam, że inne głosy są również za niskie) i przykucie bardzo przydatnego tytułu. Zmień nazwę tytułu, a usuń głosowanie w dół. Jest zbyt wiele grudek biegających wokół oznaczania A jako duplikatu B i jest to rodzaj nonsensu, który tylko pogarsza sytuację. – John

+0

@John "strasznie zawiłe pytanie"? Pytanie wydaje mi się w porządku. Generalnie nie dbam o "downvotes", ale zależy mi na zadawaniu użytecznych pytań i konstruktywnych sugestii. Prawdopodobnie chciałeś powiedzieć, że tytuł jest zbyt ogólny, tak jak twoje własne pytanie? ["MariaDB JOIN tabele z różnych baz danych na podstawie wartości kolumny"?] (Https://stackoverflow.com/questions/48062280/mariadb-join-tables-from-different-databases-based-on-column-value) :) – undefined

Odpowiedz

16

Nie jestem w 100% pewien, czy składnia jest właściwa i nie mam teraz szansy na jej przetestowanie, ale pomysł powinien być jasny.

SELECT DISTINCT n.id 
FROM notifications n 
JOIN (
    (SELECT b.id, 'book' AS type FROM books b WHERE b.is_visible = 1) 
    UNION 
    (SELECT i.id, 'interview' AS type FROM interviews i WHERE i.is_visible = 1) 
) ids ON n.parent_id = ids.id AND n.parent_type = ids.type 
WHERE n.user_id = 1 
+2

Użycie 'JOIN' i' UNION' robi lewę. Dziękuję Ci bardzo. – undefined

+0

Dzięki! To mi pomogło! –

Powiązane problemy