2017-06-12 498 views
0

但是,由於第二個查詢是在第一個查詢的循環中運行的,因此我無法對第一個查詢返回的結果重新排序。將兩個查詢合併爲一個並重新排序

第一個查詢總是返回結果,第二個查詢 - 有時候,但是當它需要時,我需要這些結果在最上面。默認情況下,結果按距離排序,從最近開始。

例如,這裏就是我現在得到:

  • 名1(PHONE1) - 0.1英里
  • 名稱2(PHONE2) - 0.4英里
  • NAME3(電話3) - 1.3英里< - 現在打開(查詢2匹配)
  • NAME4(PHONE4) - 2.4英里

我想看到什麼:

  • NAME3(電話3) - 1.3英里< - 現在打開(查詢2匹配)
  • 名1(PHONE1) - 0.1英里
  • 名稱2(PHONE2) - 0.4英里
  • NAME4(PHONE4) - 2.4 MI

這裏是我當前的查詢(簡體):

查詢1:

SELECT 
    t1.busName, 
    t1.busPhone 
FROM t1 
WHERE t1.lat BETWEEN $min_lat AND $max_lat 
    AND t1.lon BETWEEN $min_lon AND $max_lon 
ORDER BY (POW((t1.lon-$lon),2) + POW((t1.lat-$lat),2)) 
LIMIT 5 

查詢2:

SELECT COUNT(t3.rule_id) AS rcount 
FROM t3 
LEFT JOIN t2 ON (t3.rule_busID = t2.busID) 
WHERE t3.APIid = '".$APIid."' 

還有一個問題,我有是,有沒有辦法建立T1和T3之間的直接連接。唯一的辦法是讓T2

t1.APIid = t2.APIid 
t2.busID = t3.rule_busID 

表結構如下:

t1 
-------------------------------------- 
busName | busPhone | lon | lat | APIid 

t2 
-------------------------------------- 
busID | APIid 

t3 
-------------------------------------- 
rule_id | rule_busID 

目前,有兩個疑問,如果我返回10個結果我要運行11個查詢。理想情況下,我只想做一次。

對不起,這可能很明顯,但我卡住了。

+0

什麼是你的表結構?和他們的關係? – nacho

+0

@nacho我添加了表格結構。所有關係都在OP中。 – santa

+0

你應該更精確地解釋你想要訂購結果的方式。按距離ASC,numberOfRules DESC? –

回答

0

不知道是否真的有效,但你可以試試下面的辦法: 使用您的查詢1的子查詢中FROM -clause(添加內部排序和限制),請在SELECT -clause規則數。通過計數DESC對結果進行排序。

沒有測試過,但是應該是這個樣子:

SELECT 
    sub1.busName, 
    sub1.busPhone, 
    (SELECT COUNT(t3.rule_id) AS rcount FROM t3 LEFT JOIN t2 ON (t3.rule_busID = t2.busID) WHERE t2.APIid = t1.APIid) as rCount 
FROM 
    (
    SELECT 
     t1.busName, 
     t1.busPhone 
    FROM t1 
     WHERE t1.lat BETWEEN $min_lat AND $max_lat AND t1.lon BETWEEN $min_lon AND $max_lon 
     ORDER BY (POW((t1.lon-$lon),2) + POW((t1.lat-$lat),2)) ASC 
     LIMIT 5 
) as sub1 
ORDER BY rCount DESC 

但實際上,我不會給,我可能會與您現有的個人不太複雜的查詢和做法堅持之後在應用程序中重新排序。

+0

我目前的方法存在的問題是,我無法排序第二個查詢找到的匹配位於頂部的結果。我現在擁有的是由第一個查詢找到的匹配列表,按照鄰近性排序,如果其中一個匹配的是第二個匹配,我就以不同的方式進行設計。 – santa

+0

但你可以在你的應用程序中進行排序。不知道你在使用什麼語言/技術,但我想你可以從數組(或其他)讀取query1的結果,將查詢2的結果添加到相同的數據結構中,然後對其進行排序。 –

+0

