2017-06-23 1 views
1

私は、次のデータがあります。反復処理テーブル内のグループを超える

cte1 
=========================== 
m_ids |p_id  |level 
---------|-----------|----- 
{123} |98   |1 
{123} |111  |2 
{432,222}|215  |1 
{432,222}|215  |1 
{432,222}|240  |2 
{432,222}|240  |2 
{432,222}|437  |3 
{432,222}|275  |3 

私は、次の操作を実行する必要があります。すべてのために、以下のアルゴリズム

  1. によって

    1. エキスp_idを同一の列m_ids

    2. 各gro up:
      2.I.グループレコードby p_id
      2.II.注文の記録をlevel
      2.IIIで注文します。これは最後のために(私はarray_lengthを取得しています場所はおそらく間違った)m_ids長さと正確な数でp_idを選択し、これまでのところ、私は完全にこのアルゴリズムを記述するために失敗する最大とlevel

、私が書きましたその一部:m_ids={123}ためgrouped_cte1

SELECT id 
FROM grouped_cte1 
GROUP BY id, 
      level 
HAVING Count(*) = array_length(grouped_cte1.m_ids, 1) 
ORDER BY level DESC 
LIMIT 1 

ある

m_ids |p_id  |level 
---------|-----------|----- 
{123} |98   |1 
{123} |111  |2 

m_ids={432,222}ためには

m_ids |p_id  |level 
---------|-----------|----- 
{432,222}|215  |1 
{432,222}|215  |1 
{432,222}|240  |2 
{432,222}|240  |2 
{432,222}|437  |3 
{432,222}|275  |3 

2である)以下でP.1からクエリを組み合わせます。各m_idsについてlevel=1と、次の抽出物p_idは:

以下になり
select m_ids, p_id from cte1 where level=1 --also selecting m_ids for joining later` 

m_ids |p_id 
---------|---- 
{123} |98 
{432,222}|215 

望ましい結果:

m_ids |result_1 |result_2 
---------|-----------|-------- 
{123} |111  |98 
{432,222}|240  |215 

だから誰も私が最初の解決助けてください可能性がありアルゴリズムの一部および(オプション)を2番目の部分と1つのクエリで結合しますか?

EDIT:それを反復しながら、m_idsによってサブテーブルに提示テーブルを破る
1:
はこれまでのところ私が失敗します。
2.クエリの対応する行に対してarray_length(grouped_cte1.m_ids, 1)の計算を実行する。

答えて

1

正しいトラックにあるクエリの最初の部分については、グループ化ロジックを変更してから、再度テーブルに参加して、DISTINCT ON句を使用できるm_idsごとの最高レベルでフィルタリングする必要があります適切なソートと組み合わせる:

select 
    distinct on (t.m_ids) 
    t.m_ids, t.p_id, t.level 
from cte1 t 
join (
    select 
    m_ids, 
    p_id 
    from cte1 
    group by m_ids, p_id 
    having count(*) = array_length(m_ids, 1) 
) as g using (m_ids, p_id) 
order by t.m_ids, t.level DESC; 

これはあなたを与えるだろう:

m_ids | p_id | level 
-----------+------+------- 
{123}  | 111 |  2 
{432,222} | 240 |  2 

そして私が変更された第2のクエリ(最初のクエリは、このような条件が欠落しているとき、目的を表示するためのFULL JOINを使用)と組み合わせます〜によってあなたは結果を与える

select 
    coalesce(r1.m_ids, r2.m_ids) as m_ids, 
    r1.p_id AS result_1, 
    r2.p_id AS result_2 
from (
    select 
    distinct on (t.m_ids) 
    t.m_ids, t.p_id, t.level 
    from cte1 t 
    join (
    select 
     m_ids, 
     p_id 
    from cte1 
    group by m_ids, p_id 
    having count(*) = array_length(m_ids, 1) 
    ) as g using (m_ids, p_id) 
    order by t.m_ids, t.level DESC 
) r1 
full join (
    select distinct m_ids, p_id 
    from cte1 
    where level = 1 
) r2 on r1.m_ids = r2.m_ids 

::がある(実際にある)ことができますので、最初のレベルのm_ids, p_idペアのための複数のレコードは、それは次のようになり明確なdding

m_ids | result_1 | result_2 
-----------+----------+---------- 
{123}  |  111 |  98 
{432,222} |  240 |  215 

ものとは異なって見えることあなたは期待していますが、ロジックの私の理解から、正しいものです。私が何かを誤解した場合は、私に知らせてください。ちょうどロジック説明、一点のために


{123}とm_idsがresult_1ための111を返すのはなぜ? m_ids = {123}グループの

  • 我々は、このようresult_1
  • ために選択される、 m_idsp_id = 111
  • より高いレベルを有しているとカウント等価の条件のための2つの別個のp_id
  • 両方98111アカウントを持っています
+0

あなたは正しく、私は本当に「望ましい結果」で間違いを犯しました!あなたの答えは信じられないほど役に立ちます! –

+1

'm_ids = {432,222} 'と同じです。お役に立てて嬉しいです。 –

+0

申し訳ありませんが、私はすでにそれを受け入れたと思った; D –