MySQL sıralaması


243

Burada bulunacak birçok benzer soru var, ancak herhangi bir sorunun soruyu yeterince cevapladığını sanmıyorum.

Mevcut en popüler sorudan devam edeceğim ve eğer uygunsa örneklerini kullanacağım.

Bu örnekte görev, veritabanındaki her yazar için en son gönderiyi almaktır.

Örnek sorgu, her zaman döndürülen en son yayın olmadığı için kullanılamaz sonuçlar üretir.

SELECT wp_posts.* FROM wp_posts
    WHERE wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
    GROUP BY wp_posts.post_author           
    ORDER BY wp_posts.post_date DESC

Geçerli kabul edilen cevap

SELECT
    wp_posts.*
FROM wp_posts
WHERE
    wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author
HAVING wp_posts.post_date = MAX(wp_posts.post_date) <- ONLY THE LAST POST FOR EACH AUTHOR
ORDER BY wp_posts.post_date DESC

Ne yazık ki bu cevap basit ve basit bir yanlıştır ve çoğu durumda orijinal sorgudan daha az kararlı sonuçlar üretir.

En iyi çözümüm formun alt sorgusunu kullanmak

SELECT wp_posts.* FROM 
(
    SELECT * 
    FROM wp_posts
    ORDER BY wp_posts.post_date DESC
) AS wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author 

Benim sorum o zaman basit: Bir alt sorguyu başvurmadan gruplamadan önce satır sipariş için zaten var mı?

Düzenleme : Bu soru başka bir sorudan bir devamtı ve durumumun detayları biraz farklı. Ayrıca belirli bir gönderi için benzersiz bir tanımlayıcı olan bir wp_posts.id olduğunu varsayabilirsiniz (ve yapmalısınız).


2
Verilen cevapların yorumlarında belirttiğiniz gibi, aynı Zaman Damgasına sahip bazı yayınlara sahip olmak mümkün olabilir. Öyleyse, lütfen verileri ve beklenen sonucu içeren bir örnek verin. Ve lütfen bu sonucu neden beklediğinizi açıklayın. post_authorve post_datebenzersiz bir sıra elde etmek için yeterli değil, bu yüzden başına benzersiz bir sıra elde etmek için daha fazlası olmalıpost_author
Sir Rufo

@SirRufo Haklısın, sizin için bir düzenleme ekledim.
Rob Forrest

There are plenty of similar questions to be found on here but I don't think that any answer the question adequately.Ödüller bunun içindir.
Orbit'te Hafiflik Yarışları

@LightnessRacesinOrbit, mevcut sorunun bence yanlış olduğunu kabul eden bir cevabı varsa, ne yapmayı önerirsiniz?
Rob Forrest

1
Eğer bir alt sorgu kullanan bir cevap neden kabul merak - Sorunuz açıkça "... sorduğunda ??? 'Bir alt sorgu başvurmadan gruplama önce sipariş satırlarına yine de var mı?'
Tv-C-15

Yanıtlar:


373

ORDER BYBir alt sorguda kullanmak bu soruna en iyi çözüm değildir.

max(post_date)Yazarın yazdığı en iyi çözüm , maksimum tarihi döndürmek için bir alt sorgu kullanmak ve ardından bunu hem ve post_authorhem de maksimum tarihte tablonuza katılmaktır .

Çözüm şöyle olmalıdır:

SELECT p1.* 
FROM wp_posts p1
INNER JOIN
(
    SELECT max(post_date) MaxPostDate, post_author
    FROM wp_posts
    WHERE post_status='publish'
       AND post_type='post'
    GROUP BY post_author
) p2
  ON p1.post_author = p2.post_author
  AND p1.post_date = p2.MaxPostDate
WHERE p1.post_status='publish'
  AND p1.post_type='post'
order by p1.post_date desc

Aşağıdaki örnek verilere sahipseniz:

CREATE TABLE wp_posts
    (`id` int, `title` varchar(6), `post_date` datetime, `post_author` varchar(3))
