2014-12-11 2 views
0

Мне нужно найти совпадение для пользователя.MySQL Query - многие для многих

Каждый пользователь имеет мультипликатор «Категория» (как бухгалтерский учет, банковское дело, финансы и т.д.) и множественным «привилегированной категории работы» (найти соответствующий профиль в тех указанной категории)

Что такое эффективная способ найти совпадение с помощью MySQL Query.

Структура MyProfile таблице:

User_Id | Work_Id 
1  | 5 
1  | 7 
1  | 8 
2  | 7 
2  | 9 

Структура PreferedWork стол

User_Id | Work_Id 
1  | 7 
1  | 9 
2  | 1 
2  | 8 

Я должен проверить против 100000 профилей и возвращать только 10 профилей.

EDIT: Мой Оригинальный запрос (без присоединиться):

$getMatchesQry = " 
     select ed.Entity_Id as entId,ed.Status as status,ed.First_Name,ed.Profile_Pic_Url,ed.Sex,ed.Current_Lat,ed.Current_Long,ed.community,ed.ethnicity,ed.Fb_Id,ent.Last_Active_Dt_Time, 
     YEAR(NOW()) - YEAR(ed.dob) - (RIGHT(NOW(), 5) < RIGHT(ed.DOB, 5)) as age, pr.Orientation 
     from entity_details ed,entity ent, preferences pr 
     where 
     (3959 * acos(cos(radians('" . $prefRow['Current_Lat'] . "')) * cos(radians(ed.Current_Lat)) * cos(radians(ed.Current_Long) - radians('" . $prefRow['Current_Long'] . "')) + sin(radians('" . $prefRow['Current_Lat'] . "')) * sin(radians(ed.Current_Lat)))) <= " . $prefRow['Preference_radius'] . "   
     and 
     (" . $pref_sex_str . ") 
     and 
     (" . $prefComWord . ") and (" . $prefRelWord . ") 
     and 
     pr.Orientation = '" . $prefRow['Orientation'] . "' 
     and    
     '" . $prefRow['min_height'] . "' <= ed.height 
     and 
     ed.height <= '" . $prefRow['max_height'] . "'         
     and    
     ed.Entity_Id = ent.Entity_Id and 
     ed.Entity_Id = pr.Entity_Id and    
     ent.status = 1 and ed.Fb_Id != '" . $prefRow['Fb_Id'] . "' and 
     ed.Entity_Id NOT IN (select Entity2_Id from likes where Entity1_Id = '" . $entityId . "' and (Like_Flag = '1' OR Like_Flag = '2' OR Like_Flag = '3' OR Like_Flag = '4'))    
     having 
     age BETWEEN '" . $prefRow['Preference_lower_age'] . "' AND '" . $prefRow['Preference_upper_age'] . "' LIMIT 10"; 

, когда я добавить присоединиться,

$getMatchesQry = " 
     select ed.Entity_Id as entId,ed.Status as status,ed.First_Name,ed.Profile_Pic_Url,ed.Sex,ed.Current_Lat,ed.Current_Long,ed.community,ed.ethnicity,ed.Fb_Id,ent.Last_Active_Dt_Time, 
     YEAR(NOW()) - YEAR(ed.dob) - (RIGHT(NOW(), 5) < RIGHT(ed.DOB, 5)) as age, pr.Orientation 
     from entity_details ed,entity ent, preferences pr, **pref_occupation ul1, users_occ ul2** 
     where 
     (3959 * acos(cos(radians('" . $prefRow['Current_Lat'] . "')) * cos(radians(ed.Current_Lat)) * cos(radians(ed.Current_Long) - radians('" . $prefRow['Current_Long'] . "')) + sin(radians('" . $prefRow['Current_Lat'] . "')) * sin(radians(ed.Current_Lat)))) <= " . $prefRow['Preference_radius'] . "   
     and 
     (" . $pref_sex_str . ") 
     and 
     (" . $prefComWord . ") and (" . $prefRelWord . ") 
     and 
     pr.Orientation = '" . $prefRow['Orientation'] . "' 
     and    
     '" . $prefRow['min_height'] . "' <= ed.height 
     and 
     ed.height <= '" . $prefRow['max_height'] . "'      
     and 
     **(ul1.Occupation_Id = ul2.Work_Id AND ul1.Entity_Id != ul2.Entity_Id AND ul2.Entity_Id = ed.Entity_Id)** 
     and    
     ed.Entity_Id = ent.Entity_Id and 
     ed.Entity_Id = pr.Entity_Id and    
     ent.status = 1 and ed.Fb_Id != '" . $prefRow['Fb_Id'] . "' and 
     ed.Entity_Id NOT IN (select Entity2_Id from likes where Entity1_Id = '" . $entityId . "' and (Like_Flag = '1' OR Like_Flag = '2' OR Like_Flag = '3' OR Like_Flag = '4'))    
     having 
     age BETWEEN '" . $prefRow['Preference_lower_age'] . "' AND '" . $prefRow['Preference_upper_age'] . "' LIMIT 10"; 

Когда я добавляю JOIN (упоминается в жирным), я получить только частичный результат и НЕ комбинировать результат из исходного запроса.

Я думаю, я перепутал И или другой важный оператор цепочки где-то.

Редактировать 2:: Получение правильных значений сейчас. В любом случае, чтобы его оптимизировать?

