Bagaimana saya bisa memilih dari daftar nilai dalam SQL Server

216

Saya memiliki masalah yang sangat sederhana yang tidak dapat saya pecahkan. Saya perlu melakukan sesuatu seperti ini:

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

Adakah yang bisa membantu ??

Edit

Data datang sebagai file teks dari salah satu klien kami. Ini benar-benar tidak diformat (ini adalah satu baris teks yang sangat panjang), tetapi dimungkinkan untuk melakukannya di Excel. Tapi itu tidak praktis bagi saya, karena saya perlu menggunakan nilai-nilai ini dalam kueri sql saya. Tidak nyaman melakukannya setiap kali saya perlu menjalankan kueri.

Eedoh
sumber
Anda ingin memilih dari beberapa tabel atau memilih dari satu tabel tetapi memiliki nilai tertentu untuk dipilih? beberapa hal seperti id tertentu saja
Anirudh Goel
Bukan apa yang Anda minta, tetapi Anda bisa melakukannya dalam bahasa lain. Misalnya di PowerShell, Anda bisa lakukan $d = (1, 1, 1, 2, 5, 1, 6) | sort -Uniqueuntuk mendapatkan nilai berbeda dalam sebuah array $d. Mudah diperluas ke alat file-ke-file.
Jeppe Stig Nielsen
Apakah yang penting di sini untuk mendapatkan daftar nilai-nilai yang berbeda, atau untuk memasukkan daftar nilai-nilai itu ke dalam SQL? Seperti yang dikatakan @JeppeStigNielsen, ada cara lain untuk mendapatkan nilai berbeda dari daftar teks yang tidak melibatkan SQL. Saya datang ke sini mencari cara untuk mendapatkan daftar nilai ke dalam skrip SQL yang merujuk tabel lain.
Rikki

Jawaban:

81

Cara paling sederhana untuk mendapatkan nilai-nilai yang berbeda dari daftar panjang teks yang dibatasi koma adalah dengan menggunakan menemukan ganti dengan UNION untuk mendapatkan nilai-nilai yang berbeda.

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

Diterapkan pada baris panjang teks terbatas koma Anda

  • Temukan dan ganti setiap koma dengan UNION SELECT
  • Tambahkan SELECTdi depan pernyataan

Anda sekarang harus memiliki kueri yang berfungsi

Letnan Keersmaekers
sumber
3
tidak, tidak, saya punya daftar beberapa ratusan nilai, secara manual itu akan menjadi siksaan
Eedoh
dari mana daftar itu berasal? Mungkin lebih mudah untuk hanya menyalin / menempelkan daftar itu di Excel dan mengekstrak nilai berbeda di sana menggunakan tab silang sederhana.
Lieven Keersmaekers
btw, cari dan ganti mungkin juga akan membawa Anda jauh. Ganti setiap koma dengan serikat pilih , tambahkan pilih di depan dan Anda harus memiliki kueri yang berfungsi cfr serikat saya tunjukkan.
Lieven Keersmaekers
1
hal ini dengan mengganti koma dengan pilih serikat bekerja seperti pesona Terima kasih banyak :)
Eedoh
5
Untuk alasan kinerja, saya akan merekomendasikan Union-All, lalu Group-By atau gunakan Distinct di bagian luar pilihan Anda.
MikeTeeVee
427

Hanya tersedia di SQL Server 2008 dan lebih adalah baris-konstruktor dalam formulir ini:
Anda bisa menggunakan

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

Banyak yang menulis, di antaranya:

sore.
sumber
66
Catatan sisi: Xadalah alias untuk nama tabel dan aalias untuk nama kolom;).
shA.t
11
Ini adalah jawaban yang lebih benar dibandingkan dengan yang saat ini dipilih
TabsNotSpaces
1
Ini adalah cara yang paling umum, saya dimanjakan oleh undest (ARRAY []) di pgsqldan sekarang membenturkan kepala untuk membuat FROM menerima nilai-nilai kecil sebagai catatan baris sqlserver, dan ini dia. Senang tahu
Ben
1
Jawaban yang lebih baik karena kolom dan tabel alias
Alfredo A.
79

Secara umum :

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 )

Dalam kasus Anda:

Select 
  distinct
  TempTableName.Field1 
From 
  (
  VALUES
    (1), 
    (1), 
    (1), 
    (2), 
    (5), 
    (1), 
    (6)
  ) AS TempTableName (Field1)
Ardalan Shahgholi
sumber
Saya tahu "pilih *" dianggap sebagai bentuk yang buruk, tetapi apakah ada alasan untuk tidak menggunakan pilih * dalam kasus ini? Karena itu duplikasi FieldName1, FieldName2, ..., FieldNameN adalah aneh.
Pxtl
43

Sudahkah Anda mencoba menggunakan sintaks berikut?