;

INSERT INTO wp_posts
    (`id`, `title`, `post_date`, `post_author`)
VALUES
    (1, 'Title1', '2013-01-01 00:00:00', 'Jim'),
    (2, 'Title2', '2013-02-01 00:00:00', 'Jim')
;

Alt sorgu şu maksimum tarihi ve yazarı döndürecektir:

MaxPostDate | Author
2/1/2013    | Jim

Sonra bunu tekrar masaya kattığınız için, her iki değerde de bu yayının tüm ayrıntılarını döndürürsünüz.

Demo ile SQL Fiddle bakın .

Bu verileri doğru şekilde döndürmek için bir alt sorgu kullanma hakkındaki yorumlarımı genişletmek için.

MySQL GROUP BYsizi SELECTlisteye eklediğiniz her sütuna zorlamaz . Sonuç olarak, yalnızca GROUP BYbir sütun ancak toplamda 10 sütun döndürürseniz, buna ait olan diğer sütun değerlerinin post_authordöndürüldüğünün garantisi yoktur . Sütun bir GROUP BYMySQL içinde değilse, hangi değerin döndürüleceğini seçer.

Alt sorguyu toplama işleviyle kullanmak, her seferinde doğru yazar ve gönderinin döndürülmesini garanti eder.

Yan not olarak, MySQL ORDER BYbir alt sorguda kullanmanıza izin verirken GROUP BYve SELECTlistedeki her sütuna a uygulamanıza izin verirken, bu davranışın SQL Server da dahil olmak üzere diğer veritabanlarında izin verilmez.


4
Orada ne yaptığınızı görüyorum, ancak bu en son gönderinin yapıldığı tarihi döndürüyor, en son gönderinin tamamı değil.
Rob Forrest

1
@RobForrest birleştirmenin yaptığı şeydir. Alt sorgudaki en son yayın tarihini yazar tarafından döndürür ve ardından wp_poststam satırı elde etmek için her iki sütunda da birleştirilirsiniz .
Taryn

7
@RobForrest Birisi için, GROUP BYyalnızca bir sütuna uyguladığınızda , diğer sütunlardaki değerlerin tutarlı bir şekilde doğru olacağının garantisi yoktur. Maalesef, MySQL bu tür SELECT / GROUPing türünün diğer ürünlerin gerçekleşmesine izin vermez. İkinci olarak, ORDER BYSQL Server da dahil olmak üzere diğer veritabanı ürünlerinde MySQL'de izin verilirken bir alt sorguda bir sözdiziminin kullanılmasına izin verilmez. Her yürütüldüğünde doğru sonucu döndürecek bir çözüm kullanmalısınız.
Taryn

2
Ölçeklendirme için bileşik INDEX(post_author, post_date)önemlidir.
Rick James

1
@ jtcotton63 Doğru, ancak post_idiç sorgunuzu koyarsanız , teknik olarak da gruplandırmalısınız, bu da sonuçlarınızı eğrir.
Taryn

20

Çözümünüz, bazı alanlara göre gruplandırmaya izin veren GROUP BY deyimine yönelik bir uzantı kullanıyor (bu durumda, sadece post_author):

GROUP BY wp_posts.post_author

ve birleştirilmemiş sütunları seçin:

SELECT wp_posts.*

grupta yan tümce olarak listelenmeyen veya toplama işlevinde kullanılmayan (MIN, MAX, COUNT, vb.).

Uzantıyı GROUP BY deyimine doğru kullanma

Bu, toplanmamış sütunların tüm değerleri her satır için eşit olduğunda kullanışlıdır.

Örneğin, bir bahçeniz olduğunu varsayalım GardensFlowers( namebahçede flowerbüyüyen bahçede):

INSERT INTO GardensFlowers VALUES
('Central Park',       'Magnolia'),
('Hyde Park',          'Tulip'),
('Gardens By The Bay', 'Peony'),
('Gardens By The Bay', 'Cherry Blossom');

