Sql 过滤数据上的行号()
我正在尝试查找筛选数据上的Sql 过滤数据上的行号(),sql,rank,Sql,Rank,我正在尝试查找筛选数据上的行号()。当我在where子句中包含过滤器时,row_number按预期工作。但我试图在select case语句中设置过滤条件,但它似乎不起作用 我不想在where子句中放入筛选条件的原因是,我在同一select sql语句中有其他度量。我尝试过使用子查询方法对表进行别名处理,效果很好 但我想知道是否还有其他更好/更有效的方法来做到这一点 --working with where clause - works SELECT order_id, ROW_NUM
行号()。当我在where子句中包含过滤器时,row_number按预期工作。但我试图在select case语句中设置过滤条件,但它似乎不起作用
我不想在where子句中放入筛选条件的原因是,我在同一select sql语句中有其他度量。我尝试过使用子查询方法对表进行别名处理,效果很好
但我想知道是否还有其他更好/更有效的方法来做到这一点
--working with where clause - works
SELECT
order_id,
ROW_NUMBER() over(
PARTITION BY orderid, date_trunc('month',order_date)
ORDER BY order_date)
FROM order
WHERE order_success='yes'
--working with sub query - works
SELECT
order.order_id,
row_number() over(
PARTITION BY temp.orderid, date_trunc('month',temp.order_date)
ORDER BY temp.order_date)
FROM order
LEFT OUTER JOIN (
SELECT order_id, order_date
FROM order
WHERE order_success='yes'
) temp_order ON order.order_id=temp_order.order_id
--trying to achieve with case statement/ does not work
SELECT
order_id,
CASE WHEN order_success='yes' and ROW_NUMBER() OVER(PARTITION BY orderid, date_trunc('month',order_date) ORDER BY order_date) = 1 THEN 1 ELSE 0 END
FROM order
谢谢大家! 尝试将ROW\u NUMBER()
函数移动到子查询,并在外部查询中将其作为别名引用:
SELECT
src.order_id,
CASE
WHEN src.order_success='yes' AND src.MyWindowFunction = 1 THEN 1
ELSE 0
END
FROM (
SELECT
order_id,
order_success,
ROW_NUMBER() OVER(
PARTITION BY orderid, date_trunc('month', order_date)
ORDER BY order_date
) AS MyWindowFunction
FROM order
) src
对于特定的order\u id,当您将rownumber()作为1多次获取时,您需要一个IN子句。这就像order\u success='yes'对于order\u id的单个行一样,比如x,您将通过分区获得多行作为子组,因此行号将具有多个1,并且比较将失败
select order_id, case when
order_success='yes' and row_number()
over(partition by
orderid,date_trunc('month',order_date)
order by order_date) IN (1) then max(1)else
max(0 )
end from order
如果我理解正确,您只想在选择其他订单时对成功订单进行编号。如果是这样,您可以在分区中包含成功标志,并使用CASE-WHEN
抑制非成功行上的数字
select
order_id,
case when order_success = 'yes' then
row_number() over(partition by order_success, orderid, date_trunc('month', order_date)
order by order_date)
end as num
from order
order by order_date;
(旁注:为什么在partition子句中有orderid
?这不是订单表的唯一键吗?这取决于您是只想计算“yes”的值,还是在行没有“yes”时希望值为NULL
如果要计算“是”,则使用累积计数:
select order_id,
sum(case when order_success = 'yes' then 1 else 0 end) over (partition by orderid, date_trunc('month', order_date) order by order_date)
from order o;
这似乎比在非“是”行上设置NULL
值更有用。您似乎正在使用Postgres,因此可以简化为:
select order_id,
count(*) filter (where order_success = 'yes') over (partition by orderid, date_trunc('month', order_date) order by order_date)
from order o;
如果希望对非“是”行执行NULL
,则可以将它们中的任何一个包装在大小写表达式中。我希望计算行数()的顺序\u success=yes。但是在您发布的子查询中,排名是在子查询中没有此过滤器的情况下完成的。那么,如何正确地对它们进行排序呢?这是我创建的测试表(我应该说是customer_id,而不是order_id)。但在我的实际场景中,我有4个字段要过滤,并且只按正确的顺序排列过滤后的记录。我尝试了与您建议的类似的方法:当order_success='yes'时,然后是row_number(),而不包括分区中的filter列。您能告诉我在partition by子句中包含筛选器列的原因吗?非常感谢。可以方法是一样的:将列添加到partition子句中,并扩展case-when子句。您能告诉我在partition-by子句中包含过滤列的原因吗?我有4个字段要过滤。那么,使用case语句这样做是否比使用单独过滤的子查询更好?请告知!非常感谢。诀窍是将所有过滤的行放在一个分区中。好吧,如果它不仅仅是关于平等,比如在order\u success='yes'
,那么你甚至必须在子句中加入whle条件:当order\u success在('yes','maybe')中时按大小写划分,然后1其他2结束,
。这可能会变得麻烦。也许你的外部连接方法比我的更具可读性。我不认为一种方法比另一种好。也许更快。我不知道。只需选择一个你更喜欢的。在按列表分区中添加筛选子句后,它就可以完美地工作了。谢谢你的帮助。我同意你的方法,因为它消除了很多子查询。