簡體   English   中英

MySQL查詢-多對多

[英]MySQL Query - Many to Many

我需要為用戶找到匹配項。

每個用戶都有多個 “工作類別”(例如會計,銀行,財務等)和多個 “首選工作類別”(以在那些指定的類別中找到匹配的配置文件)

使用MySQL Query查找匹配項的有效方法是什么?

MyProfile表的結構:

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

首選工作表的結構

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

我必須對照100,000個配置文件進行檢查,並僅返回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
        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(以粗體顯示 )時,我只得到部分結果,而不是合並來自原始查詢的結果。

我想,我在某個地方弄亂了AND或其他重要的鏈接運算符。

編輯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"; 

您的問題似乎還不完整,但是據我了解,您可以嘗試執行以下操作:

SQL小提琴

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

結果

| 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

在不了解更多細節的情況下,您應該擁有的是這個,而不是現在擁有的:

我的簡歷:

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

在用戶ID上加入拖車表,以獲取工作類別和首選工作之間的所有組合。 然后過濾工作類別等於首選工作的行。

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

如果要兩個表之間的交集,請使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM