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

? 表示您拥有的 identityprimary/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 的行数。

如果您的密钥有多个列,那么您将必须将 EXISTSIN 切换为多个列(您不能使用多个列 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
    )