Creating Django pgSQL Query With COUNT , GROUP BY , INTERVAL and LIMIT

时间:2017-04-10 01:51:04

标签: python sql django postgresql

I am trying to create the following query in Django

SELECT content_reference , COUNT(reference) 
    AS total 
  FROM usage_statistics 
 WHERE content_type = 'blog' 
   AND access_date > NOW() - INTERVAL '90' DAY 
 GROUP BY content_reference 
 ORDER BY total DESC 
 LIMIT 10

What I've figured out so far is:

result = UsageStatistics.objects.values('content_reference')\
    .annotate(total=Count('reference'))\
    .order_by('total')

This makes the query

SELECT "usage_statistics"."content_reference", COUNT("usage_statistics"."reference") AS "total" 
  FROM "usage_statistics" 
 GROUP BY "usage_statistics"."content_reference" 
 ORDER BY "total" ASC 
 LIMIT 21

I am unsure how to correctly include:

  • AND access_date > NOW() - INTERVAL '90' DAY
  • ORDER BY total DESC

The following is my usage_statistics table structure

CREATE TABLE usage_statistics
(
  reference bigint
  access_date timestamp with time zone,
  ip_address inet NOT NULL,
  language_iso text NOT NULL,
  content_type character varying(12) NOT NULL,
  content_reference text NOT NULL,
  passport_user_id bigint
)

2 个答案:

答案 0 :(得分:2)

You can use a .filter() to limit to those changed in the last 60 days. It is possible to use a database function NOW(), or you could just do that math in python:

.filter(access_date__gt=datetime.datetime.utcnow() - datetime.timedelta(days=60))

The ordering is likewise possible:

.order_by('-total')

And finally, you can take a slice on the queryset to get just the first 10 results:

[:10]

So, your final query might look something like:

result = UsageStatistics.objects.filter(
    access_date__gte=datetime.datetime.utcnow() - datetime.timedelta(days=60)
).values('content_reference').annotate(
    total=Count('reference')
).order_by('-total')[:10]

答案 1 :(得分:-1)

using: result =UsageStatistics.objects.raw("SELECT content_reference , COUNT(reference) AS total FROM usage_statistics WHERE content_type = 'blog' AND access_date > NOW() - INTERVAL '90' DAY GROUP BY content_reference ORDER BY total DESC LIMIT 10 ")

check https://docs.djangoproject.com/en/dev/topics/db/sql/ for more details.