如何从SQL Server的值列表中选择


216

我有一个非常简单的问题,我无法解决。我需要做这样的事情:

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

有人可以帮忙吗?

编辑

数据来自我们的一位客户的文本文件。它是完全未格式化的(它是一行很长的文本),但是在Excel中可能是这样做的。但这对我来说并不实际,因为我将需要在sql查询中使用这些值。每次我需要运行查询时,这样做都不方便。


您要从多个表中选择还是从一个表中选择,但是要选择特定的值?像特定ID一样的东西
Anirudh Goel

不是您要问的,而是可以用另一种语言来做。例如,在PowerShell中,您可以$d = (1, 1, 1, 2, 5, 1, 6) | sort -Unique获取array中的不同值$d。易于扩展到文件到文件工具。
杰普·斯蒂格·尼尔森

在这里重要的是获取这些值的不同列表,或者将该值列表导入SQL吗?正如@JeppeStigNielsen所说,还有其他方法可以从不涉及SQL的文本列表中获取不同的值。我来这里的目的是寻找如何在引用其他表的SQL脚本中获取值列表。
瑞奇(Rikki)'18

Answers:


81

获取一长串用逗号分隔的文本唯一值的最简单方法是使用find替换为UNION来获得唯一值。

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

应用于您用逗号分隔的长行文本

  • 查找并替换每个逗号 UNION SELECT
  • SELECT在语句前面添加一个

您现在应该有一个有效的查询


3
不,不,我有一个数百个值的列表,手动操作将是一种折磨
Eedoh

该清单从何而来?只需在Excel中复制/粘贴列表并使用简单的交叉表在其中提取不同的值,可能会更容易。
Lieven Keersmaekers,

顺便说一句,查找和替换也可能会花很长时间。用union select替换每个逗号,在前面添加一个select,您应该有一个有效的查询cfr我显示的工会。
Lieven Keersmaekers,2009年

1
用选择的工会替换逗号代替这些东西就像一个魅力一样非常感谢:)
Eedoh

5
出于性能原因,我建议全部合并,然后按组合并,或者在外部选择中使用Distinct。
MikeTeeVee 2014年

426

行构造器仅在SQL Server 2008及更高版本中可用,其格式为:
您可以使用

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

许多人写道:


66
旁注:X是表名a的别名,是列名的别名;)。
shA.t 2015年

11
与当前选择的答案相比,这是更正确的答案
TabsNotSpaces

1
这是最通用的方法,我被innest(ARRAY [])宠坏了pgsql,现在又开始努力使FROM接受较小的值作为中的行记录sqlserver,这里就是。很高兴知道。

1
由于列和表的别名更好的答案
Alfredo A.18年

79

一般来说 :

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 )

在您的情况下:

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

43

您是否尝试过使用以下语法?

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

5
一位匿名用户建议将代码编辑为:SELECT DISTINCT table_name.column_name FROM (VALUES (1), (2), (3)) AS table_name(column_name)
Vogel612

19

如果您只想从单个表中选择某些值,则可以尝试此操作

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

例如:

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

如果要从多个表中进行选择,则必须进行选择UNION

如果只想选择值1、1、1、2、5、1、6,则必须这样做

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

1
我不需要从表中选择,而是从值列表中(括号中)进行选择。这就是主要问题(从逗号分隔的值数组中进行选择,而不是从表中进行选择)
Eedoh

在这种情况下,就像我们在Oracle中拥有DUAL表一样,您可以使用相同的表。但是,由于没有DUAL,所以您将必须采用联合方式。您可以尝试另一种方法,正如您提到的那样,您使用逗号分隔的值数组,为什么不将它们插入表中,然后使用整洁的sql select查询,而不是使用那么多的sql联合。
阿尼鲁德·戈尔

14

PostgreSQL为您提供了两种方法:

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

要么

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

使用数组方法,您还可以执行以下操作:

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

11
尽管该问题确实指定了MSSQL ...:)
2012年

@halfer此处给出的第一个答案对我有用,它使用MSSQL 2016,而其他答案则没有。7年后
尘土飞扬

9

这在SQL Server 2005上有效,并且如果有最大数量:

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整洁,但仅限于与自己交叉连接的syscomments中的行数。就我而言,是294849。(您忘记了与众不同。)
Lieven Keersmaekers,2009年

您可以再次交叉联接,但是替换逗号是更快的解决方案。
LukLed

是的,这种方法也很好,但是由于简单,我更喜欢Lieven的解决方案。
Eedoh

3

我知道这是一个很老的线程,但是我正在寻找类似的东西并提出了这个想法。

假设您使用逗号分隔的字符串,则可以使用 string_split

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

这应该返回

1
2
5
6

字符串拆分有两个参数,字符串输入和分隔符。

您可以添加一个可选的where语句value用作列名

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

产生

2
5
6

这似乎需要MSSQL 2016或更高版本:docs.microsoft.com/en-us/sql/t-sql/functions/…–
Jonathan

1
@Sam是的,按照原始问题的标签,这是SQL Server
NapkinBob

1
@Jonathan是的,考虑到这个问题的年代,它不会对原始海报有所帮助,但是我认为有人可能像我一样偶然发现它,并发现它会有所帮助。
NapkinBob

2

如果需要数组,请用逗号分隔数组列:

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

0

您可以使用的另一种方式是这样的查询:

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

从用户ID列表中选择用户ID:

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

-2

对我有用的一种技术是查询一个您知道其中有大量记录的表,其中仅包括结果中的Row_Number字段

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

将返回1到10000之间的10000条记录的结果集,在另一个查询中使用此结果可为您提供所需的结果


-4

使用SQL In功能

像这样:

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

在ArcGIS中工作


1
此SELECT会在SQL Server中生成语法错误。
JohnH
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.