0

これらのようなDOCUMENTとATTRIBUTESの2つのテーブルがあります

  • DOCUMENT(id)
  • ATTRIBUTE(name, value, doc_fk).

この「抽象クエリ」のように機能するクエリを実行する必要があります

select top 100 documents
where $state='COMPLETED'
order by $creationDate

$state$creationDateは 2 つの属性です。

制限は属性ではなくドキュメントにあり、並べ替えとフィルターは 2 つの異なる属性にあることに注意してください。最後のクエリは、フィルタリング/ソートされたものだけでなく、すべてのドキュメント属性を返す必要があります。

非常に複雑なクエリでこれを書くことができたので、より良い代替手段を探しています。役立つ場合はソリューションを投稿できますが、おそらく間違った方向に向けたくありません。

100 ではなく 1000 のように、少数の余分なドキュメントを取得し、メモリ内でフィルター処理/並べ替えを行うことは問題ありません。必要な制限100の代わりに74のように、制限が正確でなくても問題ありませんが、それから遠すぎません.

追加の「ソフト」要件:

  • クエリはいくつかのデータベース (oracle、mysql、および sqlserver) で動作するはずなので、すべてのプラットフォームで利用できない限り、奇妙な分析関数は避ける必要があります。
  • JPA(eclipselink 2.4.0実装)で動作するはずです

期待される出力は次のようなものです

DOC_ID   ATTRIBUTE_NAME          VALUE
  123       state              COMPLETED
  123       creationDate       21/11/2012
  123       userid             someone
  456       state              COMPLETED
  ...
4

2 に答える 2

0

ああ、EAV設計の欠陥。

これを試して。

select 
   top 100
   document.* 

from document   
    inner join attribute astate on document.id = astate.doc_fk
          and astate.name='state'
          and astate.value = 'completed'
    inner join attribute acreation on document.id = acreation.doc_fk
            and acreation.name='creationdate'
order by cast(acreation.value as date)

しかし、この EAV 構造に固執すると、さらに複雑になるだけです。

(PS. MySQL は TOP を使用しませんが、代わりに LIMIT を使用します)

于 2012-11-07T09:24:22.307 に答える
0
SELECT doc_id, attr_name, attr_val, creationDate FROM 

   (
       SELECT * FROM (
          SELECT 
             doc.id as 'doc_id', attr.name as 'attr_name', null as 'attr_val', attr.value as 'creationDate'  
          FROM 
             ATTRIBUTE attr 
          LEFT JOIN 
             DOCUMENT doc ON attr.doc_fk = doc.id 
          WHERE 
             attr.name='creationDate' 
          ORDER BY creationDate desc;

       ) AS dt1


     UNION ALL


      SELECT * FROM( 
          SELECT 
             doc.id as 'doc_id', attr.name as 'attr_name', attr.value as 'attr_val', null as 'creationDate'  
          FROM 
             ATTRIBUTE attr 
          LEFT JOIN 
             DOCUMENT doc ON attr.doc_fk = doc.id;
      ) as dt2


   ) as dt0 GROUP BY doc_id ORDER by creationDate desc LIMIT 100;

派生テーブル 1 (dt1) は、すべての日付属性を提供します。これにより、ドキュメントの作成日で結果を並べ替えることができます。派生テーブル 2 は、すべての属性を提供します。すべてを「union all」でまとめて、ドキュメントでグループ化し、作成日で並べ替えることができます。これが正しい方向にあることを願っています。

于 2012-11-07T09:34:55.270 に答える