2013-08-10 13 views
8

Bunu bir süredir anlamaya çalışıyorum ve işe yaramayacak gibi görünmüyor. Buna benzeyen bir tablom var.Eloquent kullanarak gruplanmış sonuçlar nasıl sipariş edilir?

Tablo: Sorunlar

id yearly_issue year stock created_at  updated_at  magazine_id 
1 10    2000 1  [timestamp]  [timestamp]  3 
2 12    1994 6  [timestamp]  [timestamp]  10 
3 36    2007 10  [timestamp]  [timestamp]  102 
4 6    2002 7  [timestamp]  [timestamp]  7 
5 6    2002 2  [timestamp]  [timestamp]  5 
6 12    2003 9  [timestamp]  [timestamp]  10 
7 11    2003 12  [timestamp]  [timestamp]  10 

Benim sorunum sadece her dergi (sütun magazine_id) birini almak istiyorum, ben (! Kolay) ama sıralamak gerekir olmasıdır.

$issues = Issue::where('stock', ($all ? '>=' : '>'), 0) 
    ->orderBy('year', 'desc') 
    ->orderBy('yearly_issue', 'desc') 
    ->take($perpage) 
    ->get(); 

ben groupBy('magazine_id') yardımcı olacağını da ekledi düşündüm, ama sadece kısmen yardımcı oluyor sanki görünüyor:

bugün itibariyle Benim, Etkili sorgusu olur. Sonuçlar doğru sırada değil. Öyleyse, benim sorum şu - bunun etrafında herhangi bir kolay yolu var mı?

Benzer sorulara çeşitli yanıtlar deniyorum, ancak uygulamayı tamamen gerçekleştiremedim.

Retrieving the last record in each group

veya

How to get the latest record in each group using GROUP BY?

fazla yardım çok takdir edilecektir.

DÜZENLEME: Ancak

SELECT i1.*, c.name AS image, m.title AS title 
FROM issues i1 
INNER JOIN covers c ON i1.id = c.issue_id 
INNER JOIN magazines m ON i1.magazine_id = m.id 
JOIN (SELECT magazine_id, MAX(year) year, MAX(yearly_issue) yearly_issue FROM issues GROUP BY magazine_id) i2 
ON i1.magazine_id = i2.magazine_id 
AND i1.year = i2.year 
-- AND i1.yearly_issue = i2.yearly_issue 
WHERE i1.stock ($all ? '>=' : '>') 0 
ORDER BY i1.year DESC, i1.yearly_issue DESC 
LIMIT $perpage 

bu hiç bana istenilen sonucu vermiyor: Şu anda ben en yakın budur.

cevap

13

DESC sonlandırma siparişi ile sipariş verilecek her sütun için MAX işlevini SELECT maddesine eklemeniz gerekir. Tersi, ASC sonlandırma sırasına göre sipariş edilen sütunlar için gider,işlevini SELECT maddesine eklemeniz gerekir.

Sizin Eloquent sorgu raw seçmek içermelidir:

$issues = DB::table('issues') 
    ->select(DB::raw('id, max(year) as year, max(yearly_issue) as yearly_issue, stock, created_at, updated_at, magazine_id')) 
    ->groupBy('magazine_id') 
    ->orderBy('year', 'desc') 
    ->orderBy('yearly_issue', 'desc') 
    ->take(10) 
    ->get(); 

sadece dezavantajı Eğer almak istediğiniz her sütun belirtmek gerekir olmasıdır. Ve * seçiciyi kullanmayın, select deyimindeki toplama işlevini geçersiz kılar.


Güncelleme: Çok çalışır SELECT fıkrada önce toplama işlevlerini * seçici ekleme gibi görünüyor. Ben * seçici önce toplama işlevleri onların sütunları geçersiz kılar yapar koyarak düşünüyorum

->select(DB::raw('*, max(year) as year, max(yearly_issue) as yearly_issue')) 

: Bu ham seçme yeniden anlamına gelir.

+1

Awesome! =) Bu haftasonu kurtardı. – Andreas

+1

Uooow! Bu gerçekten bir hayat kurtarıcıydı. Çok teşekkürler! –

+0

teşekkürler bu en iyi çözümdür –

3

Gruplamadan önce sonuçlar sipariş etmenin bir yolunu aradım ve bu cevap patlamaya devam etti. Benim durumumda, bir kullanıcının mesaj gelen kutusu içindi.Kullanıcı tarafından alınan en son mesajı, bir parçası oldukları her ileti dizisinde göstermem gerekiyordu.

-------------------------------------------------------------------- 
| id | sender_id | receiver_id | message | created_at | updated_at | 
-------------------------------------------------------------------- 
| |   |    |   |   |   | 
-------------------------------------------------------------------- 

bu soruya, gruplar sonuçları kabul cevabı ve daha sonra bunları sıralar: My tablo bu gibi görünüyor. Sonuçları gruplandırmadan önce created_at alanına göre inmeye ihtiyacım vardı, böylece her iş parçasından en son mesajı alırdım. Gelen

select * 
    from `UserTable` 
where userId=3 
    group by `field` desc 
    order by `dateActivityComplete` ; 

:

select * from (
    select * from `messages` 
    order by `created_at` desc 
) as sub 
group by `sender_id` 
+1

Çok teşekkürler, özel ihtiyacım için işe yaramadı, -> tosql ayrıştırıcısı parametreleri çok iyi ayrıştırmıyor, ancak basit bir raw sql sorgulaması çalıştırdı benim için çözdü, kendi çözüm :) –

0

MySQL böyle bir şey yapabilirsiniz:

$sub = $query->orderBy('created_at', 'desc'); 
return $query->select('*') 
      ->from(DB::raw("({$sub->toSql()}) as sub")) 
      ->groupBy('sender_id'); 

Bu aşağıdaki sorgu oluşturur: Neyse, burada kazma bir sürü sonra benim son çözüm oldu şunun gibi bir şey yaparsınız: -> groupBy ('field', 'desc'), ancak, groupBy siparişi, sırayla sipariş ile aynı bir seçenek olarak görünmüyor.

Ham sorguyu veya muhtemelen maksimum işlevi kullanmanız gereken bir örnek olabilir.

Wade

İlgili konular