簡體   English   中英

與表中定義的多個范圍的列匹配的子查詢

[英]Subquery that matches column with several ranges defined in table

我已經為地址數據庫設置了一個非常普通的設置:一個person通過聯接表綁定到一家company ,該company可以有一個address ,依此類推。

所有這些都非常標准化並且易於使用。 但是為了提高搜索性能,我正在創建一個物化的,相當規范化的視圖。 我只需要非常有限的信息和快速查詢集。 現在通常通過連接表完成的大多數操作現在都在數組中。 根據查詢,我可以直接搜索它,也可以通過unnest加入它。

作為補充,以我的zipcodes列( varchar[]我想補充一個states具有(德國fedaral)列國家已經預先計算,這樣我就不必變換查詢,包括各種范圍比較。

我的映射日期在這樣的表中:

CREATE TABLE zip2state (
    state TEXT NOT NULL,
    range_start CHARACTER VARYING(5) NOT NULL,
    range_end CHARACTER VARYING(5) NOT NULL
)

每個州都有多個范圍,范圍可以重疊(一個郵政編碼可以用於兩個不同的州)。 一些范圍具有range_start = range_end

現在,我有點想知道如何一次全部實現它。 通常,我很想重復進行操作(通過觸發器或在應用程序級別)。 或者,因為我們只是在談論5位數字,所以我可以創建一個大表映射zip來直接聲明而不是通過范圍來表示(我目前的最愛,但是它有點丑陋,以至於提示我問是否有更好的方法)

用上面的表(或類似的表)在SQL中執行此操作的任何方法? 我使用的是Postgres 9.3,允許使用所有功能...

為了完整起見,這是郵政編碼的子查詢:

    (select array_agg(distinct address.zipcode)
      from  affiliation
      join  company
        on  affiliation.ins_id = company.id
      join  address
        on  address.com_id = company.id
     where  affiliation.per_id = person.id) AS zipcodes,

我建議使用LATERAL而不是相關子查詢來方便地一次計算兩個列。 可能看起來像這樣:

SELECT p.*, z.*
FROM   person p
LEFT   JOIN LATERAL (
   SELECT array_agg(DISTINCT d.zipcode) AS zipcodes
        , array_agg(DISTINCT z.state)   AS states
   FROM   affiliation    a
   -- JOIN   company     c ON a.ins_id = c.id  -- suspect you don't need this
   JOIN   address        d ON d.com_id = a.ins_id  -- c.id
   LEFT   JOIN zip2state z ON d.zipcode BETWEEN z.range_start AND z.range_end
   WHERE  a.per_id = p.id
   ) z ON true;

如果保證了參照完整性,則根本不需要加入表company 我走了捷徑。

請注意, varchartext行為與預期的數字不同。 例如: '333' > '0999' 如果所有郵政編碼都有5位數字,則可以。

有關:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM