2009-07-25 34 views
8

Şu anda biraz zor bir MySQL Seçimi Bildirimi oluşturmaya çalışıyorum.MySQL Seçim Bildirimi Çoklu Sütunlar için DISTINCT

Böyle bir tablo var: İşte başarmaya çalışıyorum budur stringID (resimde TARAFINDAN/GROUP SEÇ edebilmek

data_table 

uniqueID  stringID   subject 
    1    144   "My Subject" 
    2    144   "My Subject - New" 
    3    144   "My Subject - Newest" 
    4    211   "Some other column" 

Bascially, ne yapmam istiyorum ki stringID iş parçacığıdır ve çoğaltılmamış. Ayrıca, en son stringID satırını SEÇİM (yukarıdaki örnekte uniqueID 3 olan). Ben veritabanını sorgulamak için olsaydı

nedenle, dönecekti (en üstteki en son UNIQUEID ile) şunlardır:

uniqueID stringID subject 
4   211  "Some other column" 
3   144  "My Subject - Newest" //Notice this is the most recent and distinct stringID row, with the proper subject column. 

Bu mantıklı umuyoruz. Yardımın için teşekkürler.

+2

% 100 belli uniqueID hep tablosundaki en yüksek ID olur musunuz? Değilse, en son için bir zaman damgası eklemenizi öneririm. – lexu

+0

Aslında bir zaman damgası sütunum var (yukarıdaki örneğimde yer almıyor). O zaman zaman damgası sütunumu kullanmaya nasıl başlarım? MAX bir zaman damgası sütunuyla çalışır mı? Teşekkürler. –

cevap

9

Aşağıdakileri deneyin. Bu en verimli sorgusu olmayabilir, ama işe yarayacak:

SELECT uniqueID, stringID, subject 
FROM data_table 
WHERE uniqueID IN 
(
    SELECT MAX(uniqueID) 
    FROM data_table 
    GROUP BY stringID 
) 
ORDER BY uniqueID DESC 
+1

Bu sorguya en fazla yardımcı oldu. Ayrıca, zaman damgası kullanarak yukarıdaki 'lexi' önerisi ile 'uniqueID' yerini aldım. Yardımlarınız için çok teşekkürler. –

+2

Bunu benzer bir soruna çözüm buldum. Bu iyi bir çözümdür, ancak alt seçeğin yerine geçici bir tablo kullanarak yapılması gereken bir performans artışı vardır. Alt seçime göre bir temp tablosu oluşturun, sonra ana sorgudaki alt seçimler gittiğinde, temp tablosunu kendi yerine koyun. 80000+ satırlık veri kümemde, alt seçim yönteminin çalıştırılması birkaç dakika sürdü, bunun yerine geçici bir tablo kullanıldığında yaklaşık 15 saniye sürdü. – GordonM

2

Düzenleme: yorumunda OP tarafından sağlanan yeni bilgilere dayanarak, bu tercih olacaktır uniqueID güvenerek için:

select t.uniqueID 
     , t.stringID 
     , t.subject 
     , t.your_timestamp_col 
from data_table t 
     left outer join data_table t2 
     on t.stringID = t2.stringID 
    and 
     t2.your_timestamp_col > t.your_timestamp_col 
where t2.uniqueID is null 
lexu bir açıklama bahseder gibi, en yüksek uniqueID değeri her zaman en yeni konu ile karşılık geldiğini eminseniz, varsa

, bunu yapabilirdi:

select t.uniqueID 
     , t.stringID 
     , t.subject 
from data_table t 
     left outer join data_table t2 
     on t.stringID = t2.stringID 
    and 
     t2.uniqueID > t.uniqueID 
where t2.uniqueID is null 

Temel olarak şu anlama gelir: değeri daha yüksek olan data_table numaralı kayıtlara geri dön.

+1

Aslında daha kötü performans gösterecek. Alt sorgu, süpermarket sütunlarından hiçbirini kullanmaz ve bu nedenle yalnızca bir kez hesaplanır. Bir 'max', her bir kimliği birer birer karşılaştırmaya çalışmaktan çok daha hızlıdır. Üstelik, birleşme daha sonra 'nerede' maddesini uygulamak zorunda kalacak. Ancak alt sorgu, kimliklerin her birine bir arama görevi gören bir karma tablo oluşturacaktır. Ergo, sadece bir karşılaştırma ve tüm karşılaştırmalar yapıldıktan sonra sütunu kontrol etmek zorunda değiliz. – Eric

+0

@Eric - Argümanınız mantıklı fakat [ne yazık ki MySQL şu anda bu şekilde çalışmıyor] (http: // stackoverflow.com/questions/3417074/why-would-an-in-condition-in-in-in-sql/3417190 # 3417190) –

3
SELECT DISTINCT(a), 
    (SELECT DISTINCT(b)) AS b, 
    (SELECT DISTINCT(c)) AS c 

FROM tblMyTBL 

WHERE... 
Order By... 
Etc. 
0

Benzer bir durum vardı ve farklı bir sorgu buldu. Bu deneyin:

SELECT MAX(uniqueID), stringID, subject 
FROM data_table 
GROUP BY stringID 
+0

Sorunu çözen bir kod sağladığında, en azından kısa bir açıklama yapmak en iyisidir Nasıl çalıştığı, bu yüzden okumaya devam etmenin, zihinsel olarak farklılıkları anlamak için çizgiyi çizgisel olarak ayrıştırması gerekmeyecek. – Fluffeh

-1
private void LoadAllFamilyMembers(string relationShip) 
     { 
      lbFamilyMembers.SelectedIndexChanged -= new EventHandler(lbFamilyMembers_SelectedIndexChanged); 
      SqlCommand cmd = new SqlCommand("select familymemberid,name from FamilyMembers where relationship = @relationship", con); 
      cmd.Parameters.AddWithValue("@relationship", relationShip); 
      DataTable dt = new DataTable(); 
      SqlDataAdapter adapter = new SqlDataAdapter(cmd); 
      adapter.Fill(dt); 
      lbFamilyMembers.DataSource = dt; 
      lbFamilyMembers.DisplayMember = "name"; 
      lbFamilyMembers.ValueMember = "familymemberid"; 
      lbFamilyMembers.SelectedIndex = -1; 
      lbFamilyMembers.SelectedIndexChanged += new EventHandler(lbFamilyMembers_SelectedIndexChanged); 
     }