我需要选择的是表用户中每个“ id_customer”及其ID,dispatch_seconds和一次订购距离的总行程数。 id_customer,customer_id和order_id是字符串。
应该看起来像这样
+------+--------+------------+--------------------------+------------------+
| id | count | #1order id | #1order dispatch seconds | #1order distance |
+------+--------+------------+--------------------------+------------------+
| 1ar5 | 3 | 4r56 | 1 | 500 |
| 2et7 | 2 | dc1f | 5 | 100 |
+------+--------+------------+--------------------------+------------------+
干杯!
原文经过编辑,因为在讨论过程中S-man帮助我找到了确切的问题解决方案。 S-man https://dbfiddle.uk/?rdbms=postgres_10&fiddle=e16aa6008990107e55a26d05b10b02b5
解决方案答案 0 :(得分:1)
SELECT
customer_id,
order_id,
order_timestamp,
dispatch_seconds,
distance
FROM (
SELECT
*,
count(*) over (partition by customer_id), -- A
first_value(order_id) over (partition by customer_id order by order_timestamp) -- B
FROM orders
)s
WHERE order_id = first_value -- C
https://www.postgresql.org/docs/current/static/tutorial-window.html
一个窗口功能,可获取每个用户的总记录数
B窗口函数,该函数按时间戳对每个用户的所有记录进行排序,并给出相应用户的第一个order_id
。使用first_value
而不是min
有一个好处:也许您的订单ID并没有按时间戳实际增加(也许两个订单同时进入,或者您的订单ID并不是按顺序增加,而是某种形式)哈希)
->都是新列
C现在获得所有列,其中“ first_value”(按时间戳记即第一个order_id
)等于当前行的order_id
。这将按用户给出所有具有第一顺序的行。
结果:
customer_id count order_id order_timestamp dispatch_seconds distance
----------- ----- -------- ------------------- ---------------- --------
1ar5 3 4r56 2018-08-16 17:24:00 1 500
2et7 2 dc1f 2018-08-15 01:24:00 5 100
请注意,在这些测试数据中,用户“ 2et7”的顺序“ dc1f”具有较小的时间戳,但排在后面。它不是表中用户的第一个出现,而是顺序最早的用户。如上所述,这应该证明first_value
与min
的对比。
答案 1 :(得分:0)
您可以使用窗口功能:
select distinct customer_id,
count(*) over (partition by customer_id) as no_of_order
min(order_id) over (partition by customer_id order by order_timestamp) as first_order_id
from orders o;
答案 2 :(得分:0)
我认为您的原始查询中有很多错误,您的排名未分区,order by子句似乎不正确,您仅过滤了一个“随机”订单,然后应用计数,列表继续。 / p>
这样的事情似乎更接近您想要的东西?
SELECT
customer_id,
order_count,
order_id
FROM (
SELECT
a.customer_id,
a.order_count,
a.order_id,
RANK() OVER (PARTITION BY a.order_id, a.customer_id ORDER BY a.order_count DESC) AS rank_id
FROM (
SELECT
customer_id,
order_id,
COUNT(*) AS order_count
FROM
orders
GROUP BY
customer_id,
order_id) a) b
WHERE
b.rank_id = 1;
答案 3 :(得分:0)
您处在正确的轨道上。只需使用条件聚合:
SELECT o.customer_id, COUNT(*)
MAX(CASE WHEN seqnum = 1 THEN o.order_id END) as first_order_id
FROM (SELECT o.*,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_timestamp ASC) as seqnum
FROM orders o
) o
GROUP BY o.customer_id;
您的JOIN
对于此查询不是必需的。