【问题标题】:How can I select from list of values in SQL Server如何从 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) 是正确答案,请更新

标签: sql-server select-query


【解决方案1】:

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

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

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

【讨论】:

  • 旁注: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 生成语法错误。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2012-05-08
                • 1970-01-01
                • 2015-09-07
                • 2021-02-09
                • 2023-03-13
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多