Birçok insan bunu yapmak için alt sorgular veya başka satıcıya özgü özellikleri kullanın, ancak genellikle bu şekilde sorgu alt sorgular olmadan aşağıdaki şekilde yapmak. Düz, standart SQL kullanır, bu nedenle RDBMS'nin herhangi bir markasında çalışmalıdır.
SELECT t1.*
FROM mytable t1
LEFT OUTER JOIN mytable t2
ON (t1.UserId = t2.UserId AND t1."Date" < t2."Date")
WHERE t2.UserId IS NULL;
Başka bir deyişle: satırı, t1başka bir satırın olmadığı yerden getirUserId ve daha büyük bir Tarih .
("Date" tanımlayıcısını ayırıcılara koydum, çünkü bu SQL ayrılmış bir kelimedir.)
Böyle bir durumda t1."Date" = t2."Date"iki katına çıkar. Genellikle tabloların auto_inc(seq)anahtarı vardır, örn id. Çifte önlemek için aşağıdaki kullanılabilir:
SELECT t1.*
FROM mytable t1
LEFT OUTER JOIN mytable t2
ON t1.UserId = t2.UserId AND ((t1."Date" < t2."Date")
OR (t1."Date" = t2."Date" AND t1.id < t2.id))
WHERE t2.UserId IS NULL;
@Farhan'dan yorum:
İşte daha ayrıntılı bir açıklama:
Bir dış katılması için girişimlerde birleştirme t1ile t2. Varsayılan olarak, tüm sonuçlar t1döndürülür ve eğer bir maç var ise t2, o da döndürülür. t2Belirli bir satır için eşleşme yoksa, t1sorgu yine de satırını döndürür ve tüm sütunları için yer tutucu olarak t1kullanır . Dış birleşimler genel olarak böyle çalışır.NULLt2
Bu sorgudaki hile, birleştirmenin eşleşen koşulunu aynı ve daha büyük bir değerlet2 eşleşecek şekilde tasarlamaktır . Bir satır bulunuyorsa olmak fikri bu daha büyük vardır , o satır buna karşı karşılaştırıldığında oluyor değil kutu büyük olması bunun için . Ancak eşleşme yoksa - yani , satırdan daha büyük bir satır yoksa - içerideki satırın verilen için en büyük satır olduğunu biliyoruz . userid datet2datet1dateuseridt2datet1t1dateuserid
Bu gibi durumlarda (eşleşme olmadığında), birleşim koşulunda belirtilen sütunlar bile sütunları t2olacaktır NULL. Bu yüzden kullanıyoruz WHERE t2.UserId IS NULL, çünkü dateverilenler için daha büyük bir satır bulunmayan durumları arıyoruz userid.