Для исходного решения SQL, я создал приблизительную репликацию вашей проблемы на установке ideone here
данных:
create table content_a(id int, user_id int, content varchar(20));
create table content_b(id int, user_id int, content varchar(20));
create table content_c(id int, user_id int, content varchar(20));
create table voting(user_id int, content_id int, content_type_id int, vote int);
create table users(id int, name varchar(20));
insert into content_a values(1,1,'aaaa');
insert into content_a values(2,1,'bbbb');
insert into content_a values(3,1,'cccc');
insert into content_b values(1,2,'dddd');
insert into content_b values(2,2,'eeee');
insert into content_b values(3,2,'ffff');
insert into content_c values(1,1,'gggg');
insert into content_c values(2,2,'hhhh');
insert into content_c values(3,3,'iiii');
insert into users values(1, 'first');
insert into users values(2, 'second');
insert into users values(3, 'third');
insert into users values(4, 'voteonly');
-- user 1 net votes (2)
insert into voting values (1, 1, 1, 1);
insert into voting values (2, 3, 1, -1);
insert into voting values (3, 1, 1, 1);
insert into voting values (4, 2, 1, 1);
-- user 2 net votes (3)
insert into voting values (1, 2, 2, 1);
insert into voting values (1, 1, 2, 1);
insert into voting values (2, 3, 2, -1);
insert into voting values (4, 2, 2, 1);
insert into voting values (4, 2, 3, 1);
-- user 3 net votes (-1)
insert into voting values (2, 3, 3, -1);
Я предположил, что у content_a есть тип 1, content_b имеет тип 2, а content_c - тип 3. Используя raw SQL, кажется, что t с очевидными подходами. Во-первых, объединить все содержимое вместе, затем присоединить его к пользователям и таблицам для голосования. Я проверил этот подход ниже.
select users.*, sum(voting.vote)
from users,
voting, (
SELECT id, 1 AS content_type_id, user_id
FROM content_a
UNION
SELECT id, 2 AS content_type_id, user_id
FROM content_b
UNION
SELECT id, 3 AS content_type_id, user_id
FROM content_c) contents
where contents.user_id = users.id
and voting.content_id = contents.id
and voting.content_type_id = contents.content_type_id
group by users.id
order by sum(voting.vote) desc;
Альтернативой, по-видимому, является внешнее соединение таблиц контента с таблицами для голосования без шага объединения. Это может быть более результативным, но я не смог его протестировать, потому что визуальная студия продолжает переписывать мой sql для меня ... Я бы ожидал, что SQL будет выглядеть примерно так (но я его не тестировал):
select users.*, sum(voting.vote)
from users, voting, content_a, content_b, content_c
where users.id = content_a.user_id (+)
and users.id = content_b.user_id (+)
and users.id = content_c.user_id (+)
and ((content_a.id = voting.content_id and voting.content_type_id = 1) OR
(content_b.id = voting.content_id and voting.content_type_id = 2) OR
(content_c.id = voting.content_id and voting.content_type_id = 3))
group by users.id
order by sum(voting.vote) desc;
Учитывая, что в вашей таблице «голосование» есть голос, как вы можете указать, к какой таблице контента он относится? Что, если 'content_id' существует в нескольких таблицах? – eggyal
Прошу прощения, я забыл включить столбец. – mburke13