select * from (values (1), (2), (3), (4), (5)) numbers(number)
Robba
sumber
5
seorang pengguna anonim menyarankan untuk mengedit kode ke:SELECT DISTINCT table_name.column_name FROM (VALUES (1), (2), (3)) AS table_name(column_name)
Vogel612
19

Jika Anda ingin memilih hanya nilai-nilai tertentu dari satu tabel, Anda dapat mencoba ini

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

misalnya:

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

jika Anda ingin memilih dari beberapa tabel maka Anda harus memilih UNION.

Jika Anda hanya ingin memilih nilai 1, 1, 1, 2, 5, 1, 6 maka Anda harus melakukan ini

select 1 
union select 1 
union select 1 
union select 2 
union select 5 
union select 1 
union select 6
Anirudh Goel
sumber
1
Saya tidak perlu memilih dari tabel, tetapi dari daftar nilai ini (dalam kurung). Itulah masalah utama (memilih dari array nilai yang dipisahkan koma, bukan dari tabel)
Eedoh
kasus itu, seperti kita memiliki tabel DUAL di Oracle, Anda dapat menggunakan yang sama. Tetapi karena tidak ada DUAL maka Anda harus pergi dengan cara serikat. Anda dapat mencoba metode lain, seperti yang Anda sebutkan, Anda memiliki array nilai yang dipisahkan koma, mengapa Anda tidak memasukkannya ke tabel dan kemudian menggunakan kueri pemilihan sql yang rapi, alih-alih menggunakan begitu banyak serikat sql.
Anirudh Goel
14

PostgreSQL memberi Anda 2 cara untuk melakukan ini:

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

atau

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

menggunakan pendekatan array Anda juga dapat melakukan sesuatu seperti ini:

SELECT DISTINCT * FROM (select unnest(string_to_array('a;b;c;d;e;f;a;b;d', ';'))) AS tbl(col1)
Arek
sumber
11
Meskipun pertanyaannya tidak menentukan MSSQL ...:)
halfer
@halfer Jawaban pertama yang diberikan di sini bekerja untuk saya, menggunakan MSSQL 2016 sedangkan jawaban lainnya tidak. 7 tahun kemudian
dustytrash
9

Ini berfungsi pada SQL Server 2005 dan jika ada angka maksimal:

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)
LukLed
sumber
2
+1 rapi tetapi terbatas pada jumlah baris dalam syscomments yang disatukan dengan sendirinya. Dalam kasus saya ke 294849. (dan Anda lupa berbeda).
Lieven Keersmaekers
Anda dapat bergabung sekali lagi, tetapi mengganti koma adalah solusi yang jauh lebih cepat.
LukLed
Ya, cara ini juga bagus, tapi aku lebih suka solusi Lieven, karena kesederhanaan.
Eedoh
3

Saya tahu ini adalah utas yang cukup lama, tetapi saya sedang mencari sesuatu yang serupa dan muncul dengan ini.

Karena Anda memiliki string yang dipisahkan koma, Anda dapat menggunakannya string_split

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

Ini harus kembali

1
2
5
6

Pemisahan string membutuhkan dua parameter, input string, dan karakter pemisah.

Anda dapat menambahkan pernyataan opsional tempat menggunakan valuesebagai nama kolom

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

menghasilkan

2
5
6
NapkinBob
sumber
Ini tampaknya memerlukan MSSQL 2016 atau lebih baru: docs.microsoft.com/en-us/sql/t-sql/functions/…
Jonathan
1
@ Sam Ya, ini SQL Server, sesuai tag pertanyaan asli
NapkinBob
1
@ Jonathan Ya, mengingat usia pertanyaan, Itu tidak akan membantu poster asli, tapi saya pikir seseorang mungkin tersandung, seperti yang saya lakukan, dan merasa itu membantu.
NapkinBob
2

Jika Anda membutuhkan array, pisahkan kolom array dengan koma:

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

Cara lain yang dapat Anda gunakan adalah kueri seperti ini:

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);
shA.t
sumber
0

Pilih id pengguna dari daftar id pengguna:

SELECT * FROM my_table WHERE user_id IN (1,3,5,7,9,4);
Biplob Das
sumber
-2

Teknik yang berhasil bagi saya adalah dengan menanyakan tabel yang Anda tahu memiliki banyak catatan di dalamnya, termasuk hanya bidang Row_Number di hasil Anda

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

akan mengembalikan set hasil 10.000 rekaman dari 1 hingga 10.000, gunakan ini dalam kueri lain untuk memberi Anda hasil yang diinginkan

Jwalter
sumber
-4

Gunakan Infungsi SQL

Sesuatu seperti ini:

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

Berhasil di ArcGIS

pengguna3059384
sumber
1
SELECT ini menghasilkan kesalahan sintaksis dengan SQL Server.
JohnH