我有这样的查询:
SELECT DISTINCT(orders.email), uuid_nil() AS customer_id, 'Order' AS customer_type, orders.first_name, orders.last_name, MAX(orders.paid_at) AS last_order_at, 1 AS order_count, SUM(orders.total_price_cents) AS total_spent_pennies
FROM orders
WHERE orders.state = 'paid' AND orders.customer_id IS null
GROUP BY orders.email, customer_id, orders.first_name, orders.last_name
UNION
SELECT DISTINCT(customers.email), customers.id AS customer_id, 'Customer' AS customer_type, customers.first_name, customers.last_name, MAX(orders.paid_at) AS last_order_at, COUNT(orders.*) AS order_count, SUM(orders.total_price_cents) AS total_spent_pennies
FROM customers
JOIN orders ON customers.id = orders.customer_id
GROUP BY customers.email, customers.id, customers.first_name, customers.last_name
看起来像:
+-------------------------------+--------------------------------------+---------------+------------+--------------+-------------------------+-------------+---------------------+
| email | customer_id | customer_type | first_name | last_name | last_order_at | order_count | total_spent_pennies |
+-------------------------------+--------------------------------------+---------------+------------+--------------+-------------------------+-------------+---------------------+
| blah@gmail.com | 00000000-0000-0000-0000-000000000000 | Order | Richard | Doe | 2015-12-18 14:45:22 UTC | 1 | 2000 |
| paul@blah.com | 00000000-0000-0000-0000-000000000000 | Order | Paul | Doe | 2016-04-05 09:04:57 UTC | 1 | 5000 |
+-------------------------------+--------------------------------------+---------------+------------+--------------+-------------------------+-------------+---------------------+
我的问题是如何包含他们的最后一个IP地址(INET列)。一个日期我可以简单地使用MAX聚合函数,但IP地址显然没有。
基本上我如何将上面的查询结合起来给我一个带有last_ip地址的新列,例如:
SELECT browser_ip FROM orders
WHERE email = 'blah@gmail.com'
ORDER BY paid_at DESC
LIMIT 1
答案 0 :(得分:1)
你可以使用这样的简单子查询,你只需要命名你的查询以便在它们之间进行引用。
http://www.techonthenet.com/postgresql/subqueries.php
例如,查询的第一部分将是:
SELECT DISTINCT(c1.email), c1.id AS customer_id, 'Customer' AS customer_type,
c1.first_name, c1.last_name, MAX(orders.paid_at) AS last_order_at,
COUNT(orders.*) AS order_count, SUM(orders.total_price_cents) AS total_spent_pennies,
(SELECT browser_ip FROM orders WHERE c1.email = orders.email
ORDER BY paid_at DESC LIMIT 1) last_ip
FROM customers c1
JOIN orders ON c1.id = orders.customer_id
GROUP BY c1.email, c1.id, c1.first_name, c1.last_name
答案 1 :(得分:0)
Cast to varchar,并使用string_agg - 类似于:
SELECT email, paid_at, string_agg(browser_ip::varchar, ',') as ips
WHERE email = 'blah@gmail.com'
GROUP BY email, paid_at
ORDER BY email, paid_at DESC
LIMIT 1
应该可以正常工作。
答案 2 :(得分:0)
几个选项:
在你的情况下,由于联盟,我可能会做第二次并做这样的事情:
CREATE OR REPLACE FUNCTION latest_ip(in_email text)
RETURNS inet LANGUAGE SQL AS
$$
SELECT paid_at, string_agg(browser_ip::varchar, ',') as ips
WHERE email = in_email
GROUP BY paid_at
ORDER BY paid_at DESC
LIMIT 1
$$;
然后,您只需在列列表中调用latest_ip(orders.email)
另一个需要在你的工会的两个分支上的LATERAL语句之后复制上面的子查询。值得了解,但在这种情况下可能是一个维护问题。