Sql 分区值更改时的行数
我有一段sql代码,它根据一个表中的一些值查找行号,该表连接到一个查找表EvalSql 分区值更改时的行数,sql,sql-server,Sql,Sql Server,我有一段sql代码,它根据一个表中的一些值查找行号,该表连接到一个查找表Eval ;WITH r AS ( select w.uid, t.TypeId, --weight ROW_NUMBER () OVER (PARTITION BY w.uid ORDER BY DIFFERENCE(t.val1, w.val1) + DIFFERENCE(t.val2, w.val2) + DIFFERENCE(t.val3, w.val3) + DI
;WITH r
AS (
select
w.uid,
t.TypeId,
--weight
ROW_NUMBER () OVER (PARTITION BY w.uid ORDER BY DIFFERENCE(t.val1, w.val1) + DIFFERENCE(t.val2, w.val2) + DIFFERENCE(t.val3, w.val3) + DIFFERENCE(t.val4, w.val4) DESC) as Score
,w.account
from __Working w
join __eval t on w.val1 like t.val1 and IsNull(w.val4, '') like t.val4 and IsNull(w.val2, '') like t.val2 and IsNull(w.val3, '') like t.val3
)
select * from r where r.account = 1 and score = 1
这将返回一个typeId=1
但是如果我这样写的话
;WITH r
AS (
select
w.uid,
t.TypeId,
--weight
ROW_NUMBER () OVER (PARTITION BY w.uid ORDER BY DIFFERENCE(t.val1, w.val1) + DIFFERENCE(t.val2, w.val2) + DIFFERENCE(t.val3, w.val3) + DIFFERENCE(t.val4, w.val4) DESC) as Score
,w.account
from __Working w
join __eval t on w.val1 like t.val1 and IsNull(w.val4, '') like t.val4 and IsNull(w.val2, '') like t.val2 and IsNull(w.val3, '') like t.val3
where r.account = 1
)
select * from r where r.account = 1 and score = 1
它返回TypeId=2。我希望如果我有多个UID在不同的帐户中工作,但我没有。我在这里错过了什么?哦,这是一种不稳定的怪异。您的
行号()
表达式是:
ROW_NUMBER() OVER (PARTITION BY w.uid
ORDER BY DIFFERENCE(t.val1, w.val1) +
DIFFERENCE(t.val2, w.val2) +
DIFFERENCE(t.val3, w.val3) +
DIFFERENCE(t.val4, w.val4) DESC
) as Score
问题在于,多行对于ORDER BY
键具有相同的值。不同的调用可以任意选择这多行中的哪一行是第一行、第二行,依此类推
标准解决方案是包含某种类型的唯一键,以便排序是稳定的:
ROW_NUMBER() OVER (PARTITION BY w.uid
ORDER BY (DIFFERENCE(t.val1, w.val1) +
DIFFERENCE(t.val2, w.val2) +
DIFFERENCE(t.val3, w.val3) +
DIFFERENCE(t.val4, w.val4)
) DESC,
?? -- perhaps typeId
) as Score
然而,我可能会建议一个更艰巨的解决方案。接受关系可能存在的事实,并使用
rank()
和densite\u rank()
来识别它们。然后,明确地弄清楚在打领带的情况下该怎么办——也许你对所有这些都同样感兴趣,或者你有其他打破领带的方法。哦,这是一种不稳定的奇怪现象。您的行号()
表达式是:
ROW_NUMBER() OVER (PARTITION BY w.uid
ORDER BY DIFFERENCE(t.val1, w.val1) +
DIFFERENCE(t.val2, w.val2) +
DIFFERENCE(t.val3, w.val3) +
DIFFERENCE(t.val4, w.val4) DESC
) as Score
问题在于,多行对于ORDER BY
键具有相同的值。不同的调用可以任意选择这多行中的哪一行是第一行、第二行,依此类推
标准解决方案是包含某种类型的唯一键,以便排序是稳定的:
ROW_NUMBER() OVER (PARTITION BY w.uid
ORDER BY (DIFFERENCE(t.val1, w.val1) +
DIFFERENCE(t.val2, w.val2) +
DIFFERENCE(t.val3, w.val3) +
DIFFERENCE(t.val4, w.val4)
) DESC,
?? -- perhaps typeId
) as Score
然而,我可能会建议一个更艰巨的解决方案。接受关系可能存在的事实,并使用
rank()
和densite\u rank()
来识别它们。然后,明确指出在打成平局的情况下该怎么办——也许所有这些都对您同样感兴趣,或者您有其他打破平局的方法。为什么要在CTE中过滤r.account,然后再次在select中过滤?CTE内的过滤将更改您的行号()正确回答。但需要注意的一点是,差异(t.val1,NULL)将为NULL。NULL+1是NULL,因此,如果差分函数中的列中有1个可以为NULL,那么整个orderby将变为NULL。我猜你可能想做一些空处理,但不确定你的用例是的,val1是一个不可空的字段,因此不需要空检查,但感谢在CTE中对r.account进行筛选,然后再次选择int?CTE内的过滤将更改您的行号()正确回答。但需要注意的一点是,差异(t.val1,NULL)将为NULL。NULL+1是NULL,因此,如果差分函数中的列中有1个可以为NULL,那么整个orderby将变为NULL。我猜你可能想做一些空处理,但不确定你的用例是的,val1是一个不可空的字段,所以不需要空检查,但非常感谢。所以查找表的构造实际上没有关系,所以当你说的时候,我找到了答案。真正的问题是差分函数的使用,它实际上并不像我想象的那样。它根据soundex以0-4的比例对这两条弦进行评级,而我认为这会给我在字符方面的差异。我将不得不重新考虑在那里使用什么函数,或者写我自己的哦,非常感谢。所以查找表的构造实际上没有关系,所以当你说的时候,我找到了答案。真正的问题是差分函数的使用,它实际上并不像我想象的那样。它根据soundex以0-4的比例对这两条弦进行评级,而我认为这会给我在字符方面的差异。我必须重新考虑在那里使用什么函数,或者写我自己的函数