ve birden fazla çiçeğin yetiştiği bir bahçede yetişen tüm çiçekleri çıkarmak istiyorsunuz. Sonra bir alt sorgu kullanmak zorundasınız, örneğin bunu kullanabilirsiniz:

SELECT GardensFlowers.*
FROM   GardensFlowers
WHERE  name IN (SELECT   name
                FROM     GardensFlowers
                GROUP BY name
                HAVING   COUNT(DISTINCT flower)>1);

Bunun yerine bahçedeki tek çiçek olan tüm çiçekleri çıkarmanız gerekiyorsa, HAVING koşulunu sadece değiştirebilirsiniz HAVING COUNT(DISTINCT flower)=1, ancak MySql de bunu kullanmanıza izin verir:

SELECT   GardensFlowers.*
FROM     GardensFlowers
GROUP BY name
HAVING   COUNT(DISTINCT flower)=1;

alt sorgu yok, standart SQL değil, daha basit.

GROUP BY yantümcesine yanlış uzantı kullanımı

Ancak, her satır için eşit olmayan birleştirilmiş sütunları SEÇERSENİZ ne olur? MySql'in bu sütun için seçtiği değer nedir?

Görünüşe göre MySql her zaman karşılaştığı İLK değeri seçer .

Karşılaştığı ilk değerin tam olarak istediğiniz değer olduğundan emin olmak için, GROUP BYsıralı bir sorguya a uygulamanız gerekir , dolayısıyla bir alt sorgu kullanmanız gerekir. Aksi halde yapamazsın.

MySql'in her zaman karşılaştığı ilk satırı seçtiği varsayımı göz önüne alındığında, satırları GROUP BY'dan önce doğru bir şekilde sıralıyorsunuz. Ancak ne yazık ki, belgeleri dikkatlice okursanız, bu varsayımın doğru olmadığını fark edeceksiniz.

Her zaman aynı olmayan birleştirilmiş sütunları seçerken, MySql herhangi bir değer seçmekte serbesttir, bu nedenle gerçekte gösterdiği sonuç belirsizdir .

Toplanmayan bir sütunun ilk değerini elde etmek için bu hile çok kullanılır ve genellikle / neredeyse her zaman çalışır, bazen de (kendi riskimde) kullanıyorum. Ancak belgelenmediği için bu davranışa güvenemezsiniz.

Bu bağlantı (teşekkürler ypercube!) GROUP BY hilesi optimize edildi , aynı sorgunun muhtemelen farklı bir optimizasyon motoru nedeniyle MySql ve MariaDB arasında farklı sonuçlar döndürdüğü bir durumu gösteriyor.

Yani, bu hile işe yararsa, bu sadece bir şans meselesidir.

Diğer soru üzerine kabul cevabı bana yanlış görünüyor:

HAVING wp_posts.post_date = MAX(wp_posts.post_date)

wp_posts.post_datebirleştirilmiş olmayan bir sütundur ve değeri resmi olarak belirsizdir, ancak büyük olasılıkla ilk post_datekarşılaşılan değer olacaktır . Ancak GROUP BY hilesi sırasız bir tabloya uygulandığından, ilk post_datekarşılaşılanın hangisi olduğundan emin değil .

Muhtemelen tek bir yazarın tek mesajları olan yayınları döndürür, ancak bu bile her zaman kesin değildir.

Olası bir çözüm

Bunun olası bir çözüm olabileceğini düşünüyorum:

SELECT wp_posts.*
FROM   wp_posts
WHERE  id IN (
  SELECT max(id)
  FROM wp_posts
  WHERE (post_author, post_date) = (
    SELECT   post_author, max(post_date)
    FROM     wp_posts
    WHERE    wp_posts.post_status='publish'
             AND wp_posts.post_type='post'
    GROUP BY post_author
  ) AND wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
  GROUP BY post_author
)

