【问题标题】:SQL First row only following aggregation RulesSQL 第一行仅遵循聚合规则
【发布时间】:2013-12-04 21:14:01
【问题描述】:

我只需要从表中选择最重要的值。使用 Postgre SQL(最新版本) 遵循数据示例:

餐桌公司

Id, Name, ExternalId, StartAt
1   Comp1      54123  21/05/2000
2   Comp2      23123  21/05/2000

表地址

Id,  Company, Address_Type, City
1          1            7     A
2          2            2     B
3          2           62     C

表格地址类型

Id, Name, importance_order
62  Adt1               1
7   Adt2               2
2   Adt3               2

我需要做的是根据“importance_order”获取公司及其主要地址。已经有一个函数返回这个结果:

Create function~~~~
Select * from Company  c
join Address a on c.address_id = a.id
Join AddressType at on a.adresstype_id = at.id
ORDER by at.importance_order
Limit 1

我现在的问题是查询中的每一行都会调用一次此函数,并且需要花费很多时间(大约 20 分钟)。是否可以通过连接表来执行这种类似的方法?我需要这个加入来获取第一个“最重要”的地址,然后获取城市名称,但需要以“更快”的方式执行此操作。我需要将子查询的数量减少到最小。

Select * from table t
    inner join Company c on t.company_id = c.id
    left join address a on (c.company_id = c.id)
    left join addresstype at on (a.adresstype_id = at.id)
    where at.id = (
        select max(id)  from addresstype 
        where adresstype in (
            select adresstype from adress where company_id = c.id
            )
        )   

如果不清楚,请告诉我更多细节。

谢谢。

【问题讨论】:

    标签: sql postgresql aggregation


    【解决方案1】:

    我想为此你需要 PostgreSQL 8.4+

    SELECT T.*
    FROM TABLE AS T
    INNER JOIN
    (
        SELECT * FROM
        (
            SELECT C1.*, ROW_NUMBER() OVER(partition by C1.ID ORDER BY T.IMPORTANCE_ORDER) AS RN
            FROM COMPANY AS C1
            INNER JOIN ADDRESS AS A
            ON C1.ID = A.COMPANY
            INNER JOIN ADDRESS_TYPE AS T
            ON T.ID = A.ADDRESS_TYPE_ID
        ) A 
        WHERE RN = 1
    ) AS B
    ON B.ID= T.COMPANY_ID
    

    【讨论】:

    • 这样做我只得到 1 行的所有记录,但我需要每家公司得到 1 行。我不应该以某种方式重置 RN,比如使用 group by?
    • 做了一个修改,看到OVER关键字后添加了基于公司ID的Partition子句
    • 这是完美的,正是我需要的。非常感谢。最终查询现在快了 5 倍:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多