2016-10-25 3 views
1

Я пытаюсь разработать приложение для голосования, которое требует расширенных запросов к базе данных. Приложение позволяет пользователям голосовать за других пользователей, используя их номера телефонов. Поэтому убедитесь, что пользователь с множеством телефонных номеров получает все свои голоса, вместе взятые, у меня есть таблица, связывающая их номера телефонов, используя их национальный идентификационный номер. В конце концов, у меня есть две таблицы, как так:mysql procedure/function

user_national_id стол

user_phone_no | national_id
-------------------- | -----------------
Phone1                             | nat_id1
phone2                             | nat_id1

голосов таблица

user_phone_no | отправитель
-------------------- | -----------------
Phone1                             | sender1
Phone1                             | sender2
phone2                             | sender3
phone2                             | sender2

Теперь мне нужен метод, который собирает уникальные национальные идентификационные номера в таблице user_national_id, связывает национальный идентификатор с телефонными номерами пользователя в таблице user_national_id, а затем подсчитывает количество обратных номеров телефона в таблице голосов.

Заранее благодарен.

(переехал из комментария ...)

DELIMITER $$ 
    CREATE PROCEDURE GetUniqueNominees() 
    BEGIN DECLARE done BOOLEAN; 
    DECLARE nomIds VARCHAR(255); 
    DECLARE curIds CURSOR FOR 
     SELECT DISTINCT national_id 
      FROM user_national_id; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE; 
    OPEN curIds; 
    LOOPROWS: LOOP 
     IF done=TRUE THEN 
     CLOSE curIds; 
     LEAVE LOOPROWS; 
     END IF; 
     FETCH curIds 
     INTO nomIds; 
     SELECT DISTINCT nomIds; 
     select count(user_phone_no) 
     from votes 
     inner join user_national_id 
      ON (votes.user_phone_no = user_national_id.user_phone_no) 
     where national_id=nomIds; 
    END LOOP; 
    END$$ 
DELIMITER ; 
+0

@mmushtaq Я плохо разбираюсь в Sql, но я пробовал объединения, которые явно не работали – user3783697

+0

вот что я до сих пор нашел – user3783697

+0

проблема в том, что он возвращает каждый результат дважды – user3783697

ответ

0

SQL обычно не нужны петли и курсоры, и часто (хотя и не всегда), когда вы думаете, что вам нужно их, вы нет.

SQL не предназначен для процедур, он должен быть декларативным: вы сообщаете серверу, что хотите, а не как сервер должен его получить. Затем сервер (оптимизатор запросов) может реализовать любую логику, которую он может придумать для вычисления результата, если он логически согласуется с тем, что вы просите.

В этом случае, вот способ выразить то, что вы, кажется, задаются вопросом:

SELECT u1.national_id, COUNT(DISTINCT v.sender) AS votes_counted 
    FROM user_national_id u1 
    JOIN user_national_id u2 ON u2.national_id = u1.national_id 
    JOIN votes v ON v.user_phone_no = u2.user_phone_no 
WHERE u1.user_phone_no = ? 
GROUP BY u1.national_id 

Здесь мы используем две «виртуальные копии» таблицы user_national_id, псевдонимами, как u1 и u2. Мы находим введенный номер телефона в u1, который дает идентификатор пользователя. Из этого мы находим один и тот же национальный идентификатор в u2, который дает нам все номера телефонов, и оттуда мы подсчитываем голоса (путем подсчета отправителей) для всех номеров телефонов, соответствующих телефонным номерам, найденным в u2 , основанный на критериях от u1. Мы рассчитываем отправителя DISTINCT, который отбрасывает повторяющиеся голоса, так как существующая структура, по-видимому, позволяет мне голосовать за разные телефонные номера пользователя, но я предполагаю, что эти shold будут проигнорированы. Если нет, удалите DISTINCT.

DISTINCT - еще одна особенность, обычно злоупотребляемая неофитами SQL, что часто является признаком того, что «мой запрос неверен, но по какой-то причине это, кажется, исправить». Не используйте его небрежно, небрежно или регулярно, и не используйте его без специального обоснования. Здесь оправдание кажется очевидным.

+0

** УДИВИТЕЛЬНЫЙ СТУФ! РАБОТАЕТ КАК ШАРМ ** – user3783697

+0

Отличная новость, @ user3783697. Не забудьте отметить как принято. –

0

гул, если я хорошо понимал это и должно быть:

select count(sender) from votes inner join user_national on (votes.user_phone_no = user_national.user_phone_no) where national_id = {yourValueHere} 
+0

Это действительно работает, когда вы уже знаете национальный идентификационный номер. – user3783697

+0

Моя проблема: я получаю отдельный национальный идентификатор через результат и рассчитываю, как вы это делали. Так что национальный идентификатор будет поставляться динамически. – user3783697