日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本文介紹了如何聚集PostgreSQL表中與輸入值或來自任何其他匹配行的值匹配的行?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我的PostgreSQL數據庫中有一個如下所示的表

如果群集中的每個聯系人與群集中的另一個聯系人共享Contact_id_a或Contact_id_b值(或兩者),我如何帶回該群集中的聯系人?

在上面屏幕截圖圖像中的示例中,第1-6行將位于同一群集中,而第8行將不屬于任何群集。

如何將SQL查詢或SQL查詢與Java代碼結合使用來實現此目的?

對于上下文,此表列出了聯系人列表中所有潛在的重復聯系人。我們希望向列表所有者顯示所有可能重復的聯系人,以便用戶可以手動管理這些重復項。

以下是我的起始代碼:

DuplicateCandidate firstDuplicate = db.sql("select * from duplicates where list_id = "+list_id+ " and ignore_duplicate is not true").first(DuplicateCandidate);
        String sql = "select * from duplicates where list_id = "+list_id+ "and ignore_duplicate is not true "
                + "and (contact_id_a = ? or contact_id_b = ? or contact_id_a = ? or contact_id_b = ?";
        List<DuplicateCandidate> groupOfDuplicates  = db.sql(sql, firstDuplicate.contact_id_a,firstDuplicate.contact_id_a, firstDuplicate.contact_id_b, firstDuplicate.contact_id_b).results(DuplicateCandidate.class);

這將返回第一行和包含16247096或16247097的任何其他行,但不返回與第二個查詢結果中的Contact_id匹配的其他重要行。

干杯。

推薦答案

這樣的群集是一個迭代過程,步驟數未知。我從未找到可以在遞歸查詢中完成的解決方案。

我已經六年多沒有從事CRM工作了,但是下面的函數類似于我們過去生成匹配組的方式。逐行執行此操作對于我們的工作負載來說執行得不夠好,并且通過主機語言(例如使用JavaHashMap()HashSet())來完成此操作,而倒排索引會造成非?;靵y的代碼。

假設此架構:

d contact_info 
                 Table "public.contact_info"
      Column      |  Type   | Collation | Nullable | Default 
------------------+---------+-----------+----------+---------
 contact_id_a     | bigint  |           |          | 
 contact_id_b     | bigint  |           |          | 
 ignore_duplicate | boolean |           |          | false
 list_id          | integer |           |          | 496

select * from contact_info ;
 contact_id_a | contact_id_b | ignore_duplicate | list_id 
--------------+--------------+------------------+---------
     16247096 |     16247097 | f                |     496
     16247096 |     16247098 | f                |     496
     16247096 |     16247099 | f                |     496
     16247097 |     16247098 | f                |     496
     16247097 |     16247099 | f                |     496
     16247098 |     16247099 | f                |     496
     16247094 |     16247095 | f                |     496
(7 rows)

此函數創建兩個臨時表來保存中間群集,然后在不再可能進行群集時返回結果。

create or replace function cluster_contact() 
  returns table (clust_id bigint, contact_id bigint) 
  language plpgsql as $$
declare 
  last_count bigint := 1;
  this_count bigint := 0;
begin
  create temp table contact_match (clust_id bigint, contact_id bigint) on commit drop;
  create index cm_1 on contact_match (contact_id, clust_id);
  create index cm_2 on contact_match using hash (clust_id);
  create temp table contact_hold (clust_id bigint, contact_id bigint) on commit drop;

  with dedup as (
    select distinct least(ci.contact_id_a) as clust_id,
           greatest(ci.contact_id_b) as contact_id
      from contact_info ci
     where not ci.ignore_duplicate
  )
  insert into contact_match
    select d.clust_id, d.clust_id from dedup d
    union
    select d.clust_id, d.contact_id from dedup d;

  while last_count > this_count loop

    if this_count = 0 then 
      select count(distinct cm.clust_id) into last_count from contact_match cm;
    else 
      last_count := this_count;
    end if;

    with new_cid as (
      select cm.contact_id as clust_id_old,
             min(cm.clust_id) as clust_id_new
        from contact_match cm
       group by cm.contact_id
    )
    update contact_match
       set clust_id = nc.clust_id_new
      from new_cid nc
     where contact_match.clust_id = nc.clust_id_old;

    truncate table contact_hold;
    insert into contact_hold 
      select distinct * from contact_match;
 
    truncate table contact_match;
    insert into contact_match
      select * from contact_hold;

    select count(distinct cm.clust_id) into this_count from contact_match cm;

  end loop;

  return query select * from contact_match order by clust_id, contact_id;
end $$;

我見過的開發人員面臨的最大心理障礙之一是忽略包括contact_id與其自身的關系。這會導致不連續的處理和不必要地使左右兩邊復雜化的心理模型。

select * from cluster_contact();
 clust_id | contact_id 
----------+------------
 16247094 |   16247094
 16247094 |   16247095
 16247096 |   16247096
 16247096 |   16247097
 16247096 |   16247098
 16247096 |   16247099
(6 rows)

如果您需要澄清此解決方案中的任何步驟,或者它對您不起作用,請提供意見。

另外,請知道fuzzystrmatch中提供了Levenshtein,并且它工作正常。

如果您希望使用從1開始的順序clust_id,請將函數中的return query更改為:

  return query 
    select dense_rank() over (order by cm.clust_id) as clust_id, 
           cm.contact_id 
      from contact_match cm 
     order by clust_id, contact_id;

它將產生:

select * from cluster_contact();
 clust_id | contact_id 
----------+------------
        1 |   16247094
        1 |   16247095
        2 |   16247096
        2 |   16247097
        2 |   16247098
        2 |   16247099
(6 rows)

這篇關于如何聚集PostgreSQL表中與輸入值或來自任何其他匹配行的值匹配的行?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,

分享到:
標簽:postgresql 中與 匹配 聚集 輸入
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定