SQL Server'daki değerler listesinden nasıl seçim yapabilirim


218

Çözemediğim çok basit bir sorunum var. Böyle bir şey yapmam gerekiyor:

select distinct * from (1, 1, 1, 2, 5, 1, 6).

Herkes yardımcı olabilir ??

Düzenle

Veriler, müşterilerimizden birinden gelen bir metin dosyası olarak gelir. Tamamen biçimlendirilmemiş (tek, çok uzun bir metin satırı), ancak Excel'de bunu yapmak mümkün olabilir. Ama benim için pratik değil, çünkü sql sorgumda bu değerleri kullanmam gerekecek. Bir sorgu çalıştırmak gerektiğinde bunu yapmak uygun değil.


birden fazla tablodan mı, yoksa tek bir tablodan mı, ancak seçmek için belirli değerlere mi sahip olmak istiyorsunuz? sadece belirli bir id's gibi bir şey
Anirudh Goel

Sorduğunuz şey değil, başka bir dilde yapabilirsiniz. Örneğin PowerShell'de, $d = (1, 1, 1, 2, 5, 1, 6) | sort -Uniquebir dizideki farklı değerleri almak için yapabilirsiniz $d. Dosyadan dosyaya genişletmek kolaydır.
Jeppe Stig Nielsen

Burada önemli olan, bu değerlerin ayrı bir listesini almak veya bu değerler listesini SQL'e almak mı? @JeppeStigNielsen'in dediği gibi, SQL içermeyen bir metin listesinden farklı değerler almanın başka yolları da vardır. Burada diğer tablolara başvuran bir SQL komut dosyasına bir değer listesi almak için nasıl geldi geldi.
Rikki

Yanıtlar:


82

Virgülle sınırlandırılmış metnin uzun bir listesinin farklı değerlerini almanın en basit yolu, farklı değerleri elde etmek için UNION ile bir değiştir yerine kullanmaktır .

SELECT 1
UNION SELECT 1
UNION SELECT 1
UNION SELECT 2
UNION SELECT 5
UNION SELECT 1
UNION SELECT 6

Uzun virgülle ayrılmış metin satırınıza uygulanır

  • Her virgül ile bulun ve değiştirin UNION SELECT
  • İfadenin SELECTönüne a ekle

Şimdi çalışan bir sorgunuz olmalıdır


3
hayır, hayır, yüzlerce değerden oluşan bir listem var, el ile işkence olurdu
Eedoh

bu liste nereden geliyor? Bu listeyi Excel'de kopyalayıp yapıştırmak ve basit bir çapraz tablo kullanarak oradaki farklı değerleri çıkarmak çok daha kolay olabilir.
Lieven Keersmaekers

btw, find and replace de uzun bir yol alabilir. Her virgül yerine sendika seçimi ile değiştirin , önüne bir seçim ekleyin ve gösterdiğim sendika için çalışan bir sorguya sahip olmalısınız.
Lieven Keersmaekers

1
virgüllerin seçili sendikalarla değiştirilmesi ile bu şeyler bir cazibe gibi çalışıyor Teşekkürler :)
Eedoh

5
Performans nedenlerinden ötürü, Union-All ürününü, ardından Group-By ürününü veya dış seçiminizde Distinct özelliğini kullanmanızı öneririm.
MikeTeeVee

428

Sadece SQL Server 2008 tarihinde ve üzeri Mevcut bu formda satır yapıcı geçerli:
Şunları kullanabilirsiniz

SELECT DISTINCT * FROM (VALUES (1), (1), (1), (2), (5), (1), (6)) AS X(a)

Birçoğu aralarında şunları yazdı:


66
Yan not: Xtablo adı aiçin takma ad ve sütun adı için takma addır;).
shA.t

11
Bu, şu anda seçili
olana

1
Bu en genel yol, ben dürüst (ARRAY []) tarafından şımarık pgsqlve şimdi FROM satır kayıtları olarak küçük değerleri kabul etmek için kafa vurarak sqlserver, ve işte burada. Bildiğim için mutluyum.
Ben

