0

私はこのクエリを持っており、うまく機能しています:

 SELECT * FROM
 (
 select
        p.id,
        comparestrings('marco', pc.value) as similarity
 from
        unit u, person p
        inner join person_field pc ON (p.id = pc.id_person)
        inner join field c ON (pc.id_field = c.id AND c.flag_name = true)
     where  ( u.id = 1 ) AND p.id_unit = u.id    

 ) as subQuery
 where
        similarity is not null
        AND
        similarity > 0.35
 order by
        similarity desc;

状況を説明させてください。

テーブル:

  • person列としてのID。
    • fieldname, varchar(そのようなもの)のような列を表すテーブル
    • person_fieldその人とそのフィールドの値を表します。次のように:
    • unitこの質問には関係ありません

例えば。:

  Person id 1
  Field  id 1 {name, eg)
  value "Marco Noronha"

したがって、関数「comparestrings」は0から1までのdoubleを返します。ここで、1は正確です('Marco' =='Marco')。

したがって、0.35を超える類似性を持つすべての人が必要であり、その類似性も必要です。

問題ありません。クエリは正常に機能します。しかし、これらの行の変更を追跡するために、テーブル「person_field」に変更日が含まれるという新しい要件があります。

例えば。:

 Person ID 1 
 Field  ID 1 
 Value  "Marco Noronha"
 Date - 01/25/2013

 Person ID 1
 Field  ID 1
 Value  "Marco Tulio Jacovine Noronha"
 Date - 02/01/2013

だから私がする必要があるのは、最新の行だけを検討することです!! 同じクエリを実行すると、結果は次のようになります(例)。

 1, 0.8
 1, 0.751121
 2, 0.51212
 3, 0.42454
 //other results here, other 'person's 

そして、私が持ち込みたい値が1、0.751121であると仮定しましょう(魔女はDATEまでに最も遅い値です)

私は次のようなことをすべきだと思います order by date desc limit 1...

しかし、私がそのようなことをすると、クエリは1人だけを返します= /

好き:

 1, 0.751121

本当に欲しいとき:

 1, 0.751121
 2, 0.51212
 3, 0.42454
4

2 に答える 2

1

サブクエリで使用できDISTINCT ON(p.id)ます:

 SELECT * FROM
 (
 select
        DISTINCT ON(p.id)
        p.id,
        comparestrings('marco', pc.value) as similarity
 from
        unit u, person p
        inner join person_field pc ON (p.id = pc.id_person)
        inner join field c ON (pc.id_field = c.id AND c.flag_name = true)
     where  ( u.id = 1 ) AND p.id_unit = u.id    
     ORDER BY p.id, pc.alt_date DESC

 ) as subQuery
 where
        similarity is not null
        AND
        similarity > 0.35
 order by
        similarity desc;

機能させるには、次を追加する必要があることに注意してくださいORDER BY p.id, pc.alt_date DESC

  • p.id: 必須DISTINCT ON( を使用する場合ORDER BY、最初のフィールドは とまったく同じでなければなりませんDISTINCT ON);
  • pc.alt_date DESC:あなたが言及した変更日(私たちは降順に並べるので、それぞれで最も古いものを取得しますp.id

ちなみに、サブクエリはまったく必要ないようです(がまたはcomparestringsとしてマークされていることを確認してください。十分に高速です):stableimmutable

SELECT
    DISTINCT ON(p.id)
    p.id,
    comparestrings('marco', pc.value) as similarity
FROM
    unit u, person p
    inner join person_field pc ON (p.id = pc.id_person)
    inner join field c ON (pc.id_field = c.id AND c.flag_name = true)
WHERE  ( u.id = 1 ) AND p.id_unit = u.id    
    AND COALESCE(comparestrings('marco', pc.value), 0.0) > 0.35
ORDER BY p.id, pc.alt_date DESC, similarity DESC;
于 2013-02-25T16:05:35.537 に答える
0

次の例のように、サブクエリへの参照を変更しますperson(サブクエリは と呼ばれるものですp)。

. . .
from unit u cross join
     (select p.*
      from (select p.*,
                   row_number() over (partition by person_id order by alterationdate desc) as seqnum
            from person p
           ) p
      where seqnum = 1
     ) p
     . . .

これはrow_number()関数を使用して最後の行を識別します。追加のサブクエリを使用して、結果を最新のものに制限しました。onこれを句または句に含めることもできますwhere

,また、を明示的に変更しましたcross join

于 2013-02-25T15:14:01.170 に答える