Bri*_*pie 3 sql database sql-server-2000
(我希望我能想出一个更具描述性的标题...如果你可以命名我询问的查询类型,建议一个或编辑这篇文章)
数据库:SQL Server 2000
样本数据(假设500,000行):
Name Candy PreferenceFactor Jim Chocolate 1.0 Brad Lemon Drop .9 Brad Chocolate .1 Chris Chocolate .5 Chris Candy Cane .5 499,995 more rows...
请注意,具有给定"名称"的行数是无限的.
期望的查询结果:
Jim Chocolate 1.0 Brad Lemon Drop .9 Chris Chocolate .5 ~250,000 more rows...
(由于克里斯对糖果手杖和巧克力同样偏爱,因此一致的结果就足够了).
问题: 如何从数据中选择名称,糖果,其中每个结果行包含唯一的名称,以便所选择的糖果具有每个名称的最高PreferenceFactor.(快速有效的答案首选).
桌子上需要什么索引?如果Name和Candy是另一个表的整数索引(除了需要一些连接)之外,它会有所不同吗?
您将发现以下查询优于给出的每个其他答案,因为它适用于单次扫描.这模拟了MS Access的First和Last聚合函数,这基本上就是你正在做的事情.
当然,你可能在CandyPreference表中有外键而不是名字.要回答你的问题,如果Candy和Name是另一个表中的外键,那么事实上是非常好的.
如果CandyPreferences表中有其他列,那么具有包含所涉及列的覆盖索引将产生更好的性能.使列尽可能小会增加每页的行数并再次提高性能.如果您经常使用WHERE条件进行查询以限制行,则覆盖WHERE条件的索引变得很重要.
彼得在这方面做得很好,但有一些不必要的复杂性.
CREATE TABLE #CandyPreference (
[Name] varchar(20),
Candy varchar(30),
PreferenceFactor decimal(11, 10)
)
INSERT #CandyPreference VALUES ('Jim', 'Chocolate', 1.0)
INSERT #CandyPreference VALUES ('Brad', 'Lemon Drop', .9)
INSERT #CandyPreference VALUES ('Brad', 'Chocolate', .1)
INSERT #CandyPreference VALUES ('Chris', 'Chocolate', .5)
INSERT #CandyPreference VALUES ('Chris', 'Candy Cane', .5)
SELECT
[Name],
Candy = Substring(PackedData, 13, 30),
PreferenceFactor = Convert(decimal(11,10), Left(PackedData, 12))
FROM (
SELECT
[Name],
PackedData = Max(Convert(char(12), PreferenceFactor) + Candy)
FROM CandyPreference
GROUP BY [Name]
) X
DROP TABLE #CandyPreference
Run Code Online (Sandbox Code Playgroud)
除非性能至关重要,否则我实际上不推荐这种方法.执行它的"规范"方法是OrbMan的标准Max/GROUP BY派生表,然后连接到它以获取所选行.但是,当有多个列参与选择Max时,该方法开始变得困难,并且可以复制选择器的最终组合,也就是说,当没有列提供任意唯一性时,如此处的情况如果PreferenceFactor相同,我们使用名称.
编辑:最好提供一些更多的使用说明,以帮助提高清晰度,并帮助人们避免问题.