1
Sütun ve tablo takma adı nedeniyle daha iyi cevap
Alfredo A.

79

Genel olarak :

SELECT 
  DISTINCT 
      FieldName1, FieldName2, ..., FieldNameN
FROM
  (
    Values
        ( ValueForField1, ValueForField2,..., ValueForFieldN ),
        ( ValueForField1, ValueForField2,..., ValueForFieldN ),
        ( ValueForField1, ValueForField2,..., ValueForFieldN ),
        ( ValueForField1, ValueForField2,..., ValueForFieldN ),
        ( ValueForField1, ValueForField2,..., ValueForFieldN )
  ) AS TempTableName ( FieldName1, FieldName2, ..., FieldNameN )

Senin durumunda :

Select 
  distinct
  TempTableName.Field1 
From 
  (
  VALUES
    (1), 
    (1), 
    (1), 
    (2), 
    (5), 
    (1), 
    (6)
  ) AS TempTableName (Field1)

1
Biliyorum "select *" kötü form olarak kabul edilir, ancak bu durumda select * kullanmamak için herhangi bir neden var mı? FieldName1, FieldName2, ..., FieldNameN çoğaltması grotesk çünkü.
Pxtl

@Pxtl "Seç *" kullanmamak için hiçbir neden yoktur. Bu alanın adlarını daha açık olması için yeniden yazdım. Ayrıca, "Farklı" anahtar kelimeye ihtiyacınız olmayabilir.
Ardalan Shahgholi

43

Aşağıdaki sözdizimini kullanmayı denediniz mi?

select * from (values (1), (2), (3), (4), (5)) numbers(number)

5
anonim bir kullanıcı kodu düzenlemek için önerdi:SELECT DISTINCT table_name.column_name FROM (VALUES (1), (2), (3)) AS table_name(column_name)
Vogel612

19

Tek bir tablodan yalnızca belirli değerleri seçmek istiyorsanız bunu deneyebilirsiniz

select distinct(*) from table_name where table_field in (1,1,2,3,4,5)

Örneğin:

select first_name,phone_number from telephone_list where district id in (1,2,5,7,8,9)

Birden fazla tablodan seçim yapmak istiyorsanız, UNION .

Sadece 1, 1, 1, 2, 5, 1, 6 değerlerini seçmek istiyorsanız, bunu yapmanız gerekir

select 1 
union select 1 
union select 1 
union select 2 
union select 5 
union select 1 
union select 6

1
Bir tablodan seçmem gerekmiyor, ancak bu değerler listesinden (parantez içinde). Ana sorun bu (bir tablodan değil, virgülle ayrılmış değerler dizisinden seçim yapmak)
Eedoh

bu durumda, Oracle'da DUAL tablonuz olduğu gibi, bunu da kullanabilirsiniz. Ancak DUAL olmadığı için sendika yoluna gitmeniz gerekecek. Virgülle ayrılmış değerler dizisine sahip olduğunuzdan bahsettiğiniz gibi başka bir yöntem deneyebilirsiniz, neden bunları bir tabloya eklemiyorsunuz ve sonra çok fazla sql sendikası kullanmak yerine düzgün bir sql seçme sorgusu kullanmıyorsunuz.
Anirudh Goel

14

PostgreSQL size bunu yapmanın 2 yolunu sunar:

SELECT DISTINCT * FROM (VALUES('a'),('b'),('a'),('v')) AS tbl(col1)

veya

SELECT DISTINCT * FROM (select unnest(array['a','b', 'a','v'])) AS tbl(col1)

dizi yaklaşımını kullanarak da şöyle bir şey yapabilirsiniz:

SELECT DISTINCT * FROM (select unnest(string_to_array('a;b;c;d;e;f;a;b;d', ';'))) AS tbl(col1)

11
Her ne kadar soru MSSQL :)
belirtiyor

