2016-01-14 45 views
2

如果我有一個具有多個停靠點的巴士表,並且每個停靠記錄都有到達時間,那麼如何檢索並按最早停止時間排序巴士?按另一個表中的屬性排序SQL結果

_______ ________ 
| Buses | | Stops | 
|-------| |--------| 
| id | | id  | 
| name | | bus_id | 
------- | time | 
      -------- 

我可以用下面的查詢做到這一點:

SELECT DISTINCT sub.id, sub.name 
FROM 
(SELECT buses.*, stops.time 
FROM buses 
INNER JOIN stops ON stops.bus_id = buses.id 
ORDER BY stops.time) AS sub; 

...但是這具有做2個查詢,不必從公交車在指定的所有字段的缺點SELECT DISTINCT子句。如果巴士表發生變化,這會變得特別煩人。

我想要做的是這樣的:

SELECT DISTINCT buses.* 
FROM buses 
INNER JOIN stops ON stops.bus_id = buses.id 
ORDER BY stops.time; 

...但是爲了得到DISTINCT buses.*,我必須包括stops.time有作爲,這讓我重複公交車不同的停止時間。

什麼是更好的方式來做這個查詢?

回答

2

一兩件事你可以做的是把內部查詢到ORDER BY。這將保持外部查詢「乾淨」,因爲它只會從總線中選擇。這樣你就不需要返回任何額外的字段。

SELECT buses.* 
FROM buses 
ORDER BY (
    SELECT MIN(stops.time) FROM stops WHERE stops.bus_id = buses.id 
) 
+1

這是最簡單的答案,從維護的角度來看可能是最好的。謝謝! – Matt

1

我沒有PostgreSQL的,但我認爲在這個問題上的問題一般是任何SQL 問題是區分就會從未給出正確的解決方案,因爲從表停止所有的停止時間將上市。

爲了讓我們可以使用GROUP BY和MIN,而不是正確的解決方案..

SELECT B.id, B.name, MIN(S.time) MinTime 
FROM 
Buses B INNER JOIN Stops S 
ON B.id = S.bus_id 
GROUP BY B.id, B.name 
ORDER BY MIN(S.time) 
2

指定字段選擇是最好的做法,所以我不知道爲什麼被列爲負面。

我會做

Select buses.* From buses inner join 
(Select stops.bus_id, min(stops.time) as mintime 
    From Stops 
    Group By stops.bus_id) st on buses.id = st.bus_id 

Select buses.*, min(stops.time) as stoptime 
    From buses inner join stops on 
    buses.ID = stops.bus_ID group by buses.id, buses.name 
1

我想打開「選擇不同」的方式過度使用,往往知之甚少。這是一個非常有限的工具,如果你已經使用它,查詢仍然沒有做你所需要的,接下來的2個工具是1. GROUP BY2。ROW_NUMBER()

在這個例子中,那裏有沒有必要多列,所以一個GROUP BY會很容易產生想要的結果:

SELECT 
     B.id 
    , B.name 
    , MIN(S.time) MinTime 
FROM Buses B 
     INNER JOIN Stops S ON B.id = S.bus_id 
GROUP BY 
     B.id 
    , B.name 
ORDER BY 
     MinTime 
  • 注:這是完全一樣的答案由蘇西洛除了我已經使用 列別名MinTIme在ORDER BY子句

的有效替代這一點,當你需要從交流中的所有列,這是有用ERTAIN排,如表示「最早的停止時間」是使用ROW_NUMBER()

SELECT 
     id 
    , name 
    , time 
FROM (
     SELECT 
      B.id 
      , B.name 
      , S.time 
      , ROW_NUMBER() OVER (PARTITION BY B.id ORDER BY S.time ASC) AS rowno 
     FROM Buses B 
      INNER JOIN Stops S ON B.id = S.bus_id 
    ) dt 
WHERE rowno = 1 
ORDER BY 
     Time 
; 
  • 尖端一行:如果你看到/在查詢中聽到「最早的」或「最新」要求 然後這種技術經常適用。
相關問題