Sql 根据列选择行

Sql 根据列选择行,sql,sql-server,tsql,sql-server-2008-r2,Sql,Sql Server,Tsql,Sql Server 2008 R2,我有一个包含如下数据的表: ID Mfgr Primary_Mfgr a1 Acme P a1 Bcme S a1 Ccme S b1 Acme b1 Bcme c1 Acme S c1 Bcme d1 Acme d1 Bcme ID主制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商

我有一个包含如下数据的表:

ID Mfgr Primary_Mfgr a1 Acme P a1 Bcme S a1 Ccme S b1 Acme b1 Bcme c1 Acme S c1 Bcme d1 Acme d1 Bcme ID主制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商制造商 a1顶点P a1 Bcme S a1 Ccme S b1顶点 b1 Bcme c1顶点S c1 Bcme d1顶点 d1 Bcme < P>我需要创建一个SELECT语句,它将基于ID返回以P作为PrimaRyMFGR的记录,如果没有P记录,则返回空白记录,如果不存在,则返回第一个S记录。在所有情况下,如果存在重复项,则返回第一个结果

因此,使用上述数据,我希望从四个不同的查询中返回以下内容:

查询a1:

a1 Acme P a1顶点P 查询b1:

b1 Acme b1顶点 查询c1:

c1 Bcme c1 Bcme 查询首被告:

d1 Acme d1顶点
在每种情况下,我只需要返回一条记录。我不知道我该如何做。例如,我可以很容易地获取所有“a1”记录,但我不确定如何编写一个查询,以获取ID参数,并在所有情况下仍然返回正确的单个记录。我使用的是SQL Server 2008 R2。

您只需按带有case语句的Primary_Mfgr列排序,然后选择前1个

SELECT TOP 1 *
FROM Table1
WHERE ID = @ID
ORDER BY 
    CASE Primary_Mfgr 
        WHEN 'P' THEN 1
        WHEN ''  THEN 2
        ELSE 3
    END

您只需使用case语句按Primary_Mfgr列排序,然后选择前1个

SELECT TOP 1 *
FROM Table1
WHERE ID = @ID
ORDER BY 
    CASE Primary_Mfgr 
        WHEN 'P' THEN 1
        WHEN ''  THEN 2
        ELSE 3
    END
这采用字母顺序排列的“第一个”Mfgr(根据排序规则等),其中给定ID/Primary_Mfgr对有多个。否则,您可以将二级排序更改为另一列(如果您有一列),或者将其保留以获取随机记录

;WITH myCTE AS
(
    SELECT
       *,
       ROW_NUMBER() OVER (
               PARTITION BY ID
               ORDER BY
                  CASE Primary_Mfgr 
                     WHEN 'P' THEN 1 WHEN 'S' THEN 3 ELSE 2
                  END, Mfgr) AS rn
    FROM
       MyTable
)
SELECT *
FROM myCTE
WHERE rn = 1
编辑:您不必为每个ID查询一次,这很愚蠢:这个答案可以一次性为所有ID查询一次。因此,上述4个查询将成为一个查询。

这将按字母顺序选择“第一个”Mfgr(根据排序规则等),其中给定ID/主\u Mfgr对有多个查询。否则,您可以将二级排序更改为另一列(如果您有一列),或者将其保留以获取随机记录

;WITH myCTE AS
(
    SELECT
       *,
       ROW_NUMBER() OVER (
               PARTITION BY ID
               ORDER BY
                  CASE Primary_Mfgr 
                     WHEN 'P' THEN 1 WHEN 'S' THEN 3 ELSE 2
                  END, Mfgr) AS rn
    FROM
       MyTable
)
SELECT *
FROM myCTE
WHERE rn = 1

编辑:您不必为每个ID查询一次,这很愚蠢:这个答案可以一次性为所有ID查询一次。因此,上面的4个查询变成一个。

您需要定义“第一个”。SQL没有在表中排序的感觉。您的查询定义了顺序。这让我想起:我并不特别关心它们返回的顺序。如果有两个a,只需给我一个从服务器返回的a。如果存在重复的类型,则顺序对于我的需求来说就不重要了。您需要定义“第一”。SQL没有在表中排序的感觉。您的查询定义了顺序。这让我想起:我并不特别关心它们返回的顺序。如果有两个a,只需给我一个从服务器返回的a。如果存在重复类型,则订单对于我的需求将变得不重要。这将只返回一行。不是“每个ID组一行”,他说“在每种情况下,我只需要返回一条记录”。他提到了4个不同的查询。结果表明OP想要“每组一行”,但不知道如何进行。如果有120万个ID,您建议120万个查询吗?你的哪里也错了——1我们是有的;这很有效。谢谢你的快速回复。我唯一更改的是where子句,它是按ID过滤的,而不是按Primary_Mfgr。是的,我弄乱了ID。很抱歉,这将只返回一行。不是“每个ID组一行”,他说“在每种情况下,我只需要返回一条记录”。他提到了4个不同的查询。结果表明OP想要“每组一行”,但不知道如何进行。如果有120万个ID,您建议120万个查询吗?你的哪里也错了——1我们是有的;这很有效。谢谢你的快速回复。我唯一更改的是where子句,它是按ID过滤的,而不是按Primary_Mfgr过滤的。是的,我弄错了ID。很抱歉,我没有选择这个答案,因为它需要服务器做很多额外的工作,而在任何情况下,我都会在执行查询之前知道ID,因此,当只返回一个ID时,按ID进行分区似乎没有意义。不过,我可以看出这对其他情况可能有多大的帮助,所以感谢您的分享。由于一些其他因素,我实际上只需要在每个请求中返回一行,我在这里没有包括这些因素。实际上,我正在努力更改该要求,如果发生这种情况,我将使用您的答案,但现在一次只能返回一行。我没有选择此答案,因为它需要对服务器进行大量额外的工作,而在任何情况下,我都会在执行查询之前知道ID,因此,当只返回一个ID时,按ID进行分区似乎没有意义。不过,我可以看出这对其他情况可能有多大的帮助,所以感谢您的分享。由于一些其他因素,我实际上只需要在每个请求中返回一行,我在这里没有包括这些因素。事实上,我正在努力改变这个要求,如果发生这种情况,我将使用你的答案,但现在一次只能返回一行。