sparql getting all months between two dates SPARQL - date
I am working on a SPARQL query in TopBraid Composer to get the number of data quality rules in each month.
I have a Start Date and End Date, but I need to get all the months between the start date and end date so that I can get a count of the data quality rules applicable to that duration.
My current query and result is as follows-:
SELECT *
WHERE
{
?Rules CDE:Data_Quality_Rule_added_on ?Date1.
?Rules CDE:Data_Quality_Removed_On ?Date2
BIND(month(?Date1) AS ?Month1)
BIND(month(?Date2) AS ?Month2)
BIND(smf:duration("mon",?Date1,?Date2) AS ?dur)
}
LIMIT 5
| [Rules] | Date1 | Date2 | Month1 | Month2 | dur
| CDE:Data_Quality_Rule_13 | 2016-01-28 | 2016-09-15 | 01 | 09 | 8
| CDE:Data_Quality_Rule_16 | 2016-02-29 | 2016-08-08 | 02 | 08 | 5
| CDE:Data_Quality_Rule_18 | 2016-05-15 | 2016-10-31 | 05 | 10 | 6
| CDE:Data_Quality_Rule_4 | 2016-03-28 | 2016-07-02 | 03 | 07 | 3
| CDE:Data_Quality_Rule_5 | 2016-02-02 | 2016-06-06 | 02 | 06 | 4
I am able to get the start month,end month and the duration. But I would like to get all the months between the start month and end month in SPARQL. The end result is to get the month-wise count of the number of data qulaity rules based on the start and end date as follows-:
| Months | Number Of Data Quality Rules |
| 1 | 2
| 2 | 4
| 3 | 6
| 4 | 3
| 5 | 3
| 6 | 4
| 7 | 4
| 8 | 4
| 9 | 5
| 10 | 3
| 11 | 2
| 12 | 5
First, some data to work with that has some rules with begin and end dates:
#prefix : <urn:ex:>
#prefix xsd: <http://www.w3.org/2001/XMLSchema#>
:rule1 :begin "2011-01-10T14:45:13.815-05:00"^^xsd:dateTime ;
:end "2011-06-10T14:45:13.815-05:00"^^xsd:dateTime .
:rule2 :begin "2011-04-10T14:45:13.815-05:00"^^xsd:dateTime ;
:end "2011-10-10T14:45:13.815-05:00"^^xsd:dateTime .
:rule3 :begin "2011-06-10T14:45:13.815-05:00"^^xsd:dateTime ;
:end "2011-11-10T14:45:13.815-05:00"^^xsd:dateTime .
Then you can write a query that gets the months in which each rule is active. IF you then group by the month, and count the number of rules, you get the number of rules active in each month:
prefix : <urn:ex:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?rule ?month {
#-- Specify the possible values for ?month
#-- in advance. These are just the numbers
#-- one through twelve.
values ?month { 1 2 3 4 5 6 7 8 9 10 11 12 }
#-- Get the begin and end dates of that
#-- you're interested in. The way you
#-- do this depends on the structure of
#-- your data, of course.
?rule :begin ?begin ; :end ?end .
#-- Then take only the values of ?month
#-- that are between the beginning month
#-- and the ending month.
filter ( month(?begin) <= ?month && ?month <= month(?end) )
}
------------------
| rule | month |
==================
| :rule1 | 1 |
| :rule1 | 2 |
| :rule1 | 3 |
| :rule1 | 4 |
| :rule1 | 5 |
| :rule1 | 6 |
| :rule2 | 4 |
| :rule2 | 5 |
| :rule2 | 6 |
| :rule2 | 7 |
| :rule2 | 8 |
| :rule2 | 9 |
| :rule2 | 10 |
| :rule3 | 6 |
| :rule3 | 7 |
| :rule3 | 8 |
| :rule3 | 9 |
| :rule3 | 10 |
| :rule3 | 11 |
------------------
Now you can group those results by month, and then count the number of rules for each month:
prefix : <urn:ex:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?month (count(distinct ?rule) as ?numRules) where {
values ?month { 1 2 3 4 5 6 7 8 9 10 11 12 }
?rule :begin ?begin ; :end ?end .
filter ( month(?begin) <= ?month && ?month <= month(?end) )
}
group by ?month
--------------------
| month | numRules |
====================
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 2 |
| 8 | 2 |
| 9 | 2 |
| 10 | 2 |
| 11 | 1 |
--------------------
That doesn't include month 12 in the result, because there were no rules active then. If you want all the months to be listed, you can make the rule matching part optional:
prefix : <urn:ex:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?month (count(distinct ?rule) as ?numRules) {
values ?month { 1 2 3 4 5 6 7 8 9 10 11 12 }
optional {
?rule :begin ?begin ; :end ?end .
filter ( month(?begin) <= ?month && ?month <= month(?end) )
}
}
group by ?month
--------------------
| month | numRules |
====================
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 2 |
| 8 | 2 |
| 9 | 2 |
| 10 | 2 |
| 11 | 1 |
| 12 | 0 |
--------------------
Related
partition by for iterval of 2 seconds
I have a DB with a field of timestamp, I want to partition it for every 2 seconds (I know how to do it for 1 minute and one second) this is an example of the DB: create table data_t(id integer, time_t timestamp without time zone, data_t integer ); insert into data_t(id,time_t,data_t) values(1,'1999-01-08 04:05:06',248), (2,'1999-01-08 04:05:06.03',45), (3,'1999-01-08 04:05:06.035',98), (4,'1999-01-08 04:05:06.9',57), (5,'1999-01-08 04:05:07',86), (6,'1999-01-08 04:05:08',84), (7,'1999-01-08 04:05:08.5',832), (8,'1999-01-08 04:05:08.7',86), (9,'1999-01-08 04:05:08.9',863), (10,'1999-01-08 04:05:9',866), (11,'1999-01-08 04:05:10',862), (12,'1999-01-08 04:05:10.5',863), (13,'1999-01-08 04:05:10.55',826), (14,'1999-01-08 04:05:11',816), (15,'1999-01-08 04:05:11.7',186), (16,'1999-01-08 04:05:12',862), (17,'1999-01-08 04:05:12.5',826) ; with t as ( select id, time_t, date_trunc('second', data_t.time_t) as time_t_1, data_t from data_t ), t1 as( select *, extract(hour from time_t_1) as h, extract(minute from time_t_1) as m, extract(second from time_t_1) as s from t ) select *, row_number() over(partition by h,m,s order by time_t_1) as t_sequence from t1; the output of this is: | id | time_t | time_t_1 | data_t | h | m | s | t_sequence | |----|--------------------------|----------------------|--------|---|---|----|------------| | 1 | 1999-01-08T04:05:06Z | 1999-01-08T04:05:06Z | 248 | 4 | 5 | 6 | 1 | | 2 | 1999-01-08T04:05:06.03Z | 1999-01-08T04:05:06Z | 45 | 4 | 5 | 6 | 2 | | 3 | 1999-01-08T04:05:06.035Z | 1999-01-08T04:05:06Z | 98 | 4 | 5 | 6 | 3 | | 4 | 1999-01-08T04:05:06.9Z | 1999-01-08T04:05:06Z | 57 | 4 | 5 | 6 | 4 | | 5 | 1999-01-08T04:05:07Z | 1999-01-08T04:05:07Z | 86 | 4 | 5 | 7 | 1 | | 6 | 1999-01-08T04:05:08Z | 1999-01-08T04:05:08Z | 84 | 4 | 5 | 8 | 1 | | 7 | 1999-01-08T04:05:08.5Z | 1999-01-08T04:05:08Z | 832 | 4 | 5 | 8 | 2 | | 8 | 1999-01-08T04:05:08.7Z | 1999-01-08T04:05:08Z | 86 | 4 | 5 | 8 | 3 | | 9 | 1999-01-08T04:05:08.9Z | 1999-01-08T04:05:08Z | 863 | 4 | 5 | 8 | 4 | | 10 | 1999-01-08T04:05:09Z | 1999-01-08T04:05:09Z | 866 | 4 | 5 | 9 | 1 | | 11 | 1999-01-08T04:05:10Z | 1999-01-08T04:05:10Z | 862 | 4 | 5 | 10 | 1 | | 12 | 1999-01-08T04:05:10.5Z | 1999-01-08T04:05:10Z | 863 | 4 | 5 | 10 | 2 | | 13 | 1999-01-08T04:05:10.55Z | 1999-01-08T04:05:10Z | 826 | 4 | 5 | 10 | 3 | | 14 | 1999-01-08T04:05:11Z | 1999-01-08T04:05:11Z | 816 | 4 | 5 | 11 | 1 | | 15 | 1999-01-08T04:05:11.7Z | 1999-01-08T04:05:11Z | 186 | 4 | 5 | 11 | 2 | | 16 | 1999-01-08T04:05:12Z | 1999-01-08T04:05:12Z | 862 | 4 | 5 | 12 | 1 | | 17 | 1999-01-08T04:05:12.5Z | 1999-01-08T04:05:12Z | 826 | 4 | 5 | 12 | 2 | as you can see the t_sequence start over every second but I want it to start over every 2 seconds, is there a way to do it? link for SQL fiddle with all the data
count continuously postgresql data
i need help with counting some data this what i want | user_id | action_id | count | ------------------------------------- | 1 | 1 | 1 | | 2 | 2 | 1 | | 3 | 2 | 2 | | 4 | 3 | 1 | | 5 | 3 | 2 | | 6 | 3 | 3 | | 7 | 4 | 1 | | 8 | 5 | 1 | | 9 | 5 | 2 | | 10 | 6 | 1 | this is what i have | user_id | action_id | count | ------------------------------- | 1 | 1 | 1 | | 2 | 2 | 1 | | 3 | 2 | 1 | | 4 | 3 | 1 | | 5 | 3 | 1 | | 6 | 3 | 1 | | 7 | 4 | 1 | | 8 | 5 | 1 | | 9 | 5 | 1 | | 10 | 6 | 1 | i really need it for create some research about second action from users how do i do it? thank you
Using ROW_NUMBER should work here: SELECT user_id, action_id, ROW_NUMBER() OVER (PARTITION BY action_id ORDER BY user_id) count FROM yourTable ORDER BY user_id; Demo
Rank based on row number SQL Server 2008 R2
I want to group rank my table data by rowcount. First 12 rows that are ordered by date for each ProductID would get value = 1. Next 12 rows would get value = 2 assigned and so on. How table structure looks: For ProductID = 1267 are below associated dates: 02-01-2016 03-01-2016 . . (skipping months..table has one date per month) . 12-01-2016 02-01-2017 . . . 02-01-2018
Use row_number() over() with some arithmetic to calculate groups of 12 ordered by date (per productid). Change the sort to ASCendng or DESCendng to suit your need. select * , (11 + row_number() over(partition by productid order by somedate DESC)) / 12 as rnk from mytable GO myTableID | productid | somedate | rnk --------: | :------------- | :------------------ | :-- 9 | 123456 | 2018-11-12 08:24:25 | 1 8 | 123456 | 2018-10-02 12:29:04 | 1 7 | 123456 | 2018-09-09 02:39:30 | 1 2 | 123456 | 2018-09-02 08:49:37 | 1 1 | 123456 | 2018-07-04 12:25:06 | 1 5 | 123456 | 2018-06-06 11:38:50 | 1 12 | 123456 | 2018-05-23 21:12:03 | 1 18 | 123456 | 2018-04-02 03:59:16 | 1 3 | 123456 | 2018-01-02 03:42:24 | 1 17 | 123456 | 2017-11-29 03:19:32 | 1 10 | 123456 | 2017-11-10 00:45:41 | 1 13 | 123456 | 2017-11-05 09:53:38 | 1 16 | 123456 | 2017-10-20 15:39:42 | 2 4 | 123456 | 2017-10-14 19:25:30 | 2 20 | 123456 | 2017-09-21 21:31:06 | 2 6 | 123456 | 2017-04-06 22:10:58 | 2 14 | 123456 | 2017-03-24 23:35:52 | 2 19 | 123456 | 2017-01-22 05:07:23 | 2 11 | 123456 | 2016-12-13 19:17:08 | 2 15 | 123456 | 2016-12-02 03:22:32 | 2 dbfiddle here
Tibco Spotfire - Calculate average only if there are minimum 3 values in a column - see desc
I want to calculate average in Spotfire only when there are minimum 3 values. if there are no values or just 2 values the average should be blank Raw data: Product Age Average 1 2 3 10 4 12 5 13 11 6 7 18 8 19 9 20 19 10 21 20
The only way I could really do this is with 3 calculated columns. Insert these calculated columns in this order: If(Min(If([Age] IS NULL,0,[Age])) over (LastPeriods(3,[Product]))<>0,1) as [BitFlag] Avg([Age]) over (LastPeriods(3,[Product])) as [TempAvg] If([BitFlag]=1,[TempAvg]) as [Average] This will give you the following results. You can ignore / hide the two columns you don't care about. RESULTS +---------+-----+---------+------------------+------------------+ | Product | Age | BitFlag | TempAvg | Average | +---------+-----+---------+------------------+------------------+ | 1 | | | | | | 2 | | | | | | 3 | 10 | | 10 | | | 4 | 12 | | 11 | | | 5 | 13 | 1 | 11.6666666666667 | 11.6666666666667 | | 6 | | | 12.5 | | | 7 | 18 | | 15.5 | | | 8 | 19 | | 18.5 | | | 9 | 20 | 1 | 19 | 19 | | 10 | 21 | 1 | 20 | 20 | | 11 | | | 20.5 | | | 12 | 22 | | 21.5 | | | 13 | 36 | | 29 | | | 14 | | | 29 | | | 15 | 11 | | 23.5 | | | 16 | 23 | | 17 | | | 17 | 14 | 1 | 16 | 16 | +---------+-----+---------+------------------+------------------+
Create daily report using crosstabs
I know that crosstabs are just for summaries. But is it possible to use a crosstab for daily reports given two dates? It's more like a details summary. For example: Date: 10 August 2012 Start Date: 10/8/2012 End Date: 11/8/2012 Date: 10 August 2012 _________| Center 1 | Center 2 | Total | Person 1 | 1 | 2 | 3 | Person 2 | 2 | 5 | 7 | TOTAL | 3 | 7 | 10 | Date: 11 August 2012 _________| Center 1 | Center 2 | Total | Person 1 | 5 | 2 | 7 | Person 2 | 8 | 5 | 13 | TOTAL | 13 | 7 | 20 |
Unfortunately, you'd have to have each date as a row in the crosstab, and I think this is the best you'll be able to get: 10 August 2012|_________| Center 1 | Center 2 | Total | |Person 1 | 1 | 2 | 3 | |Person 2 | 2 | 5 | 7 | |TOTAL | 3 | 7 | 10 | 11 August 2012|_________| Center 1 | Center 2 | Total | |Person 1 | 5 | 2 | 7 | |Person 2 | 8 | 5 | 13 | |TOTAL | 13 | 7 | 20 | |GRAND | 16 | 14 | 30 | |TOTAL | | | | So your setup would be: Center Total ----+--------+-------+------+ Date| | | | |Person | | |