你的意思是說,使用這兩個查詢來構建一個數組,然後對其進行排序?我已經考慮過這種可能性,但在我走上這條路之前,我想確保我給MySQL一個公平的動搖。它返回10個結果我目前必須運行10個查詢。理想情況下,我只想做一次。 – santa

0

,你可以使用這種方法:

select name, phone from (
select 0 order, name, phone 
from ... 
union all 
select 1, name, phone 
from ... 
)q 
order by q.order 
+0

感謝您的解決方案!我不確定我的鄰近參數在哪裏? – santa

0

您可以直接提供,如果您有關係數據庫的連接(包括你的每一個表之間的連接即直接或間接)。

讓你查詢簡化成一個象下面這樣:只有

SELECT t1.busName, t1.busPhone, COUNT(t3.rule_id) AS rcount FROM t1 INNER JOIN t2 on t2.APIid=t1.APIid LEFT JOIN t3 on t2.busID=t3.rule_busID WHERE t1.lat BETWEEN $min_lat AND $max_lat AND t1.lon BETWEEN $min_lon AND $max_lon AND t3.APIid = '".$APIid."' ORDER BY (POW((t1.lon-$lon),2) + POW((t1.lat-$lat),2)) LIMIT 5

使用LIMIT關鍵字時,你限制你的數據被顯示。

9

假設:T3不包含列APIid(詢問2問題 「t3.APIid」 應改爲 「t2.APIid」)。


因爲您的不包括在選擇子句中的列排序則需要執行次數計算既可以作爲衍生的表,或作爲相關子查詢。

派生表

在這裏,您執行COUNT()& GROUP BY子查詢中,並且加入結果向主查詢。

 
SELECT 
     t1.busName 
    , t1.busPhone 
    , COALESCE(r.rcount,0) rcount 
FROM t1 
LEFT JOIN ( SELECT t2.APIid , COUNT(t3.rule_id) AS rcount FROM t3 INNER JOIN t2 ON t3.rule_busID = t2.busID GROUP BY t2.APIid ) r ON t1.APIid = r.APIid 
WHERE t1.lat BETWEEN $min_lat AND $max_lat 
AND t1.lon BETWEEN $min_lon AND $max_lon 
ORDER BY (POW((t1.lon - $lon), 2) + POW((t1.lat - $lat), 2)) 
#LIMIT 5 
;

相關子查詢

的另一種方法是執行主查詢的選擇子句中的計數計算。這種子查詢風格可能會導致性能問題,但是如果從主查詢返回的行數不是很大,那麼這種方法可能表現得非常好。

 
SELECT 
     t1.busName 
    , t1.busPhone 
    , COALESCE(SELECT COUNT(t3.rule_id) FROM t3 INNER JOIN t2 ON t3.rule_busID = t2.busID WHERE t2.APIid = t1.APIid ),0) as rCount 
FROM t1 
WHERE t1.lat BETWEEN $min_lat AND $max_lat 
AND t1.lon BETWEEN $min_lon AND $max_lon 
ORDER BY (POW((t1.lon - $lon), 2) + POW((t1.lat - $lat), 2)) 
#LIMIT 5 
;

注意:在任何一種方法中,在t2上使用從t3開始的LEFT JOIN都沒有值。如果t3具有不鏈接到t2的規則,則將這些規則鏈接到t1也變得不可能。所以,只需在t3和t2之間使用INNER JOIN即可。

您可能需要使用COALESCE()或IFNULL()的返回零,如果沒有匹配的計數。您可以使用的功能,但我更喜歡ANSI標準COALESCE()

調整,以滿足您的需要限制。

0

選擇的名字,從電話( 選擇ROW_NUMBER()以上(按姓名順序,手機)的順序,姓名,電話 從... UNION ALL 從中選擇1,姓名,電話 ... )● 爲了通過q.order

使用ROW_NUMBER()OVER(ORDER BY姓名,電話),您可以分區和順序遞增和下降的產生和身份模擬,然後你可以加入工會或做你想做的。 (你可以做第二次選擇在第一個查詢的字段中選擇一個,(從d

我不明白你所期望的輸出選擇c其中D.A = C.A B)。

對不起,我的英語:)