[英]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.username
為a.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.