How to list records with date from the last 10 days?
Yes this does work in PostgreSQL (assuming the column "date" is of datatype date
)
Why don't you just try it?
The standard ANSI SQL format would be:
SELECT Table.date
FROM Table
WHERE date > current_date - interval '10' day;
I prefer that format as it makes things easier to read (but it is the same as current_date - 10
).
Select data for last 10 days
You just need to chop off the time portion from date and group by this:
SELECT DATE(created_at) AS Date, SUM(amount) AS Total_Amount, COUNT(*) AS Num_Transactions
FROM t
GROUP BY DATE(created_at)
To restrict the results to last 10 days use the following where clause:
-- 10 days including today
WHERE created_at >= CURRENT_DATE - INTERVAL 9 DAY
AND created_at < CURRENT_DATE + INTERVAL 1 DAY
-- 10 days excluding today
WHERE created_at >= CURRENT_DATE - INTERVAL 10 DAY
AND created_at < CURRENT_DATE
-- 10 days from current time
WHERE created_at > CURRENT_TIMESTAMP - INTERVAL 10 DAY
AND created_at <= CURRENT_TIMESTAMP
Get rows for the last 10 dates
This looks unsuspicious, but it's a hell of a question.
Assumptions
- Your counts are
integer
. - All columns in table book are defined
NOT NULL
. The composite
(name, sid, date)
is unique in tablebook
. You should have aUNIQUE
constraint, preferably (for performance) with columns in this order:UNIQUE(sid, date, name)
This provides the index needed for performance automatically. (Else create one.) See:
- Multicolumn index and performance
- Is a composite index also good for queries on the first field?
crosstab()
queries
To get top performance and short query strings (especially if you run this query often) I suggest the additional module tablefunc
providing various crosstab()
functions. Basic instructions:
- PostgreSQL Crosstab Query
Basic queries
You need to get these right first.
The last 10 days:
SELECT DISTINCT date
FROM book
WHERE sid = 1
ORDER BY date DESC
LIMIT 10;
Numbers for last 10 days using the window function dense_rank()
:
SELECT *
FROM (
SELECT name
, dense_rank() OVER (ORDER BY date DESC) AS date_rnk
, count
FROM book
WHERE sid = 1
) sub
WHERE date_rnk < 11
ORDER BY name, date_rnk DESC;
(Not including actual dates in this query.)
Column names for output columns (for full solution):
SELECT 'bookname, "' || string_agg(to_char(date, 'DD/MM/YYYY'), '", "' ORDER BY date) || '"'
FROM (
SELECT DISTINCT date
FROM book
WHERE sid = 1
ORDER BY date DESC
LIMIT 10
) sub;
Simple result with static column names
This may be good enough for you - but we don't see actual dates in the result:
SELECT * FROM crosstab(
'SELECT *
FROM (
SELECT name
, dense_rank() OVER (ORDER BY date DESC) AS date_rnk
, count
FROM book
WHERE sid = 1
) sub
WHERE date_rnk < 11
ORDER BY name, date_rnk DESC'
, 'SELECT generate_series(10, 1, -1)'
) AS (bookname text
, date1 int, date2 int, date3 int, date4 int, date5 int
, date6 int, date7 int, date8 int, date9 int, date10 int);
For repeated use I suggest you create this (very fast) generic C function for 10 integer columns once, to simplify things a bit:
CREATE OR REPLACE FUNCTION crosstab_int10(text, text)
RETURNS TABLE (bookname text
, date1 int, date2 int, date3 int, date4 int, date5 int
, date6 int, date7 int, date8 int, date9 int, date10 int)
LANGUAGE C STABLE STRICT AS
'$libdir/tablefunc','crosstab_hash';
Details in this related answer:
- Dynamically generate columns for crosstab in PostgreSQL
Then your call becomes:
SELECT * FROM crosstab(
'SELECT *
FROM (
SELECT name
, dense_rank() OVER (ORDER BY date DESC) AS date_rnk
, count
FROM book
WHERE sid = 1
) sub
WHERE date_rnk < 11
ORDER BY name, date_rnk DESC'
, 'SELECT generate_series(10, 1, -1)'
); -- no column definition list required!
Full solution with dynamic column names
Your actual question is more complicated, you also want dynamic column names.
For a given table, the resulting query could look like this then:
SELECT * FROM crosstab_int10(
'SELECT *
FROM (
SELECT name
, dense_rank() OVER (ORDER BY date DESC) AS date_rnk
, count
FROM book
WHERE sid = 1
) sub
WHERE date_rnk < 11
ORDER BY name, date_rnk DESC'
, 'SELECT generate_series(10, 1, -1)'
) AS t(bookname
, "04/11/2015", "05/11/2015", "06/11/2015", "07/11/2015", "08/11/2015"
, "09/11/2015", "10/11/2015", "11/11/2015", "15/11/2015", "17/11/2015");
The difficulty is to distill dynamic column names. Either assemble the query string by hand, or (much rather) let this function do it for you:
CREATE OR REPLACE FUNCTION f_generate_date10_sql(_sid int = 1)
RETURNS text
LANGUAGE sql AS
$func$
SELECT format(
$$SELECT * FROM crosstab_int10(
'SELECT *
FROM (
SELECT name
, dense_rank() OVER (ORDER BY date DESC) AS date_rnk
, count
FROM book
WHERE sid = %1$s
) sub
WHERE date_rnk < 11
ORDER BY name, date_rnk DESC'
, 'SELECT generate_series(10, 1, -1)'
) AS ct(bookname, "$$
|| string_agg(to_char(date, 'DD/MM/YYYY'), '", "' ORDER BY date) || '")'
, _sid)
FROM (
SELECT DISTINCT date
FROM book
WHERE sid = 1
ORDER BY date DESC
LIMIT 10
) sub
$func$;
Call:
SELECT f_generate_date10_sql(1);
This generates the desired query, which you execute in turn.
db<>fiddle here
Count data for last 10 days including days without any entries
Keep your join LEFT , stop using LEFT columns in NULL -prohibiting predicates in WHERE. Include it in ON
with amonth(day) as
(
select @end as day
union all
select day + 1
from amonth
where day < CAST(@start as date)
)
select CAST(amonth.day as date) as dat, count(vrijeme) as c
from amonth
left join Dnevnik on CAST(vrijeme as date) = CAST(amonth.day as date)
and tipZapisa = 6
group by CAST(amonth.day as date) order by dat
SQL to get all data for the last 30 days from a PostgreSQL database
Just use current_timestamp
(documented here):
select *
from school
where created_time > current_timestamp - interval '30 day';
Return last 10 days data by date using Entity Framework
var tenDaysAgo = DateTime.Today.AddDays(-10);
var Chart = dbcontext.CampaignEmails.Where(x => x.DateSigned >= tenDaysAgo).ToList();
Is what you are looking for i guess.
If you only want 10 records you can use Take() LINQ method before the ToList() call.
Furthermore, you may need to order your results before even accessing them with a OrderBy().
Related Topics
MySQL Auto-Store Datetime for Each Row
How to Drop Multiple Tables in Postgresql Using a Wildcard
How to Group by Week in Postgresql
When to Use an Enum or a Small Table in a Relational Database
Postgres - Create Table from Select
Postgresql: Create Table If Not Exists As
How to Get SQL Error in Stored Procedure
SQL Server Query for Rank (Rownumber) and Groupings
How Do We Implement an Is-A Relationship
Why Does SQL Server Keep Executing After Raiserror When Xact_Abort Is On
What Free SQL Formatting Tools Exist
How to Get Week Start and End Date String in Postgresql
Is There Something Equivalent to Argmax in SQL
Postgresql 9.1: How to Concatenate Rows in Array Without Duplicates, Join Another Table
Tsql: Call a Stored Procedure from Another Stored Procedure and Read the Result