0

APIにTastypieを使用していますが、1つのエンドポイントで特定のカテゴリの場所のリストを表示する必要があります。その部分は簡単です:

class PlaceResource(ModelResource):
    class Meta:
        queryset = Place.objects.all()
        filtering = { 
            'category': ALL
        }

しかし、私が持っていると言うとlimit = 100、私は各カテゴリーから偶数の場所を取得したいと思います。

例:

/ api / Places /?category = 1&category = 2&category = 3&category = 4

各カテゴリー1、2、3、4から25の場所を教えてください。

SQLを使用してこれを実行できることはわかっていますが、それはどのように最適な方法で実行されますか?

4

1 に答える 1

1

たとえば、次のテーブルがあるとします。

CREATE TABLE place (
   place_id serial primary key
 , place    text
 , cat_id   int);

sqlfiddle でセットアップをテストします
セットアップで示したようなインデックスから利益を得ることができcategoryます。

基本的に、次の 2 つの方法があります。

row_number()

WITH x AS (
    SELECT *, row_number() OVER (PARTITION BY category) AS rn
    FROM   place
    WHERE  category IN (1,2,3,4)
    )
SELECT place_id, place, category
FROM   x
ORDER  BY rn
LIMIT  100;
  • かなり洗練されていることに加えて、このクエリがカテゴリが増えると長くなる唯一の部分はIN句です。
  • それぞれのシェアを計算する必要はありませんcategory。これは自動的に行われます。
  • カテゴリの行数がそのシェアよりも少ない場合、残りの行は他のカテゴリと同じ割合で埋められます。

UNION ALL

(SELECT * FROM place WHERE category = 1 LIMIT 25)
UNION ALL
(SELECT * FROM place WHERE category = 2 LIMIT 25)
UNION ALL
(SELECT * FROM place WHERE category = 3 LIMIT 25)
UNION ALL
(SELECT * FROM place WHERE category = 4 LIMIT 25);
  • これは原始的で非常に高速ですが、多くのカテゴリでは長くなります (遅くはありません)。
  • UNION ALLではなく、使用してくださいUNION
  • UNION適用するには、クエリの各レッグを括弧で囲む必要がありますLIMIT
  • 各カテゴリのシェアを計算し、端数シェアを分割する方法を決定する必要があります。
  • カテゴリの行数がそのシェアよりも少ない場合、クエリから得られる行数は少なくなります。
于 2012-11-19T23:35:45.057 に答える