簡體   English   中英

合並兩個復雜的查詢

[英]Merging two complex queries

我最終要做的是接受兩個SQL查詢,並在PHP中使用array_intersect()來過濾出結果:

$sql1 = 'SELECT z.*, u.username, u.user_colour, u.username_clean, u.user_avatar, u.user_avatar_type
    FROM ' . ZEBRA_TABLE . ' z, ' . USERS_TABLE . ' u
    WHERE (( z.user_id = ' . $user->data['user_id'] . '
        AND z.friend = 1
        AND u.user_id = z.zebra_id )
            OR ( z.zebra_id = ' . $user->data['user_id'] . '
                AND z.friend = 1
                AND u.user_id = z.user_id ))
    ORDER BY u.username_clean ASC';

$sql2 = 'SELECT z.*, u.username, u.user_colour, u.username_clean, u.user_avatar, u.user_avatar_type
    FROM ' . ZEBRA_TABLE . ' z, ' . USERS_TABLE . ' u
    WHERE (( z.user_id = ' . $user_id . '
        AND z.friend = 1
        AND u.user_id = z.zebra_id )
            OR ( z.zebra_id = ' . $user_id . '
                AND z.friend = 1
                AND u.user_id = z.user_id ))
    ORDER BY u.username_clean ASC';

兩個查詢的結構相同,唯一的區別是第二個查詢中的$user->data['user_id] (第一人稱)被$user_id (第二人稱)替換。 我想檢索兩個用戶共有的朋友。 任何人都可以將其合並為一個查詢,這樣我就不必使用兩個查詢並調用array_intersect()嗎?

好吧,您始終可以只對兩個子查詢:

$sql = 'SELECT a.* 
    FROM ('.$sql1.') AS a 
    JOIN ('.$sql2.') AS b ON a.user_id = b.user_id AND a.username = b.username';

您可能希望將u.user_id添加到兩個查詢u.user_id AS u_user_id的字段列表中,然后將第二個連接子句從a.username = b.usernamea.u_user_id = b.u_user_id ...

編輯:既然我真的更仔細地看,這兩個查詢幾乎是相同的...為什么不只是做這樣的事情(將where子句替換為此):

WHERE z.friend = 1 
   AND (
       ( z.user_id = '.$user_id.' AND u.user_id = z.zebra_id )
        OR
       (z.zebra_id = '.$user_id.' AND u.user_id = z.user_id )
   ) AND (
       ( z.user_id = '.$user->data['user_id'].' AND u.user_id = z.zebra_id )
        OR
       (z.zebra_id = '.$user->data['user_id'].' AND u.user_id = z.user_id )
   ) 

那應該給你兩個查詢相交的結果,並且更快,因為它可以更好地(希望)優化...

哦,它們在不同的塊位置,因為在z.user_id情況下z.user_id匹配$user_id ,但是z.zebra_id匹配$user->data['user_id'] ...因此,我沒有列出所有排列,而是像這樣布置...

通過將用戶表鏈接到zebra表兩次,可以選擇與兩個用戶都是朋友的用戶:

SELECT u.username, u.user_colour, u.username_clean, u.user_avatar, u.user_avatar_type 
FROM users u
JOIN zebra z1 ON z1.friend=1 AND (
                   (u.user_id = z1.user_id AND z1.zebra_id = @user_id1)
                   OR (u.user_id = z1.zebra_id AND z1.user_id = @user_id1)
                 )
JOIN zebra z2 ON z2.friend=1 AND (
                   (u.user_id = z2.user_id AND z2.zebra_id = @user_id2)
                   OR (u.user_id = z2.zebra_id AND z2.user_id = @user_id2)
                 )
ORDER BY u.username_clean ASC

JOIN從users表中獲取所有行,從zebra表中獲取所有行,並尋找滿足ON子句的組合。 在這種情況下,第一個@user_id1將查找與@user_id1成為好友的所有用戶,第二個@user_id1將其進一步限制為與@user_id2好友的用戶。

與使用子查詢相比,此查詢的執行速度要快得多。 如果zebra表在兩個方向上都存儲了友誼 ,則查詢將更快,從而使您能夠更多地利用表索引,並且可以刪除ON子句的OR部分:

SELECT u.username, u.user_colour, u.username_clean, u.user_avatar, u.user_avatar_type 
FROM users u
JOIN zebra z1 ON u.user_id = z1.user_id AND z1.friend=1 AND z1.zebra_id = @user_id1
JOIN zebra z2 ON u.user_id = z2.user_id AND z2.friend=1 AND z2.zebra_id = @user_id2
ORDER BY u.username_clean ASC

暫無
暫無

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

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