Limit user to post certain number of comments per article - spring

Somehow I'm running in circles for two days! I have MySQL Database and comments table in witch I have id, user_id, date, published_at, body, likes and dislikes. How to limit user for max 10 comments per day. Of course I have user table.
I know I have somehow to count number of comments for certain date and put it in security context but I don't know how. I've tried with some native queries in
Repository like:
#Query(value = "select count from comments WHERE published_at=?1 AND user_id=?2", nativeQuery = true)
public int brojPostovaPoDanuPoUseru(Date datum, Integer user_id);
I guess I should find logged user name from SecurityContext and after that find his id, but then again what if there are two users with a same name, and where to use SecurityContext to find this.
At least some guidelines please :)

You can implement this on database level. My idea would be to save the time in seconds in date ( using Java: System.currentTimeMillis()). Then when you query by the user id, you can sort the results by date in descending order and filter for the top 10. Then you would pick the smallest number in date and check if it was less then 24h ago, if so you could then return an exception.
This would be an example query:
select * from (SELECT * FROM `comments` where comments.user_id=?1 ORDER BY `comments`.`date` DESC limit 10) as c order by c.date ASC limit 1
Let's say you saved date in secods using System.currentTimeMillis() / 1000. Now with the query result you would first calculate the seconds in hours and then in a day. This results in 86400 seconds. Now you would calculate the current time in seconds and extract it with the 24h in seconds as calculated before. And then you would check if this calculated result is smaller than the value of date this would indicate that the last 10th comment was made within the 24 hours.
This is the sample code in your repository:
#Query("select * from (SELECT * FROM `comments` where comments.user_id=?1 ORDER BY `comments`.`date` DESC limit 10) as c order by c.date ASC limit 1", nativeQuery=true)
public Comments getLastTenthComment(int userId);
This is the sample code in your service:
public boolean isAllowedToComment(int userId){
Comment comment = repository.getLastTenthComment(userId);
int dayInSeconds = 86400;
long currentTime = System.currentTimeMillis() / 1000;
long yesterdayInSeconds = currentTime - dayInSeconds;
if(comment.getDate() >= yesterdayInSeconds){
return false;
}
return true;
}

Related

Why does my total session (aggregated using EXTRACT MONTH) is less than total session if I broke down by the date?

I'm trying to generate my total session by month. I've tried using two different ways.
I'm using date field for the first column
I'm using month field that is extracted from date field using EXTRACT(MONTH FROM date) AS month
I have tried using below code for the 1st one:
with
session1 as(
select date,
session_id
from table
where date >= '2019-05-20' AND date <= '2019-05-21')
SELECT date_key, COUNT(DISTINCT session_id) AS sessions from session1
GROUP BY 1
For the 2nd one I tried using this code:
with
session1 as(
select date,
session_id
from table
where date >= '2019-05-20' AND date <= '2019-05-21')
SELECT EXTRACT (MONTH FROM date_key) AS month, COUNT(DISTINCT session_id) AS sessions from session1
GROUP BY 1
For the result, I got the output as per below:
20 May: 1,548 Sessions; 21 May: 1,471 Sessions; Total: 3,019
May: 2,905
So, there's 114 session discrepancy and I'd like to know why.
Thank you in advance.
For simplicity sake - let's say there is only one session during two consecutive days. So if you will count by day and then sum result - you will get 2 sessions, while if you will count distinct sessions for whole two days - you will get just 1 session
Hope this shows you the reason why - you are counting some sessions twice on different days - maybe when they go over end of one and start of next day
The following query should show you which sessions_ids occur on both dates.
select session_id, count(distinct date) as num_dates
from table
where date >= '2019-05-20' AND date <= '2019-05-21'
group by 1
having num_dates > 1
This is either a data processing issue, or your session definition is allowed to span multiple days. Google Analytics, for example, traditionally ends a session and begins a new session at midnight. Other sessionization schemes might not impose this restriction.

How to select the closest data to the given time for each group

I'm using InfluxDB 1.4, and here's my task
1) find the closet value for each IDs.
2) Do 1) for every hour
For example,
select id, value, time from myTable where time = '2018-08-14T00:00:00Z' group by id;
select id, value, time from myTable where time = '2018-08-14T01:00:00Z' group by id;
....
select id, value, time from myTable where time = '2018-08-14T23:00:00Z' group by id;
then, some id have value at each o'clock but others don't. In this case, I want to get the closest row to the give time '2018-08-14T14:00:00Z', like as '2018-08-14T14:00:01Z' or '2018-08-14T13:59:59Z'
and I don't want to query 24 times for each hour. Can I do this task with group by time, id, or something else?
Q: I would like to select the point data closest to the hourly boundary. Is there a way I can do this without having to query 24 times for each day? Will group by time be any help on this?
A:
Will group by time be any help on this?
Unfortunately the group by time function will not be much help to you as it requires the query to have an aggregation function. What the group by time function does is that it groups all data that falls within the interval into one single record by using the aggregation function like sum, mean etc to tabulate the combined row's values.
Is there a way I can do this without having to query 24 times for each
day?
To the best of my knowledge, I don't think influxdb 1.5 has any way to build a one liner query for this task. Maybe there is something in 1.6, i'm not sure. Haven't tried that.
At the moment I think your best solution today is to build a query that uses the time filter, order by and limit functions e.g.
select * from uv where time >= '2018-08-18T14:00:00Z' and time < '2018-08-18T15:00:00Z' order by desc limit 1;
The query above means that you are selecting all the points within 2pm to 3pm and then order them by descending order but only return the first row, which is what you want.
If for some reason you can only do 1 HTTP request to influxdb for the hourly data on a particular day. You can bundle up the 24 queries into one big query using the ; seperator and retrieve the data in 1 transaction. E.g.
select * from uv where time >= '2018-08-18T14:00:00Z' and time < '2018-08-18T15:00:00Z' order by desc limit 1; select * from uv where time >= '2018-08-18T15:00:00Z' and time < '2018-08-18T16:00:00Z' order by desc limit 1; select * from uv where time >= '2018-08-18T16:00:00Z' and time < '2018-08-18T17:00:00Z' order by desc limit 1;
Output:
name: uv
time tag1 id value
---- -------- -- -----
1534603500000000000 apple uv 2
1534607100000000000 apple uv 1
1534610700000000000 apple uv 3.1

