Bir sütun ve başka bir sütunda herhangi biri için farklı nasıl seçilir?


29

Bir sütunun farklı değerlerini bulmak için bir SQL veritabanı sorgulamam gerekiyor ve başka bir sütundan rastgele bir değere ihtiyacım var. Örneğin, aşağıdaki tabloyu iki sütun, anahtar ve değer olarak düşünün:

key     value
===     =====
one     test
one     another
one     value
two     goes
two     here
two     also
three   example

Keyfi olarak seçilen her bir anahtardan, belki de bu üç sırayı alan bir örnek satırı geri almak istiyorum:

key     value
===     =====
one     test
two     goes
three   example

Böyle bir sorguyu SQL'de nasıl formüle edebilirim?


2
Hangi DBMS (Oracle, SQL-Server, DB2, MySQL, Postgres)?
ypercubeᵀᴹ

1
Bu tescilli bir sistemdir.
WilliamKF

Yanıtlar:


33

Yazması en kolay sorgu MySQL içindir (katı ANSI ayarlarıyla değil). Standart dışı yapıyı kullanır:

SELECT key, value
FROM tableX
GROUP BY key ;

Sıkı ayarların ve ONLY_FULL_GROUP_BYvarsayılan ayarların bulunduğu son sürümde (5.7 ve 8.0+) ANY_VALUE(), 5.7'de eklenmiş olan işlevi kullanabilirsiniz :

SELECT key, ANY_VALUE(value) AS value
FROM tableX
GROUP BY key ;

Pencere işlevine sahip diğer DBMS'lerde (Postgres, SQL-Server, Oracle, DB2 gibi), bunları bu şekilde kullanabilirsiniz. Avantaj, sonuçtaki diğer sütunları da seçebilmenizdir ( keyve dışında value):

SELECT key, value
FROM tableX
    ( SELECT key, value,
             ROW_NUMBER() OVER (PARTITION BY key 
                                ORDER BY whatever)     --- ORDER BY NULL
               AS rn                                   --- for example
      FROM tableX
    ) tmp 
WHERE rn = 1 ;

Yukarıdakilerin eski sürümleri ve diğer tüm DBMS'ler için hemen hemen her yerde işe yarayan genel bir yol. Dezavantajı, bu yaklaşımla diğer sütunları seçememenizdir. Başka gibi o toplama işlevleri olan MIN()ve MAX()(biraz, metin, lekeler gibi) bazı DBMSs bazı veri türleri ile işi yok:

SELECT key, MIN(value) AS value
FROM tableX
GROUP BY key ;

PostgreSQL, DISTINCT ONkullanılabilecek standart dışı özel bir operatöre sahiptir. İsteğe bağlı ORDER BY, her gruptan hangi satırın seçileceğini seçmektir:

SELECT DISTINCT ON (key) key, value
FROM tableX
-- ORDER BY key, <some_other_expressions> ;

2
@WilliamKF "Rastgele seçildiyse" ile "rastgele seçildiğini" kastediyorsanız ORDER BY whatever, sonuçları rasgele hale getirecek bir işlev çağrısı ile ypercube'un sorgusunu değiştirin .
Leigh Riffel

1
@LeighRiffel rastgele, herhangi bir seçenek, rastlanan ilk karşılaşılan iyi çalışıyor gibi basit olması gerekmez.
WilliamKF

3

MS-SQl Sunucusu için:

;with FinalDataset as
(
    select *,
        row_number() over(partition by key order by value) as rownum
    from YourOriginalTable
)
select
   key,
   value
from FinalDataset 
where rownum = 1

Aynı şekilde, ikinci sonuç kümeniz için rownum = 2 olabilir


2

Kabul edilen cevaba benzer, ancak min () veya max () yerine array_agg () kullanabilirsiniz.

SELECT key, (array_agg(value))[1] AS value
FROM tableX
GROUP BY key ;

İsteğe bağlı olarak en büyük veya en küçük olanını seçmek için dizi içindeki değerleri sipariş edebilirsiniz:

SELECT key, (array_agg(value) ORDER BY value DESC)[1] AS value
FROM tableX
GROUP BY key ;

(PostgreSQL'de kontrol edildi)

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.