İç sorguda her yazar için maksimum gönderi tarihini döndürüyorum. Daha sonra aynı yazarın teorik olarak aynı anda iki gönderi olabileceğini göz önünde bulunduruyorum, bu yüzden sadece maksimum kimliği alıyorum. Ve sonra bu maksimum kimliğe sahip tüm satırları döndürüyorum. IN yan tümcesi yerine birleşimler kullanılarak daha hızlı yapılabilir.

(Bunun IDyalnızca arttığından eminseniz ve bunun ID1 > ID2da anlamı varsa post_date1 > post_date2, sorgu çok daha basit hale getirilebilir, ancak durumun bu olup olmadığından emin değilim).


Bu extension to GROUP Byilginç bir okuma, bunun için teşekkürler.
Rob Forrest

2
Başarısız olduğu bir örnek: GROUP BY hilesi optimize edildi
ypercubeᵀᴹ

GROUP BY ile belirli ifadelerde toplanmamış sütunlar artık MySQL 5.7 ile varsayılan olarak çalışmaz: stackoverflow.com/questions/34115174/… . Hangi IMHO çok daha güvenlidir ve bazı insanları daha verimli sorgular yazmaya zorlar.
rink.attendant.6

Bu cevap bir alt sorgu kullanmıyor mu? Orijinal Poster alt sorgu kullanmayan bir çözüm istemiyor mu?
TV-C-15

1
@ TV-C-15 sorun alt sorgu başvurma ile, ve neden bir alt sorgu başvurma işe yaramaz açıklamak. Kabul edilen cevap bile bir alt sorgu kullanıyor, ancak başvurmanın neden kötü bir fikir olduğunu açıklamaya başlıyor ( Bir alt sorguda SİPARİŞ BY kullanmak bu soruna en iyi çözüm değildir )
fthiella

9

Okuyacağınız şey oldukça hileli, bu yüzden bunu evde denemeyin!

Genel olarak SQL senin sorunun cevabı HAYIR , fakat rahat modunun GROUP BY(bahsettiği @bluefeet ), cevap EVET MySQL.

Varsayalım, üzerinde bir BTREE indeksiniz var (post_status, post_type, post_author, post_date). Endeks başlık altında nasıl görünüyor?

(post_status = 'yayınla', post_type = 'posta', post_author = 'kullanıcı A', post_date = '2012-12-01') (post_status = 'yayınla', post_type = 'posta', post_author = 'kullanıcı A', post_date = '2012-12-31') (post_status = 'yayınla', post_type = 'post', post_author = 'kullanıcı B', post_date = '2012-10-01') (post_status = 'yayınla', post_type = ' post ', post_author =' kullanıcı B ', post_date =' 2012-12-01 ')

Yani veriler tüm bu alanlara göre artan sırada sıralanır.

Bir yapıyoruz zaman GROUP BYvarsayılan olarak gruplandırarak alanı tarafından verileri sıralar ( post_authorbizim durumda; post_status, post_type gerektirdiği WHEREmaddesinde) ve eşleşen dizin varsa, bu artan düzende her ilk kayıt için veri alır. Sorgu aşağıdakileri getirecektir (her kullanıcı için ilk gönderi):

(post_status = 'yayınla', post_type = 'posta', post_author = 'kullanıcı A', post_date = '2012-12-01') (post_status = 'yayınla', post_type = 'posta', post_author = 'kullanıcı B', POST_DATE = '2012/10/1')

Ancak GROUP BYMySQL'de siparişi açıkça belirtmenize izin verir. Ve post_userazalan sırada talep ettiğinizde , dizinimiz ters sırada ilerler ve yine de sonuncu olan her grup için ilk kaydı alır.

Yani

...
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC

bize verecek

(post_status = 'yayınla', post_type = 'posta', post_author = 'kullanıcı B', post_date = '2012-12-01') (post_status = 'yayınla', post_type = 'posta', post_author = 'kullanıcı A', POST_DATE = '2012/12/31')

Şimdi, gruplama sonuçlarını post_date ile sipariş ettiğinizde, istediğiniz verileri elde edersiniz.

