在窗口函数postgresql

时间:2019-07-17 07:36:22

标签: postgresql

我正在使用postgresql并应用窗口函数。以前,我必须找到具有相同姓氏和地址(街道地址和城市)的姓氏,所以我只是将姓氏放在窗口函数的partition by子句中。

但是现在我需要查找姓氏不相同的第一个g_id。地址相同时该怎么办?

这是我以前所做的。

SELECT g_id as g_id,
 First_value(g_id) 
 OVER (PARTITION BY lname,street_address , city , 
           order by  last_date DESC NULLS LAST )as c_id,
street_address as street_address  FROM my table;

让我们说这是我的数据库


g_id | l_name | street_address | city | last_date
_________________________________________________
x1   | bar    | abc road       | khi  | 11-6-19

x2   | bar    | abc road       | khi  | 12-6-19

x3   | foo    | abc road       | khi  | 19-6-19

x4   | harry  | abc road       | khi  | 17-6-19

x5   | bar    | xyz road       | khi  | 11-6-19

_________________________________________________

在以前的场景中: 因为如果我在我的c_id的第一行中运行,它应该返回“ x2”,因为它考虑了以下行:

_________________________________________________
g_id | l_name | street_address | city | last_date
_________________________________________________
x1   | bar    | abc road       | khi  | 11-6-19

x2   | bar    | abc road       | khi  | 12-6-19
_________________________________________________

并返回具有最新last_date的行。

我现在要选择这些行(具有相同的street_address和city但没有相同的l_name的行):


g_id | l_name | street_address | city | last_date
_________________________________________________
x1   | bar    | abc road       | khi  | 11-6-19

x3   | foo    | abc road       | khi  | 19-6-19

x4   | harry  | abc road       | khi  | 17-6-19
_________________________________________________

输出将是x3。

如果不等于last_name的当前值,我想以某种方式比较last_name列,然后按地址字段进行分区。如果没有行满足条件c_id应该等于当前的g_id

3 个答案:

答案 0 :(得分:1)

根据您的预期输出,尚不清楚每个组是最早的还是最早的。您可以在使用ORDER BY

的此查询中为last_date相应地更改DISTINCT ON
SELECT DISTINCT ON ( street_address, city, l_name) * 
   FROM   mytable 
ORDER  BY street_address, 
          city, 
          l_name, 
          last_date  --change this to last_date desc if you want latest

DEMO

答案 1 :(得分:1)

在讨论了此chat中的详细信息之后:

demo:db<>fiddle

SELECT DISTINCT ON (t1.g_id) 
    t1.*,
    COALESCE(t2.g_id, t1.g_id) AS g_id
FROM
    mytable t1
    LEFT JOIN mytable t2
    ON t1.street_address = t2.street_address AND t1.l_name != t2.l_name
ORDER BY t1.g_id, t2.last_date DESC

答案 2 :(得分:1)

这是我使用子查询解决的方法 创建示例表。

CREATE TABLE mytable
("g_id" varchar(2), "l_name" varchar(5), "street_address" varchar(8), "city" varchar(3), "last_date" date)

;

INSERT INTO mytable
("g_id", "l_name", "street_address", "city", "last_date")
VALUES
('x1', 'bar', 'abc road', 'khi', '11-6-19'),
('x2', 'bar', 'abc road', 'khi', '12-6-19'),
('x3', 'foo', 'abc road', 'khi', '19-6-19'),
('x4', 'harry', 'abc road', 'khi', '17-6-19'),
('x5', 'bar', 'xyz road', 'khi', '11-6-19')

;

查询以获取g_ids

SELECT * ,
(select b.g_id from mytable b where (base.g_id = b.g_id) or (base.l_name <> 
b.l_name and base.street_address = b.street_address and base.city = b.city ) 
order by b.last_date desc  limit 1)
from mytable base