$getMatchesQry = "select DISTINCT ed.Entity_Id as entId,ed.Status as status,ed.First_Name,ed.Profile_Pic_Url,ed.Sex,ed.Current_Lat,ed.Current_Long,ed.community,ed.ethnicity,ed.Fb_Id,ent.Last_Active_Dt_Time, 
    YEAR(NOW()) - YEAR(ed.dob) - (RIGHT(NOW(), 5) < RIGHT(ed.DOB, 5)) as age, pr.Orientation 
    from entity_details ed, entity ent, preferences pr, pref_occupation ul1, users_occ ul2, 
    where 
    (3959 * acos(cos(radians('" . $prefRow['Current_Lat'] . "')) * cos(radians(ed.Current_Lat)) * cos(radians(ed.Current_Long) - radians('" . $prefRow['Current_Long'] . "')) + sin(radians('" . $prefRow['Current_Lat'] . "')) * sin(radians(ed.Current_Lat)))) <= " . $prefRow['Preference_radius'] . "   
    and 
    (" . $pref_sex_str . ") 
    and 
    (" . $prefComWord . ") and (" . $prefRelWord . ") 
    and 
    pr.Orientation = '" . $prefRow['Orientation'] . "' 
    and    
    '" . $prefRow['min_height'] . "' <= ed.height 
    and 
    ed.height <= '" . $prefRow['max_height'] . "'      
    and 
    ((ul1.Occupation_Id = ul2.Work_Id AND ul1.Entity_Id != ul2.Entity_Id AND ul2.Entity_Id = ed.Entity_Id))   
    and    
    ed.Entity_Id = ent.Entity_Id and 
    ed.Entity_Id = pr.Entity_Id and    
    ent.status = 1 and ed.Fb_Id != '" . $prefRow['Fb_Id'] . "' and 
    ed.Entity_Id NOT IN (select Entity2_Id from likes where Entity1_Id = '" . $entityId . "' and (Like_Flag = '1' OR Like_Flag = '2' OR Like_Flag = '3' OR Like_Flag = '4'))   
    having 
    age BETWEEN '" . $prefRow['Preference_lower_age'] . "' AND '" . $prefRow['Preference_upper_age'] . "' LIMIT 10"; 
+0

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

+0

Что вы сделали до сих пор? Какие вопросы вы пробовали? Каковы были эти результаты? По существу, покажите часть выполненной вами работы, и мы будем работать над улучшением, где вы находитесь, но сначала вам нужно начать. –

+0

Ваш вопрос недостаточен. «Каков эффективный способ найти совпадение с помощью MySQL Query». Что именно нужно искать? –

ответ

0

Не зная больше деталей, вы должны вероятно, иметь это вместо того, что у вас есть сейчас:

MyProfile:

user_id | work_id | preference 
1  | 1  | 0 
1  | 2  | 0 
1  | 3  | 1 
2  | 1  | 1 
2  | 2  | 0 

Итак, мы видим, что user_id 1 имеет work_id 1, 2, и 3, но предпочитает 3. user_id 2 имеет work_id 1 и 2 и предпочитает 1

0

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

SELECT p.work_id, p.user_id 
FROM MyProfile as p 
INNER JOIN PreferedWork as pw on p.user_id = pw.user_id 
WHERE p.work_id = pw.work_id 
+0

Почему предложение where? Вы можете присоединить эти условия к соединению: 'INNER JOIN PreferedWork as pw на p.user_id = pw.user_id и p.work_id = pw.work_id' –

+0

Что делать, если поле, на котором мы устанавливаем условие, не имеет определенного индекса? , поэтому вы присоединяетесь к полям, которые индексируются, но если поле, на котором вы указываете условие, не индексируется, лучше сохраните его в ГДЕ. , но я не уверен, может быть, это не имеет большого значения. –

0

Если вы хотите пересечение между этими двумя таблицами просто использовать INNER JOIN

SELECT MyProfile.User_Id, MyProfile.Work_Id 
FROM MyProfile INNER JOIN PreferedWork 
USING (User_Id, Work_Id) 

http://www.bitbybit.dk/carsten/blog/?p=71

1

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

SQL Fiddle

MySQL 5.5.32 Схема установки:

CREATE TABLE MyProfile 
    (`User_Id` int, `Work_Id` int) 
; 

INSERT INTO MyProfile 
    (`User_Id`, `Work_Id`) 
VALUES 
    (1, 5), 
    (1, 7), 
    (1, 8), 
    (2, 7), 
    (2, 9), 
    (3, 10) 
; 

CREATE TABLE PreferedWork 
    (`User_Id` int, `Work_Id` int) 
; 

INSERT INTO PreferedWork 
    (`User_Id`, `Work_Id`) 
VALUES 
    (1, 7), 
    (1, 9), 
    (2, 1), 
    (2, 8) 
; 

Запрос 1:

SELECT mp.User_ID, 
     GROUP_CONCAT(DISTINCT mp.Work_Id ORDER BY mp.Work_Id) AS `work category`, 
     GROUP_CONCAT(DISTINCT ifnull(pw.Work_Id,'') ORDER BY pw.Work_Id) AS `preferred work category` 
FROM MyProfile mp 
LEFT OUTER JOIN PreferedWork pw ON mp.User_ID = pw.User_ID 
GROUP BY mp.User_ID 

Results:

| USER_ID | WORK CATEGORY | PREFERRED WORK CATEGORY | 
|---------|---------------|-------------------------| 
|  1 |   5,7,8 |      7,9 | 
|  2 |   7,9 |      1,8 | 
|  3 |   10 |       | 

или может быть вы ИЩЕМ что-то вроде ЭТО :

SELECT mp.User_ID, 
FROM MyProfile mp 
LEFT OUTER JOIN PreferedWork pw ON mp.User_ID = pw.User_ID 
WHERE (mp.Work_Id = '8' or pw.Work_Id = '8') 
LIMIT 10 
Смежные вопросы