SELECT wp_posts.*
FROM wp_posts
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC
ORDER BY wp_posts.post_date DESC;

Not :

Bu, bu özel sorgu için ne tavsiye ederim değil. Bu durumda, @bluefeet'in önerdiği şeyin biraz değiştirilmiş bir versiyonunu kullanırdım . Ancak bu teknik çok faydalı olabilir. Cevabımı şuraya bir göz atın: Her gruptaki son kaydı alma

Tuzaklar : Yaklaşımın dezavantajları

  • sorgunun sonucu SQL'in ruhuna aykırı olan dizine bağlıdır (dizinler yalnızca sorguları hızlandırmalıdır);
  • index, sorgu üzerindeki etkisi hakkında hiçbir şey bilmiyor (siz veya gelecekte başka biri, dizini çok fazla kaynak tüketen bulabilir ve bir şekilde değiştirebilir, yalnızca sonuçlarını değil, sorgu sonuçlarını kırabilir)
  • Sorgunun nasıl çalıştığını anlamıyorsanız, büyük olasılıkla bir aydaki açıklamayı unutacaksınız ve sorgu sizi ve meslektaşlarınızı karıştıracaktır.

Avantaj zor durumlarda performanstır. Bu durumda, sıralamada yer alan veri miktarı nedeniyle sorgunun performansı @ bluefeet sorgusuyla aynı olmalıdır (tüm veriler geçici bir tabloya yüklenir ve sonra sıralanır; btw, sorgusu da (post_status, post_type, post_author, post_date)dizini gerektirir ) .

Ne öneririm :

Söylediğim gibi, bu sorgular MySQL'i geçici bir tabloda potansiyel olarak büyük miktarda veriyi sıralayarak zaman kaybettiriyor. Disk belleği gerektirmeniz durumunda (LIMIT söz konusudur) verilerin çoğu atılır. Ne yapacağım sıralanan veri miktarını en aza indirmek: sıralama ve alt sorguda minimum veri sınırlamak ve sonra tekrar tüm tabloya katılmak.

SELECT * 
FROM wp_posts
INNER JOIN
(
  SELECT max(post_date) post_date, post_author
  FROM wp_posts
  WHERE post_status='publish' AND post_type='post'
  GROUP BY post_author
  ORDER BY post_date DESC
  -- LIMIT GOES HERE
) p2 USING (post_author, post_date)
WHERE post_status='publish' AND post_type='post';

Yukarıda açıklanan yaklaşımı kullanarak aynı sorgu:

SELECT *
FROM (
  SELECT post_id
  FROM wp_posts
  WHERE post_status='publish' AND post_type='post'
  GROUP BY post_author DESC
  ORDER BY post_date DESC
  -- LIMIT GOES HERE
) as ids
JOIN wp_posts USING (post_id);

Tüm bu sorgular SQLFiddle'daki yürütme planları ile .


Bu ilginç bir teknik. İki şey: bunu evde denemeyin, potansiyel tuzaklar nelerdir? ikincisi, bluefeet'in cevabının biraz değiştirilmiş bir versiyonundan bahsediyorsunuz, bu ne olurdu?
Rob Forrest

Bunun için teşekkürler, birisinin soruna farklı bir şekilde saldırdığını görmek ilginç. Veri setim 18M + satırlarınızın yakınında olmadığından, performansın sürdürülebilirlik kadar önemli olduğunu düşünmüyorum, bu nedenle sonraki seçeneklerinizin muhtemelen daha uygun olduğunu düşünüyorum. Alt sorgunun içindeki sınır fikrini seviyorum.
Rob Forrest

8

Bunu dene. Her yazarın en son yayın tarihlerinin listesini almanız yeterlidir . Bu kadar

SELECT wp_posts.* FROM wp_posts WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post' AND wp_posts.post_date IN(SELECT MAX(wp_posts.post_date) FROM wp_posts GROUP BY wp_posts.post_author) 

