Postgres: Farklı ancak yalnızca bir sütun için


120

Pgsql'de isimleri olan (1 milyondan fazla satır içeren) bir tablom var, ama aynı zamanda birçok kopyam var. Ben 3 alanları seçin: id, name, metadata.

Bunları rastgele seçmek istiyorum ORDER BY RANDOM()ve LIMIT 1000bu yüzden PHP betiğimde biraz bellek kaydetmek için bunu birçok adımda yapıyorum.

Ama bunu nasıl yapabilirim ki bana sadece isimlerde kopya olmayan bir liste veriyor.

Örneğin [1,"Michael Fox","2003-03-03,34,M,4545"]iade edilir ama iade edilmez [2,"Michael Fox","1989-02-23,M,5633"]. Ad alanı en önemli alandır ve seçimi her yaptığımda listede benzersiz ve rastgele olmalıdır.

Birlikte çalıştığımız GROUP BY name, bu o zaman beni de kimliği ve meta olmasını bekler GROUP BYyanı veya agregalı işlevinde, ama onları bir türlü filtrelenmiş olması istemiyorum.

Çok sayıda sütunun nasıl getirileceğini bilen ancak yalnızca bir sütunda farklı bir şey yapan var mı?

Yanıtlar:


226

Yalnızca bir (veya n) sütunda / sütunda ayrım yapmak için:

select distinct on (name)
    name, col1, col2
from names

Bu, adı içeren herhangi bir satırı döndürecektir. Hangi satırların iade edileceğini kontrol etmek istiyorsanız, sipariş vermeniz gerekir:

select distinct on (name)
    name, col1, col2
from names
order by name, col1

Col1'e göre sipariş edildiğinde ilk satırı döndürür.

distinct on:

SELECT DISTINCT ON (ifade [, ...]), verilen ifadelerin eşit olarak değerlendirildiği her satır kümesinin yalnızca ilk satırını tutar. DISTINCT ON ifadeleri, ORDER BY ile aynı kurallar kullanılarak yorumlanır (yukarıya bakın). İstenen satırın ilk olarak görünmesini sağlamak için ORDER BY kullanılmadığı sürece her kümenin "ilk satırının" tahmin edilemez olduğunu unutmayın.

DISTINCT ON ifadeleri, en soldaki ORDER BY ifadeleriyle eşleşmelidir. ORDER BY yan tümcesi, normalde her DISTINCT ON grubu içindeki satırların istenen önceliğini belirleyen ek ifadeler içerir.


Siparişte iyi yakaladık. Rastgele bir sipariş istemekten bahsettikleri için eklemedim, ama yine de bahsetmek önemli.
Craig Ringer

Is order by namegerekli? İle farklı bir sonuç verir order by col1mi?
Elliot Chance

1
@elliot evet namegerekli. Kontrol distinct onkılavuzuna.
Clodoaldo Neto

1
TSQL ekibinin bunu yapmak için bu kadar mantıklı bir yol sunmasını diliyorum.
JTW

Lütfen uygun postgresql referansını
Ogaga Uzoh

17

Çok sayıda sütunun nasıl getirileceğini bilen ancak yalnızca bir sütunda farklı bir şey yapan var mı?

Sen istediğiniz maddesini .DISTINCT ON

Örnek veri veya eksiksiz bir sorgu sağlamadınız, bu yüzden size gösterecek hiçbir şeyim yok. Şöyle bir şey yazmak istiyorsun:

SELECT DISTINCT ON (name) fields, id, name, metadata FROM the_table;

Bu, öngörülemeyen (ancak "rastgele" olmayan) bir satır kümesi döndürecektir. Öngörülebilir hale getirmek istiyorsanız, ORDER BYher Clodaldo'nun cevabını ekleyin . Gerçekten rastgele yapmak istiyorsanız, isteyeceksiniz ORDER BY random().


Bu DISTINCT ON cümlesine dikkat edin, yalnızca aynı şeyi + daha fazlasını sipariş edebilirsiniz. Öyleyse DISTINCT ON (isim) derseniz, isme göre sipariş vermelisiniz, sonra başka ne isterseniz. Pek ideal değil.
Kevin Parker

Kevin, dış sorguda bir CTE veya alt sorguyu
Craig Ringer

Evet, ve performansın gidişatını izleyin ... Dizin alanındaki olası sonuçların tamamı aranacaktır. Bu neyi döner olabilir posgres tarafından farklı bir ayrı / düzeni işleyemez sırf bir 900ms bir içine doğru indeksi ile 10-20ms sorgu ol. Dış sorgu sırasının ne olduğu önemli değil, önce eşleşmeleri bulmak ve sonra yeniden sıralamak için iç alt sorgudaki dizini kullanacak. Sorunlarımıza gerçek çözümler için dba.stackexchange.com/questions/260852/…
Kevin Parker

4
SELECT NAME,MAX(ID) as ID,MAX(METADATA) as METADATA 
from SOMETABLE
GROUP BY NAME

2
Sadece bir uyarı: bu, "bir araya" ait olan kimlik değerini veya meta veri değerini
döndürmeyebilir

@Novum Hayır. Bu, Michael'ın maksimum değerleri istendiğinde, kedi Michael'ın satırlarından birinden bir kimlik değeri ve diğerinden meta verileri alması anlamına gelir.
Clodoaldo Neto

Evet, bu büyük ölçüde OP'nin kullandığı gerçek verilere bağlı, ki bunu kesinlikle bilmiyorum. MIN veya her neyse kullanmanız gerekebilir. Sadece bir GROUP BYcümlecikte olmayan alanları nasıl ekleyebileceğiniz gösterildi .
David Jashi

Bu iyi bir çözüm değildir çünkü farklı satırlardan farklı değerler karışacaktır.
Elliot Chance
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.