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

Posted

技术标签:

【中文标题】如何从 SQL Server 中的值列表中进行选择【英文标题】:How can I select from list of values in SQL Server 【发布时间】:2010-12-06 14:28:03 【问题描述】:

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

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

有人可以帮忙吗??

编辑

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

【问题讨论】:

您是要从多个表中选择还是从单个表中选择但要选择特定值?诸如特定ID之类的东西 不是你要求的,但你可以用另一种语言来做。例如,在 PowerShell 中,您可以执行 $d = (1, 1, 1, 2, 5, 1, 6) | sort -Unique 来获取数组 $d 中的不同值。易于扩展为文件到文件工具。 重要的是获得这些值的不同列表,还是将该值列表放入 SQL 中?正如@JeppeStigNielsen 所说,还有其他方法可以从不涉及 SQL 的文本列表中获取不同的值。我来这里是为了寻找如何将值列表放入引用其他表的 SQL 脚本中。 VALUES ( (1), (2), (3) ) AS X(Value) 是正确答案,请更新 【参考方案1】:

仅适用于 SQL Server 2008 及更高版本的行构造函数采用以下形式: 你可以使用

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

欲了解更多信息,请参阅:

MS official http://www.sql-server-helper.com/sql-server-2008/row-value-constructor-as-derived-table.aspx

【讨论】:

旁注:X 是表名的别名,a 是列名的别名;)。 与当前选择的答案相比,这是更正确的答案 这是最通用的方式,我被pgsql 中的 unnest(ARRAY[]) 宠坏了,现在我拼命让 FROM 接受较小的值作为sqlserver 中的行记录,在这里是。很高兴知道。 由于列和表别名而得到更好的答案【参考方案2】:

一般:

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)

【讨论】:

我知道 "select *" 被认为是错误的形式,但是在这种情况下有什么理由不使用 select * 吗?因为 FieldName1、FieldName2、...、FieldNameN 的重复很奇怪。 @Pxtl 没有理由不使用“Select *”。我已经重写了这些字段的名称以更清楚。此外,您可能不需要“Distinct”关键字。【参考方案3】:

获取一长串逗号分隔文本的不同值的最简单方法是使用 UNION 的查找替换来获取不同的值。

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

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

查找每个逗号并将其替换为UNION SELECT 在声明前添加SELECT

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

【讨论】:

不,不,我有几百个值的列表,手动会很折磨 该列表从何而来?在 Excel 中复制/粘贴该列表并使用简单的交叉表在其中提取不同的值可能会更容易。 顺便说一句,查找和替换也可能会带您走很长一段路。用 union select 替换每个逗号,在前面添加一个 select,你应该有一个工作查询 cfr 我显示的联合。 这个用选择联合替换逗号的东西就像一个魅力非常感谢:) 出于性能原因,我推荐 Union-All,然后 Group-By 或在外部选择中使用 Distinct。【参考方案4】:

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

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

【讨论】:

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

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)

【讨论】:

虽然问题确实指定了MSSQL...:) @halfer 这里给出的第一个答案对我有用,使用 MSSQL 2016,而其他答案没有。 7年后【参考方案6】:

如果你只想从一个表中选择某些值,你可以试试这个

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

【讨论】:

我不需要从表中选择,而是从这个值列表中选择(在括号中)。这是主要问题(从逗号分隔的值数组中选择,而不是从表中选择) 那种情况,就像我们在Oracle中有DUAL表一样,你可以使用相同的。但既然没有 DUAL,那么你将不得不走联合之路。您可以尝试另一种方法,正如您提到的,您有逗号分隔的值数组,为什么不将它们插入到表中,然后使用简洁的 sql 选择查询,而不是使用这么多 sql 联合。【参考方案7】:

这适用于 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)

【讨论】:

+1 整洁,但仅限于 syscmets 中与其自身交叉连接的行数。在我的情况下为 294849。(你忘了区分。) 您可以再次交叉连接,但替换逗号是更快的解决方案。 是的,这种方式也不错,但我更喜欢 Lieven 的解决方案,因为它简单。【参考方案8】:

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

鉴于您有一个逗号分隔的字符串,您可以使用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/… @Sam 是的,这是 SQL Server,根据原始问题的标签 @Jonathan 是的,考虑到问题的年龄,这对原始海报没有帮助,但我想有人可能会像我一样偶然发现它,并发现它很有帮助。【参考方案9】:

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

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

【讨论】:

【参考方案10】:

使用GROUP BY 提供比DISTINCT 更好的性能:

SELECT *
FROM
(
    VALUES
        (1),
        (1),
        (1),
        (2),
        (5),
        (1),
        (6)
) AS A (nums)
GROUP BY A.nums;

【讨论】:

【参考方案11】:

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

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

【讨论】:

【参考方案12】:

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

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);

【讨论】:

【参考方案13】:

如果是现有SQL表的参数列表,例如现有Table1的ID列表,那么你可以试试这个:

select distinct ID
      FROM Table1
      where 
      ID in (1, 1, 1, 2, 5, 1, 6)
ORDER BY ID;

或者,如果您需要将参数列表作为 SQL 表常量(变量),请尝试以下操作:

WITH Id_list AS (
     select ID
      FROM Table1
      where 
      ID in (1, 1, 1, 2, 5, 1, 6)
)
SELECT distinct * FROM Id_list
ORDER BY ID;

【讨论】:

【参考方案14】:

我在我工作的大多数 SQL DB 上创建了一个函数来执行此操作。

CREATE OR ALTER FUNCTION [dbo].[UTIL_SplitList](@parList Varchar(MAX),@splitChar Varchar(1)=',') 
  Returns @t table (Column_Value varchar(MAX))
  as
  Begin
    Declare @pos integer 
    set @pos = CharIndex(@splitChar, @parList)
    while @pos > 0
    Begin
      Insert Into @t (Column_Value) VALUES (Left(@parList, @pos-1))
      set @parList = Right(@parList, Len(@parList) - @pos)
      set @pos = CharIndex(@splitChar, @parList)
    End
    Insert Into @t (Column_Value) VALUES (@parList)
    Return
  End

函数一旦存在,就这么简单

SELECT DISTINCT 
    *
FROM 
    [dbo].[UTIL_SplitList]('1,1,1,2,5,1,6',',') 

【讨论】:

【参考方案15】:

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

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

将返回一个包含从 1 到 10000 的 10000 条记录的结果集,在另一个查询中使用它可以为您提供所需的结果

【讨论】:

【参考方案16】:

使用 SQL In 函数

类似这样的:

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

在 ArcGIS 中工作是一种享受

【讨论】:

此 SELECT 使用 SQL Server 生成语法错误。

以上是关于如何从 SQL Server 中的值列表中进行选择的主要内容,如果未能解决你的问题,请参考以下文章

如何从 SQL Server 中包含多行数据的 2 个表中选择 4 个不同的值?

如何从 Oracle 中的值列表中进行选择

T-SQL:如何在值列表中选择不在表中的值?

SQL Server 2005 中的逗号分隔值插入

从一个表中选择一个逗号分隔的值,并使用 SQL Server 中的函数在另一个表中的 where 条件中使用它

如何从sql server中的表中查询json数组类型列的值?