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结束,
。这可能会变得麻烦。也许你的外部连接方法比我的更具可读性。我不认为一种方法比另一种好。也许更快。我不知道。只需选择一个你更喜欢的。在按列表分区中添加筛选子句后,它就可以完美地工作了。谢谢你的帮助。我同意你的方法,因为它消除了很多子查询。