2015-06-11 15 views
8

Tôi có một bảng có tất cả các giao dịch mua của costumers của tôi. Tôi muốn chọn tất cả các mục từ tuần trước, (bắt đầu tuần từ Chủ Nhật).PostgreSQL Truy vấn để chọn dữ liệu từ tuần trước?

id value date 
5907 1.20 "2015-06-05 09:08:34-03" 
5908 120.00 "2015-06-09 07:58:12-03" 

Tôi đã thử điều này:

SELECT id, valor, created, FROM compras WHERE created >= now() - interval '1 week' and parceiro_id= '1' 

Nhưng tôi nhận được dữ liệu từ tuần trước bao gồm dữ liệu từ tuần này, tôi chỉ muốn dữ liệu so với tuần trước.

Làm cách nào để nhận dữ liệu từ tuần trước?

Trả lời

14

Tình trạng này sẽ trả lại hồ sơ từ chủ nhật đến thứ bảy tuần trước:

WHERE created BETWEEN 
    NOW()::DATE-EXTRACT(DOW FROM NOW())::INTEGER-7 
    AND NOW()::DATE-EXTRACT(DOW from NOW())::INTEGER 

Có một ví dụ:

WITH compras AS (
    SELECT (NOW() + (s::TEXT || ' day')::INTERVAL)::TIMESTAMP(0) AS created 
    FROM generate_series(-20, 20, 1) AS s 
) 
SELECT to_char(created, 'DY'::TEXT), created 
FROM compras 
WHERE created BETWEEN 
    NOW()::DATE-EXTRACT(DOW FROM NOW())::INTEGER-7 
    AND NOW()::DATE-EXTRACT(DOW from NOW())::INTEGER 

Trong câu trả lời cho @ d456:

wouldn Không sử dụng BETWEEN bao gồm nửa đêm vào Chủ Nhật ở cả hai đầu của khoảng thời gian?

Quyền đó, BETWEEN bao gồm nửa đêm vào Chủ Nhật ở cả hai đầu của khoảng thời gian. Để loại trừ nửa đêm ngày chủ nhật tại cuối khoảng thời gian đó là cần thiết để sử dụng các toán >=<:

WITH compras AS (
    SELECT s as created 
    FROM generate_series(-- this would produce timestamps with 20 minutes step 
      (now() - '20 days'::interval)::date, 
      (now() + '20 days'::interval)::date, 
      '20 minutes'::interval) AS s 
) 
SELECT to_char(created, 'DY'::TEXT), created 
FROM compras 
WHERE TRUE 
    AND created >= NOW()::DATE-EXTRACT(DOW FROM NOW())::INTEGER-7 
    AND created < NOW()::DATE-EXTRACT(DOW from NOW())::INTEGER 
+0

Cảm ơn người đàn ông, câu trả lời của bạn đã giúp tôi có được tuần cuối cùng và tuần trước tuần trước. :) –

+1

Sẽ không sử dụng 'GIỮA 'bao gồm nửa đêm vào Chủ Nhật ở cả hai đầu của khoảng thời gian? – d456

+1

@ d456, cảm ơn bạn đã thông báo. Bạn đúng rồi. Tôi đã cập nhật câu trả lời của mình. – Nicolai

9

Postgres theo mặc định bắt đầu tuần vào ngày Chủ nhật, vì vậy bạn sẽ gặp may. Bạn có thể sử dụng date_trunc() để có được sự khởi đầu của tuần trước:

WHERE (created >= date_trunc('week', CURRENT_TIMESTAMP - interval '1 week') and 
     created < date_trunc('week', CURRENT_TIMESTAMP) 
    ) 

EDIT:

Postgres theo mặc định bắt đầu tuần cho date_trunc hôm thứ Hai, nhưng đối với dow vào chủ nhật. Vì vậy, bạn có thể làm những gì bạn muốn bằng cách sử dụng logic đó, mà Nicolai có trong câu trả lời của mình.

+0

Cảm ơn người đàn ông: D.One hơn question.What nếu tôi muốn tuần trước tuần trước? Ý tôi là, tôi sẽ cần lấy dữ liệu từ tuần trước tuần trước và vân vân. –

+0

FYI [Postgres 9.6 tài liệu] (https://www.postgresql.org/docs/9.6/static/functions-datetime.html) nói rằng tuần bắt đầu theo mặc định vào thứ Hai, chứ không phải chủ nhật (phù hợp với ISO-8601 .) Tôi đã xác minh rằng nó là như vậy. – user9645

+0

@ user9645. . . Tôi thấy điều đó. Điều thú vị là việc trích xuất DOW bắt đầu vào tuần chủ nhật. –

Các vấn đề liên quan