首页 > 解决方案 > 如何在查询中获取列出现的索引?

问题描述

我正在尝试获取数据集中出现的列的索引/行号以产生类似以下的结果:

| Make        | Model    | Option    | Model Index |
├-------------+----------+-----------+-------------┤
| Lamborghini | Diablo   | SE30 Jota | 1           |
| Lamborghini | Diablo   | SE30      | 1           |
| Lamborghini | Cala     |           | 2           |
| Pontiac     | Trans AM | GTA       | 1           |
| Pontiac     | Trans AM | Firefox   | 1           |
| Pontiac     | GTO      | Judge     | 2           |
| Pontiac     | Fiero    | GT        | 3           |

请注意,型号索引应针对具有不同选项的相同品牌和型号的汽车重复,但在品牌更改时也应重置。我已经设法找到 SQL 来重置进行更改,但是一旦我包含选项列,我就会得到错误的结果。

SELECT
    Makes.Name,
    Models.Name,
    Options.Name,
    ROW_NUMBER() OVER (PARTITION BY Makes.Id ORDER BY Models.Name) [Model Index]
FROM 
    Makes
INNER JOIN  
    Models ON Models.MakeId = Makes.Id
INNER JOIN 
    Options ON Options.ModelId = Models.Id

此 SQL 的结果(不需要):

| Make        | Model    | Option    | Model Index |
├-------------+----------+-----------+-------------┤
| Lamborghini | Diablo   | SE30 Jota | 1           |
| Lamborghini | Diablo   | SE30      | 2           |
| Lamborghini | Cala     |           | 3           |
| Pontiac     | Trans AM | GTA       | 1           |
| Pontiac     | Trans AM | Firefox   | 2           |
| Pontiac     | GTO      | Judge     | 3           |
| Pontiac     | Fiero    | GT        | 4           |

也许我在这里的错误是我ROW_NUMBER在查询中使用并且我认为行号不能在给定分区内重复。我想我需要SomethingElse(PerhapsSomeReferenceToModel) OVER (PARTITION BY Makes.Id ORDER BY Models.Name)但不知道SomethingElse(PerhapsSomeReferenceToModel)实际上应该是什么!

标签: sqlsql-servertsqlrow-number

解决方案


让我重新表述您的要求:

  • 进行更改时重置模型索引
  • 相同型号的型号索引重复

如果模型索引不能包含间隙,则需要RANK()代替:ROW_NUMBER()DENSE_RANK()

SELECT
    *,
    RANK() OVER (PARTITION BY Make ORDER BY Model) AS [Model Index],
    DENSE_RANK() OVER (PARTITION BY Make ORDER BY Model) AS [Model Index DENSE]
FROM @t
ORDER BY Make, Model

DB小提琴

(上面的示例分区和按名称排序。在实践中,您实际上会执行类似的操作PARTITION BY MakeID ORDER BY ModelID)。


推荐阅读