DAX AVG of Group Applied but returned for one specific Employee?

I have data as follows
EmployeeID Cycle Val Group
1 1 6 A
2 1 5 A
My desired result is as follows:
EmployeeID Cycle GroupVal
1 1 5.5
2 1 5.5
I have written 2 Measures as follows:
Emp_AVG: CALCULATE(AVERAGE(EmployeeFeedback, EmployeeFeedback[Val] > 0)
Group_AVG: CALCULATE(AVERAGEX(EmployeeFeedback[Emp_AVG],EmployeeFeedback[Emp_AVG] >0)
My thought process is that the Group_AVG is averaging the avg of all employees PER GROUP however since i need the results for a SPECIFIC employee, as soon as i introduce that column, it starts slicing by the Employee and the Group avg becomes inaccurate. I guess i need to generate Group Avgs before i do any employee filtering..how?
I am running a DAX query as follows:
EVALUATE SUMMARIZECOLUMNS(
EmployeeFeedback[EmployeeID],
EmployeeFeedback[Cycle],
"Group Val", [Group_AVG]
)
I need the EmployeeID to filter it down to an employee but because of EmployeeID, the Group AVG gets screwed. Without EmployeeID, Group AVG is correct but then there is no way to filter it for a specific Employee!
Thanks!
You could try to provide the ALLEXCEPT() argument to the CALCULATE function.
Btw, I believe there's an error in your Emp_AVG measure.
Try this:
Employee Average
Emp_AVG =
CALCULATE(
AVERAGE(EmployeeFeedback[Val]),
EmployeeFeedback[Val] > 0)
Group Average
Grp_Avg =
CALCULATE(EmployeeFeedback[Emp_AVG],
ALLEXCEPT(EmployeeFeedback,EmployeeFeedback[Group]))
Result:

query by day in PL/SQL(oracle)

I am querying from database:
select * from database where id = 12345
and i get a couple of days where it is equal to
3/4/2010 9:16:59 AM
but if i add
and date = to_date('03/04/2010','DD/MM/YYYY')
giving me
select * from database where id = 12345
and date = to_date('03/04/2010','DD/MM/YYYY')
I comeback with completely nothing.
Any pointers?
btw, I know that there is a time on there, but I don't know how to compare just based on the day!!!
That's because when you are creating the date, you implicitly set the time to 0:00:00, and as 0:00:00 is not equal to 9:16:59, you'll not get the date returned.
To tell Oracle to ignore the time part, just do the following:
WHERE id = 12345
AND trunc(date) = to_date('03/04/2010', 'DD/MM/YYYY')
WHERE id = 12345
AND date >= TO_DATE('03/04/2010', 'DD/MM/YYYY')
AND date < TO_DATE('03/04/2010', 'DD/MM/YYYY') + INTERVAL '1' DAY
http://use-the-index-luke.com/sql/where-clause/obfuscation/dates

oracle query need to compare and get result in the same query

I have a query which fetch record from one db and insert it into another db across servers using script.
the query is like :-
select id, date, iscomplete
from sourcedb.test where id = '1'
and date = '2011-03-15' and iscomplete = 1;
this query returns me some records, which i want only when there are certain number of records.
for ex:- there are 10 records for '2011-03-15' then I want to fetch those 10 records only when is complete is 1 for all the 10 records.
I dont want to hardcode it as records can increase in near future from 10 to 20.
Is there any way I can modify my original query and check if iscomplete = 1 for all the records for that day then fetch the records else return nothing.
I need to add one more condition to this query that is if there are 10 records and half of them are completed i.e. isComplete = 1 and half of them are isComplete <> 1 in this case I dont want any output from the query untill and unless all the record has isComplete = 1.
Regards,
Manasi
Just make the next check
select id, date, iscomplete
from sourcedb.test
where id = '1'
and date = '2011-03-15'
and not exists (select 1 from sourcedb.test where id = '1'
and date = '2011-03-15' and isComplete <> 1);

Resources