@halfer Burada verilen ilk cevap MSSQL 2016 kullanarak benim için çalıştı, diğer cevaplar olmadı. 7 yıl sonra
dustytrash

9

Bu SQL Server 2005'te çalışır ve maksimum sayı varsa:

SELECT * 
FROM
  (SELECT ROW_NUMBER() OVER(ORDER BY a.id) NUMBER
  FROM syscomments a
  CROSS JOIN syscomments b) c
WHERE c.NUMBER IN (1,4,6,7,9)

2
+1 temiz ama kendisiyle birleştirilmiş çapraz sistemlerde satır sayısı ile sınırlıdır. Benim durumumda 294849. (ve farklı unuttun.)
Lieven Keersmaekers

Bir kez daha çapraz birleştirebilirsiniz, ancak virgüllerin değiştirilmesi çok daha hızlı bir çözümdür.
LukLed

Evet, bu şekilde de iyi, ama basitlik nedeniyle Lieven'in çözümünü tercih ediyorum.
Eedoh

3

Bu oldukça eski bir konu olduğunu biliyorum, ama benzer bir şey arıyordum ve bununla geldi.

Virgülle ayrılmış bir dizeniz olduğu göz önüne alındığında, string_split

select distinct value from string_split('1, 1, 1, 2, 5, 1, 6',',')

Bu geri dönmeli

1
2
5
6

Dize bölme, dize girişi ve ayırıcı karakter olmak üzere iki parametre alır.

valuesütun adı olarak kullanarak isteğe bağlı bir where ifadesi ekleyebilirsiniz

select distinct value from string_split('1, 1, 1, 2, 5, 1, 6',',')
where value > 1

üretir

2
5
6

Bu, MSSQL 2016 veya üstünü gerektiriyor gibi görünüyor: docs.microsoft.com/en-us/sql/t-sql/functions/…
Jonathan

1
@ Evet, bu SQL Server, orijinal sorunun etiketleri başına
NapkinBob

1
@Jonathan Evet, sorunun yaşı göz önüne alındığında, Orijinal postere yardımcı olmazdı, ama yaptığım gibi birinin üzerine rastlayabileceğini düşündüm ve yararlı buldum.
NapkinBob

2

Bir diziye ihtiyacınız varsa, dizi sütunlarını virgülle ayırın:

SELECT * FROM (VALUES('WOMENS'),('MENS'),('CHILDRENS')) as X([Attribute])
,(VALUES(742),(318)) AS z([StoreID])

0

Kullanabileceğiniz başka bir yol da şöyle bir sorgudur:

SELECT DISTINCT
    LTRIM(m.n.value('.[1]','varchar(8000)')) as columnName
FROM 
    (SELECT CAST('<XMLRoot><RowData>' + REPLACE(t.val,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
     FROM (SELECT '1, 1, 1, 2, 5, 1, 6') AS t(val)
    ) dt
  CROSS APPLY 
    x.nodes('/XMLRoot/RowData') m(n);

0

Kullanıcı kimliği listesinden kullanıcı kimliğini seçin:

SELECT * FROM my_table WHERE user_id IN (1,3,5,7,9,4);

-2

Benim için çalışan bir teknik, yalnızca sonucunuzdaki Row_Number alanı da dahil olmak üzere büyük miktarda kayıt bulunduğunu bildiğiniz bir tabloyu sorgulamaktır

Select Top 10000 Row_Number() OVER (Order by fieldintable) As 'recnum' From largetable

1'den 10000'e kadar bir sonuç kümesini döndürür, bunu istediğiniz sonuçları vermek için başka bir sorguda kullanın


-4

SQL Inişlevini kullanma

Bunun gibi bir şey:

SELECT * FROM mytable WHERE:
"VALUE" In (1,2,3,7,90,500)

ArcGIS'te tedavi eder


1
Bu SELECT, SQL Server ile bir sözdizimi hatası oluşturur.
JohnH
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.