如何从 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 个不同的值?