@Rob Forrest, çözümümü kontrol et. Umarım sorunuzu çözer!
sanchitkhanna26

1
Üzgünüm, bunun işe yarayacağını sanmıyorum. Örneğin, hem yazar 1 hem de yazar 2, 01/02/13 tarihinde bir şey yayınlar ve ardından yazar 2, 08/02/13 tarihinde yeni bir şey gönderirse, 3 gönderinin tamamı döndürülür. Evet datetime alanı zamanı içerir, bu nedenle durum daha az olasıdır, ancak hiçbir şekilde yeterince büyük bir veri kümesinde garanti edilmez.
Rob Forrest

Kullanmak için +1 post_date IN (select max(...) ...). Bu, bir alt seçimdeki
Seaux

sadece açıklığa kavuşturmak için, ancak post_author dizine sahipseniz daha uygun olur.
Seaux

1
IN ( SELECT ... )eşdeğer JOIN'dan çok daha az verimlidir.
Rick James

3

Hayır. Gruplama sonuç kümesini değiştireceğinden, gruplamadan önce kayıtları sıralamak mantıklı değildir. Alt sorgu yolu tercih edilen yoldur. Bu çok yavaş gidiyorsa, tablo tasarımınızı değiştirmeniz gerekir, örneğin her yazar için son yazının kimliğini ayrı bir tabloda depolayarak veya her yazarı için yazısının sonuncusunu gösteren bir boole sütunu girmeniz gerekir. bir.


Reddet, bu tür bir sorgunun doğru SQL sözdizimi olmadığı ve bu nedenle veritabanı platformlarında taşınabilir olmadığı hakkındaki Bluefeet'in yorumlarına nasıl yanıt verirdiniz? Bunun her seferinde doğru sonuçları vereceğine dair bir garanti bulunmadığına dair endişeler de vardır.
Rob Forrest

2

Sadece max işlevini ve grup işlevini kullanın

    select max(taskhistory.id) as id from taskhistory
            group by taskhistory.taskid
            order by taskhistory.datum desc

3
En yüksek kimliğe sahip olan en son gönderilmemişse ne olur? Bunun bir örneği, yazarın görevini göndermeden önce uzun süre taslak halinde tutması olabilir.
Rob Forrest

0

Özetlemek gerekirse, standart çözüm ilişkisiz bir alt sorgu kullanır ve şöyle görünür:

SELECT x.*
  FROM my_table x
  JOIN (SELECT grouping_criteria,MAX(ranking_criterion) max_n FROM my_table GROUP BY grouping_criteria) y
    ON y.grouping_criteria = x.grouping_criteria
   AND y.max_n = x.ranking_criterion;

MySQL'in eski bir sürümünü veya oldukça küçük bir veri kümesini kullanıyorsanız, aşağıdaki yöntemi kullanabilirsiniz:

SELECT x.*
  FROM my_table x
  LEFT
  JOIN my_table y
    ON y.joining_criteria = x.joining_criteria
   AND y.ranking_criteria < x.ranking_criteria
 WHERE y.some_non_null_column IS NULL;  

Eski sürüm dediğinizde, bu MySQL'in hangi sürümü üzerinde çalışır? Ve üzgünüm hayır, örneğimde veri kümesi oldukça büyük.
Rob Forrest

Herhangi bir sürümde (yavaşça) çalışacaktır. Eski sürümler alt sorgu kullanamaz.
Çilek

Evet, yöntem # 2 (denediğim sürüm buradan ) büyük bir veri kümesinde (milyonlarca satır) çalışmaz, kayıp bir bağlantı hatası atar . Yöntem # 1 bir sorguyu yürütmek için yaklaşık 15 saniye sürer. Başlangıçta iç içe geçmiş sorguları kullanmaktan kaçınmak istedim, ancak bu beni yeniden değerlendirdi. Teşekkür ederim!
aexl

