Row_number() 过滤后的数据
Row_number() on filtered data
我正在尝试在过滤后的数据中查找 row_number()
。当我在 where 子句中包含过滤器时,row_number 会按预期工作。但是我试图在 select case 语句中添加过滤条件,但它似乎不起作用。
我不想将过滤条件放在where子句中的原因是我在同一个select sql语句中还有其他指标。我尝试使用别名 table 的子查询方法并且它有效。
但我想知道是否还有其他 better/efficient 方法可以做到这一点。
--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_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
您需要一个 IN 子句,因为您多次获得 rownumber() 作为特定 order_id 的 1。它就像同时 order_success='yes' 对于 order_id 的单行说 x 你将通过分区获得多行作为子组因此 rownumbers 将有多个 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;
(旁注:为什么分区子句中有orderid
?这不是订单table的唯一键吗?)
这取决于您是只想计算 "yes" 还是在行没有 "yes".
时希望值为 NULL
如果要统计"yes"秒,则使用累计计数:
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;
这似乎比在非 "yes" 行上设置 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;
如果你想在非 "yes" 行上 NULL
,你可以将其中任何一个包裹在 case
表达式中。
我正在尝试在过滤后的数据中查找 row_number()
。当我在 where 子句中包含过滤器时,row_number 会按预期工作。但是我试图在 select case 语句中添加过滤条件,但它似乎不起作用。
我不想将过滤条件放在where子句中的原因是我在同一个select sql语句中还有其他指标。我尝试使用别名 table 的子查询方法并且它有效。
但我想知道是否还有其他 better/efficient 方法可以做到这一点。
--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_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
您需要一个 IN 子句,因为您多次获得 rownumber() 作为特定 order_id 的 1。它就像同时 order_success='yes' 对于 order_id 的单行说 x 你将通过分区获得多行作为子组因此 rownumbers 将有多个 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;
(旁注:为什么分区子句中有orderid
?这不是订单table的唯一键吗?)
这取决于您是只想计算 "yes" 还是在行没有 "yes".
时希望值为NULL
如果要统计"yes"秒,则使用累计计数:
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;
这似乎比在非 "yes" 行上设置 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;
如果你想在非 "yes" 行上 NULL
,你可以将其中任何一个包裹在 case
表达式中。