【问题标题】:Select Row Based on Column基于列选择行
【发布时间】:2011-07-11 20:02:07
【问题描述】:

我有一个表格,其中包含如下数据:

ID Mfgr Primary_Mfgr a1 极致 P a1 Bcme S a1 Ccme S b1 极致 b1 Bcme c1 Acme S c1 Bcme d1 极致 d1 Bcme

我需要创建一个 select 语句,它将根据 ID 返回带有 P 作为 Primary_Mfgr 的记录,如果没有 P 记录,则返回空白记录,如果不存在则返回第一个 S记录。在所有情况下,如果有重复,则返回第一个结果。

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

查询 a1:

a1 极致 P

查询 b1:

b1 极致

查询 c1:

c1 Bcme

查询 d1:

d1 极致

在每种情况下,我只需要返回一条记录。我不确定我将如何构建来做到这一点。例如,我可以轻松地取回所有“a1”记录,但我不确定如何编写一个可以获取 ID 参数并在所有情况下仍返回正确的单个记录的查询。我正在使用 SQL Server 2008 R2。

【问题讨论】:

  • 您需要定义“第一”。 SQL 没有表内的顺序感。您的查询定义了排序。
  • 我并不特别关心他们返回的顺序。如果有两个“S”,只需给我首先从服务器返回的那个。如果有重复的类型,订单对我的需求变得不重要。

标签: sql sql-server tsql sql-server-2008-r2


【解决方案1】:

您可以使用 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

【讨论】:

  • 这只会返回一行。不是“每个 ID 组一行”
  • 他说“在任何情况下我只需要返回一条记录”。他提到了 4 个不同的查询。
  • 输出表明 OP 想要“每组一行”,但不知道如何。如果有 120 万个 ID,你建议 120 万个查询吗?你的 WHERE 也错了 -1
  • 太棒了;效果很好。感谢您及时的回复。我唯一改变的是 where 子句按 ID 而不是 Primary_Mfgr 过滤。
  • 是的,我弄乱了 ID。对此感到抱歉。
【解决方案2】:

这会按字母顺序(取决于排序规则等)采用“第一个”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 个查询合二为一。

【讨论】:

  • 我没有选择这个答案,因为它需要服务器做很多额外的工作,因为在每种情况下我都会在执行查询之前知道 ID,所以似乎没有分区当只返回一个 ID 时,按 ID 是有意义的。但是,我可以看到这可能对其他情况有用,所以感谢分享。
  • 我实际上确实需要每个请求只返回一行,因为这里没有包括其他一些因素。我实际上正在努力改变这个要求,如果发生这种情况,我会使用你的答案,但现在一次只能返回一行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 2018-08-24
  • 2012-01-06
  • 2021-09-18
  • 1970-01-01
相关资源
最近更新 更多