SQL server 2016 仅限于 where 语句时获得不同的结果
SQL server 2016 Getting distinct results when only limited to a where statement
我正在从我的 table 中寻找 CUSTOMER_NAME 字段的不同列表。通常我会简单地做
SELECT
distinct
[CUSTOMER_NAME]
FROM [iData3].[dbo].[N241650]
或
SELECT
[CUSTOMER_NAME]
FROM [iData3].[dbo].[N241650]
Group by [CUSTOMER_NAME]
但我的查询有限。由于软件限制,查询只能是
形式
SELECT * from
[iData3].[dbo].[N241650]
where ...
鉴于这些限制,我如何获得不同的客户名称列表?我基本上需要将所有内容都塞进 WHERE 子句中。我在想可能存在或不存在的地方,但我以前没有使用过这些条件,所以我不确定它们是否有用。
这是不可能的,因为...如果答案令人失望,则接受table。
每一行都需要一些独特的东西。如果你有,你可以使用:
SELECT CUSTOMER_NAME
FROM [iData3].[dbo].[N241650]
WHERE pk = (SELECT MIN(n2.pk)
FROM [iData3].[dbo].[N241650] n2
WHERE n2.CUSTOMER_NAME = N241650.N241650
);
pk
是唯一列。
您可以使用row_number()
函数:
SELECT TOP (1) WITH TIES [CUSTOMER_NAME]
FROM [iData3].[dbo].[N241650]
ORDER BY ROW_NUMBER() OVER (PARTITION BY CUSTOMER_NAME ORDER BY ?)
?
表示您拥有的 identity 或 primary/unique 列。
您可以按该列分组以获得相同的结果。
select CUSTOMER_NAME
from ...
group by CUSTOMER_NAME
order by CUSTOMER_NAME;
另一种方法是使用存储过程。
如果你不能从 *
中逃脱,那么你也不能 GROUP BY
,如果你只有一个 WHERE
,那么你将需要一把钥匙(独特的一组列)以便能够正确过滤,否则您无法区分重复项(并最终选择超过 1 行具有相同客户名称)。
有点复杂,但试试这个。每个 CUSTOMER_NAME
.
都会得到 1 行
SELECT
*
from
[iData3].[dbo].[N241650]
where
[N241650].KeyColumn IN
(
SELECT
Z.KeyColumn
FROM
(
SELECT
X.KeyColumn,
Ranking = ROW_NUMBER() OVER (PARTITION BY X.CUSTOMER_NAME ORDER BY X.KeyColumn ASC)
FROM
[iData3].[dbo].[N241650] AS X
WHERE
X.KeyColumn IS NOT NULL
) AS Z
WHERE
Z.Ranking = 1
)
OVER
内的 ORDER BY
将决定每个 CUSTOMER_NAME
的行数。
如果您的密钥有多个列,那么您将必须将 EXISTS
的 IN
切换为多个列(您不能使用多个列 IN
在 SQL 服务器中)。
SELECT
*
from
[iData3].[dbo].[N241650]
where
EXISTS (
SELECT
'key columns match'
FROM (
SELECT
X.KeyColumn1,
X.KeyColumn2,
Ranking = ROW_NUMBER() OVER (PARTITION BY X.CUSTOMER_NAME ORDER BY X.KeyColumn1 ASC)
FROM
[iData3].[dbo].[N241650] AS X
) AS Z
WHERE
Z.Ranking = 1 AND
[N241650].KeyColumn1 = Z.KeyColumn1 AND
[N241650].KeyColumn2 = Z.KeyColumn2
)
我正在从我的 table 中寻找 CUSTOMER_NAME 字段的不同列表。通常我会简单地做
SELECT
distinct
[CUSTOMER_NAME]
FROM [iData3].[dbo].[N241650]
或
SELECT
[CUSTOMER_NAME]
FROM [iData3].[dbo].[N241650]
Group by [CUSTOMER_NAME]
但我的查询有限。由于软件限制,查询只能是
形式SELECT * from
[iData3].[dbo].[N241650]
where ...
鉴于这些限制,我如何获得不同的客户名称列表?我基本上需要将所有内容都塞进 WHERE 子句中。我在想可能存在或不存在的地方,但我以前没有使用过这些条件,所以我不确定它们是否有用。
这是不可能的,因为...如果答案令人失望,则接受table。
每一行都需要一些独特的东西。如果你有,你可以使用:
SELECT CUSTOMER_NAME
FROM [iData3].[dbo].[N241650]
WHERE pk = (SELECT MIN(n2.pk)
FROM [iData3].[dbo].[N241650] n2
WHERE n2.CUSTOMER_NAME = N241650.N241650
);
pk
是唯一列。
您可以使用row_number()
函数:
SELECT TOP (1) WITH TIES [CUSTOMER_NAME]
FROM [iData3].[dbo].[N241650]
ORDER BY ROW_NUMBER() OVER (PARTITION BY CUSTOMER_NAME ORDER BY ?)
?
表示您拥有的 identity 或 primary/unique 列。
您可以按该列分组以获得相同的结果。
select CUSTOMER_NAME
from ...
group by CUSTOMER_NAME
order by CUSTOMER_NAME;
另一种方法是使用存储过程。
如果你不能从 *
中逃脱,那么你也不能 GROUP BY
,如果你只有一个 WHERE
,那么你将需要一把钥匙(独特的一组列)以便能够正确过滤,否则您无法区分重复项(并最终选择超过 1 行具有相同客户名称)。
有点复杂,但试试这个。每个 CUSTOMER_NAME
.
SELECT
*
from
[iData3].[dbo].[N241650]
where
[N241650].KeyColumn IN
(
SELECT
Z.KeyColumn
FROM
(
SELECT
X.KeyColumn,
Ranking = ROW_NUMBER() OVER (PARTITION BY X.CUSTOMER_NAME ORDER BY X.KeyColumn ASC)
FROM
[iData3].[dbo].[N241650] AS X
WHERE
X.KeyColumn IS NOT NULL
) AS Z
WHERE
Z.Ranking = 1
)
OVER
内的 ORDER BY
将决定每个 CUSTOMER_NAME
的行数。
如果您的密钥有多个列,那么您将必须将 EXISTS
的 IN
切换为多个列(您不能使用多个列 IN
在 SQL 服务器中)。
SELECT
*
from
[iData3].[dbo].[N241650]
where
EXISTS (
SELECT
'key columns match'
FROM (
SELECT
X.KeyColumn1,
X.KeyColumn2,
Ranking = ROW_NUMBER() OVER (PARTITION BY X.CUSTOMER_NAME ORDER BY X.KeyColumn1 ASC)
FROM
[iData3].[dbo].[N241650] AS X
) AS Z
WHERE
Z.Ranking = 1 AND
[N241650].KeyColumn1 = Z.KeyColumn1 AND
[N241650].KeyColumn2 = Z.KeyColumn2
)