2011-01-20 9 views
4

私はソート/グルーピングの問題を抱えています。2つのフィールドを使用してソートするにはどうすればよいですか?

公開日と更新日が記載された記事の表があります。私はDjangoを使用しているので、次のようになります。

class Story(models.Model): 
    pub_date = models.DateTimeField(db_index=True) 
    update_date = models.DateTimeField(blank=True, null=True, db_index=True) 
    headline = models.CharField(max_length=200) 
    ... 

1ページ分の記事をページごとにグループ分けして表示します。だから... ...

Jan 20 
    Story 1 
    Story 2 

Jan 19 
    Story 1 
    Story 3 

課題は、物語がUPDATE_DATEを持っている場合、それは一回PUB_DATE日に、2回表示、および一度update_day日の(例えばストーリー1)されなければならないということです。

何千ものストーリーがありますので、私はもちろんpythonでそれを行うことはできませんが、SQLでこのクエリを実行する方法はわかりません。

私は現在、すべてを-pub_dateで並べ替えてから、特定のページで最大と最小の日付の範囲を取得しています。それらの日付の間にupdate_dateを使って物語を検索し、それらを結合してPythonでグループ化します。問題は、ページ上のアイテムの数が不規則であることです。

だから私は、テーブルの項目リストを照会し、2つのフィールドに基づいてソートし、2番目のフィールドに値がある場合はその項目を複製し、 2つのフィールドに基づいてソートしますか?

理にかなっている希望...

答えて

3

私はこれを行うことができるという「労働組合」と考えることができます。

ここにそのような例があります。データベースは、多くの場合、それに送られたクエリのこのタイプを持っているためにそれがいかに速いか良いかわからないDかかわら:

問合せは、あなたのテーブル名がで、列に見出しPUB_DATEが使用されていると解釈およびupdate_date。 update_dateカラムには、更新されていないストーリーの値がnullであることが前提です。

SELECT  headline, 
      the_date, 
      DAY(the_date) AS the_day 
FROM (
    SELECT  headline, 
       pub_date AS the_date 
    FROM  stories 
    UNION 
    SELECT  headline, 
       update_date AS the_date 
    FROM  stories 
    WHERE  update_date IS NOT NULL 
) AS publishedandupdated 
ORDER BY the_date DESC; 

クエリに制限を追加する場合は、「order by」句の後に最後に行う必要があります。

+0

ていますが、おそらく "共用体"を使用すべきです。結果が戻ってくる(それはまったく同じになります)が変わるからではなく、はるかに速いからです。これはおそらく、「別個の」チェックを行うつもりはないからです。私は誰かが労働組合よりも3.5倍早い組合をベンチマークしたことを読んだだけです。 – davogotland

0

あなたの質問は私が持っていたものに似ています。私はFacebookの壁からいくつかの項目を読んでいます。私は2つの日付を持っていました.1つはアイテムの作成(ユーザーがアイテムを投稿)、もう1つはアイテムの取得(Facebookからアイテムを読みました)です。今日投稿または取得されたアイテムを表示したかったのです。

SELECT link,time FROM homeWallItems WHERE 
DATE_SUB(CURDATE(),INTERVAL 1 DAY)<= created 
OR 
DATE_SUB(CURDATE(),INTERVAL 1 DAY)<= time 
group by time LIMIT 0,30 

編集:私はこの文で楽観的でした。間違っていました。代わりに、CURDATEのこのコードで

、()、 あなたがtimeを使用している場合、それは あなたに動作するはずですが。

0

列名を前提として、UNION ALLを使用して、両方の部分から重複を保持する必要があります。

select headline, actualdate=pub_date 
    from story 
    where pub_date between /mindate/ and /maxdate/ 
union all 
    select headline, actualdate=update_date 
    from story 
    where update_date between /mindate/ and /maxdate/ 
order by actualdate 
  • 仮想フィールドactualdateはBYを注文することで、単一の列としてPUB_DATE/UPDATE_DATEを一致させるために使用されます。
  • ユニオンが完了した後、ユニオン・エディ・ステートメント内のORDER BYが適用されるため、1回だけ表示する必要があります。
  • 日付範囲のフィルタはワークテーブルサイズを小さくするために、内組合の各部分に適用される(それが不必要にフィルタを適用する前に、すべてのデータをプルする必要はありません)
+0

これはまだ1ページあたりのアイテムの数が予測不可能になることにつながります。新しく作成されたストーリーと更新されたストーリーの両方で日付範囲が使用されていた古いソリューションの結果として、これが望ましくない動作であったと私は理解していました。 – davogotland

+0

update_dateがNULLになるのはどうですか? –

+0

@John - update_dateがNULLになるのはどうですか?それはどうですか? – RichardTheKiwi

関連する問題