@TheSexiestManinJamaica Evet. 3,5 yılda çok fazla şey değişmedi. Bir sorgunun kendi başına verimli olduğunu varsayarsak, sorgunun yürütülmesi için gereken süre büyük ölçüde veri kümesinin boyutuna, dizinlerin düzenlenmesine ve kullanılabilir donanıma bağlıdır.
Çilek

-1

** Alt veri sorgularının büyük veri kümelerinde kullanıldığında performans üzerinde kötü etkisi olabilir **

Orijinal sorgu

SELECT wp_posts.*
FROM   wp_posts
WHERE  wp_posts.post_status = 'publish'
       AND wp_posts.post_type = 'post'
GROUP  BY wp_posts.post_author
ORDER  BY wp_posts.post_date DESC; 

Değiştirilmiş sorgu

SELECT p.post_status,
       p.post_type,
       Max(p.post_date),
       p.post_author
FROM   wp_posts P
WHERE  p.post_status = "publish"
       AND p.post_type = "post"
GROUP  BY p.post_author
ORDER  BY p.post_date; 

i kullanıyorum yapmamı maxiçinde select clause==> max(p.post_date)o tarafından grubundan sonra maksimum sütuna göre alt Seçme sorguları ve düzeni kaçınmak mümkündür.


1
Bu gerçekten yazar başına en son post_date değerini döndürür, ancak döndürülen verilerin geri kalanının en son post_date içeren gönderiyle ilgili olduğuna dair bir garanti yoktur.
Rob Forrest

@RobForrest -> Nedenini anlamıyorum? cevabınızı detaylandırmak ve sadece iddiaları ortaya koymak iyi bir fikirdir. Anladığım kadarıyla, veriyi ilişkili olduğu yerde filtrelemek için kullandığım verilerle ilişkili olduğu garanti edilmektedir.
guykaplan

1
Bir dereceye kadar, tamamen haklısınız, seçtiğiniz 4 alanın her biri bu maksimum post_date ile ilgili olacak, ancak bu sorulan soruya cevap vermiyor. Örneğin, post_id öğesini veya gönderinin içeriğini eklediyseniz, bu sütunların maksimum tarihle aynı kayıttan olacağı garanti edilemez. Sorgunuzun yukarının diğer ayrıntılarını döndürmesini sağlamak için ikinci bir sorgu çalıştırmanız gerekir. Soru en son gönderinin tarihini bulmakla ilgiliyse, evet cevabınız iyi olur.
Rob Forrest

@guykaplan, Alt sorgular yavaş değil. Veri kümesinin boyutu önemli değil. Nasıl kullandığınıza bağlıdır. Bkz. Percona.com/blog/2010/03/18/when-the-subselect-runs-faster
Pacerier

@Pacerier: Makale, alt sorgulardan nasıl performans avantajı elde edebileceğinizi gösteriyor, ancak verilen senaryoyu daha iyi performans gösterecek şekilde dönüştürdüğünüzü görmek isterim. ve Veri boyutu önemlidir, yine yayınladığınız makalede çalışmak için sadece bir tablo olduğunu varsayarsınız. veri boyutu satır boyutuna göre değil, karmaşıklık boyutuna göre. Eğer gerçekten büyük bir tablo (çok sayıda tablo dahil değil) ile çalışıyorsanız, alt sorgu çok daha iyi performans söyleyebilir.
guykaplan

-4

İlk olarak, seçimde * kullanmayın, performanslarını etkiler ve grubun kullanımını ve sırasına göre kullanımını engeller. Bu sorguyu deneyin:

SELECT wp_posts.post_author, wp_posts.post_date as pdate FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author           
ORDER BY pdate DESC

Tabloyu SİPARİŞ TARAFINDAN, yalnızca diğer ad olarak belirtmediğinizde, seçimin sonucunu sıralarlar.


Select * 'leri görmezden gelin, bu örnekte kısalık içindir. Cevabınız verdiğim ilk örnekle tamamen aynı.
Rob Forrest

Takma adın hangi satırın döndürüleceği veya sonuçların sıralanması üzerinde bir etkisi yoktur.
Rob Forrest
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.