Get records from a SQL table that should be there but are not - sql-server-2014

Is it possible to get a list of records that should be in a table but are not?
Here is the scenario: a survey question (caled certificate) is assigned to a number of facilities for a set period of time. Each facility is supposed to respond daily to this survey. The easy way to do this is to create/pre-populate the compliance records in a table and each time a facility responds, mark it as complete (set its ResponseDate). But because I am dealing with thousands of facilities over hundreds of days, it is not feasible. So right now I am doing this in DAL in a very inefficient way, converting the resulting datatable into JSON string and passing it to jQuery DataTable, and I am wondering if this can be achieved using a SQL query.
Here is an example:
Certificate: "Did you do this today"
5 facilities assigned to this certificate spanning May 1 to May 10. So there should be 50 compliance records in total.
This is how I have it set up in DB(just the releveant fields):
Table name: CertItems
CertiItemID CertificateName StartDate EndDate
1 Cert1 05/01/2018 05/10/2018
Table name: FacilityCertificate:
FacCertificateID FacilityID CertItemID
1 100 1
2 200 1
3 300 1
.... ... ...
10 1000 1
Table name: CertComplaince (theoretically, these records should be here, with some facilities having responded to some of the surveys)
CertComplianceID FacCertificateID ResponseDueDate ResponseDate
1 1 05/01/2018 05/01/2018
2 1 05/02/2018
3 1 05/03/2018 05/03/2018
... ... ...
10 1 05/10/2018
11 2 05/01/2018
12 2 05/02/2018 05/02/2018
13 2 05/03/2018
... ... ...
20 2 05/10/2018
... ... ...
98 10 05/08/2018 05/08/2018
99 10 05/09/2018
100 10 05/10/2018
But becuase I cannot pre-populate this table, I enter a record each time a facility responds, so in reality it looks like this:
CertComplianceID FacCertificateID ResponseDueDate ResponseDate
1 1 05/01/2018 05/01/2018
2 1 05/03/2018 05/03/2018
3 2 05/02/2018 05/02/2018
... ... ... ...
15 10 05/08/2018 05/08/2018
Question is how do I get all the records that would be in "theoretical" version of the compliance table having the table above, for a given date range. Something that includes facility ID, CertItemID/Name, ResponseDuedate and responseDate. I amusing SQL Server 2016.

Related

get the scheduling data based on 3 years in mysql

I have one table bibles that having two columns only i.e. is below:-
id chapter_name
1 Mathews 1
2 Mathews 2
3 Mathews 3
4 Mathews 4
... ....
... ....
364 Revelation 22 //Total Records only 364 fixed. that will not increase
Bible Scheduling starts from 5 sept 2021 for 3 years and ends on 31 Aug 2024 i.e basically bible repeats three time in 3 years.
Now Suppose today date is 8 Sept 2021
id chapter_name date_1 date_2 date_3
1 Mathews 1 2021-09-05 2022-09-04 2023-09-03
2 Mathews 2 2021-09-06 2022-09-05 2023-09-04
3 Mathews 3 2021-09-07 2022-09-06 2023-09-05
4 Mathews 4 2021-09-08 2022-09-07 2023-09-06
... ....
... ....
So now requested date is 8 spet 2021 i want to fetch the 4th record Mathews 4 and now suppose today date is 6 sept 2022 and now want to fetch the 3 row Mathews 3.
Note : these date columns are not stored in database. i have only two columns id, chapter_name.. Reason for not storing the dates because after three years i need to update again that dates to make scheduling works. Is there any way to fetch the rows?
Below answer works fine but I have two types of Bibles that starts from Id 1 to 364 another starts from 365 to 1456... 1st case
1 to 364 works.. but 365 to 1456 not works
If I understand correctly, then logic you want is:
where dateadiff(?, '2021-09-05') % 364 = id - 1
The ? is a parameter for the date you pass in.
You can start with some anchor date in the past, 2020-09-06 will do.
The id in your table is a number of days between the anchor date and the current date mod 364 (the number of rows in your table).
SELECT
id, chapter_name
FROM bibles
WHERE
id = DATEDIFF(CURRENT_DATE(), '2020-09-06') % 364 + 1
;
The DATEDIFF(CURRENT_DATE(), '2020-09-06') function returns the number of days between the current date and the anchor date 2020-09-06, i.e. the number of days between the date when the schedule started and now. This number can grow larger than 364 (the number of rows in your table). To "wrap" this number back to 0 when it is larger than 364 we use the modulo division (mod) or % operator. And then add 1, because ids in your table start with 1 (if they started with 0 you didn't have to add 1).
Try to run this query replacing the CURRENT_DATE() with your sample dates 2021-09-08 and 2022-09-06.
SELECT DATEDIFF('2021-09-08', '2020-09-06') % 364 + 1;
returns 4 (4th row)
SELECT DATEDIFF('2022-09-06', '2020-09-06') % 364 + 1;
returns 3 (3rd row)
It means that if you run the full query with the CURRENT_DATE() function on 2021-09-08 it will return a row with id=4. When you run the query on 2022-09-06 it will return a row with id=3.

Get last value in multiple rows MYSQL

I have a table that I use to record the activity log of an application. Now I have to get all records from entity X that have been published in some range of dates. So if a record has been published and later unpublished, it doesn't have to appear in the results.
I don't know how to explain it really, it's find the last appearance of each one and then catch values that are "1" or "0", on depends that I need in each case.
A simplified example (the real table has more fields and more data):
id user_id date model main_relation_id field new_value
1 24 2017-03-21 A 1 publish 1
2 24 2017-03-21 A 2 publish 1
3 24 2017-03-22 A 3 publish 0
4 24 2017-03-22 A 2 update some text
5 24 2017-03-23 A 1 publish 0
6 24 2017-03-23 A 1 update some text
7 24 2017-03-24 A 3 publish 1
8 24 2017-03-24 A 2 publish 0
9 24 2017-03-24 A 2 update some text
10 24 2017-03-25 A 1 publish 1
11 24 2017-03-25 A 2 publish 1
11 24 2017-03-26 A 3 publish 0
I need to get main_relation_id, filtering by model and date, so if I want to get all registers from model A that have been published between 2017-03-21 and 2017-03-24 I'll get:
model_main_relation_id
1
3
and if I want to get all registers that have been unpublished in the same dates, the result have to be:
model_main_relation_id
2
How can I get this result?
So, you would like to filter on the latest status by main_relation_id, whether the particular main_relation_id has been published (field='publish'; new_value=1) or unpublished (field='publish'; new_value=0) within a period.
Since the dates within the date field of the sample data are equal for multiple records, therefore I must assume that a higher value in the id field means later event. Therefore the max(id) per main_relation_id would yield the latest even record.
What I would do is to get the max(id) per main_relation_id within a date range for a particular model in a derived table where field is 'publish' and join this back to your table to find out whether the particular main_relation_id was published:
select table.main_relation_id
from table
inner join
(select main_relation_id, max(id) as maxid
from table
where date>=... and date<=... and `field`='publish' and model='...'
group by main_relation_id) t on table.id=t.maxid
where table.new_value=1
You need to substitute the filter criteria in place of the .... If you would like to get the unpublished data, then replace table.new_value=1 criterion with table.new_value=0.

Sort values in two column and insert order position into another column in mysql

I have a database about sports event that contains:
*User ID
*Amount of Points that the user got on that event
*Time (HH:MM:SS) that took the user to complete track.
How can I first sort them by no. of points, then if two users have same amount of points, by time (shorter is better); and then insert the places to rows?
I have database like that:
ID No. of Points Time Place
------------------------------------
1 15 00:56:00
2 13 00:55:15
3 17 01:00:00
4 17 00:57:00
5 19 00:52:15
I need to have it with places:
ID No. of Points Time Place
------------------------------------
1 15 00:56:00 4
2 13 00:55:15 5
3 17 01:00:00 3
4 17 00:57:00 2
5 19 00:52:15 1
I hope, you understand that. Sorry for bad English.
Best regards,
You can do this with update statement as follows.
SET #placeValue:=0;
UPDATE [Table Name] SET Place=#placeValue:=#placeValue+1 ORDER BY
[Amount of Points] DESC,Time ASC

Best way to select n-th rows based on data in a field for mySQL table

The final result of this will be used for a graphing application where sometimes we would not want the detailed granularity of data at the level it is stored in the table. This may be hard to phrase in a single question so I will give an example:
Example table:
DateTime AddressID Amount
1/1/2015 10:00:00 1 10
1/1/2015 10:00:00 2 8
1/1/2015 10:01:00 1 7
1/1/2015 10:01:00 2 12
1/1/2015 10:02:00 1 21
1/1/2015 10:02:00 2 15
etc...
Note: The times will always have 00 for the seconds - if that helps.
Note: The entries may NOT always have an entry for every minute, but they generally should. So it is possible some might times might be skipped. But there will always be an entry for both addressIDs (1 & 2) every time without fail.
I need to return the above 3 fields, in a period of time requested (for example past 24 hours), but only for certain increments of time FOR EACH OF THE ADDRESS ID's. For example, records for every 5 minutes, or every 10 minutes.
so in the case of 5 minutes it would return:
DateTime AddressID Amount
1/1/2015 10:**00**:00 1 10
1/1/2015 10:**00**:00 2 8
1/1/2015 10:**05**:00 1 11
1/1/2015 10:**05**:00 2 17
1/1/2015 10:**10**:00 1 28
1/1/2015 10:**10**:00 2 5
etc...
Performance is very important. I hope I explained that well enough for someone to get the idea of what I need and I thank you in advance for your suggestions.
EDIT: For clarification, the 5 minutes in the above example should be the minimum time BETWEEN each row. So, if in the above example, on the rare chance that there was a missing time entry for 10:05:00 it should not simply select the 10:10:00 row, it should select the 10:06:00 record and then the next row selected would be 10:11:00, etc.

SQL queries to get (elo)rating history (for graph, highest points etc)

I'm running a site with user ranking-list based on elo-rating.
I want to provide more statistics to users and I have pretty much covered, but cant really figure out how to make queries for these ones.
Players highest ranking points
Players ranking points history (for graph)
MySQL db has two tables for statistics: ranking_statistics which holds overall statistics:
id, ranking, wins, losses, draws, total6m, total8m, total10m
and ranking_matches which holds statistics for matches played:
id, home_id, away_id, home_ranking, away_ranking, home6m, away6m, home8m, away8m, home10m, away10m, datetime
Here is some sample data from ranking_matches:
46 442 456 30 -30 6 6 5 3 3 4 2013-10-14 21:22:58
54 456 480 34.0391 -34.0391 6 4 6 4 2 1 2013-10-16 17:33:37
55 473 475 30 -30 9 9 7 8 6 4 2013-10-17 03:06:41
and from ranking_statistics:
442 1029.97 7 2 6 120 89 55
456 1003.93 6 2 5 99 84 65
I would want to retrieve players highest ranking points on history (ranking_statistics.ranking holds current points) and that could be retrieved from ranking_matches by quering all matches with players id as home or away and then calculating all ranking changes with highest score remembered (starting points is 1000). With this query, a graph of points history would be drawn also.
I have tried to understand how this is done but could not get it by myself and there doesnt seem to be any similar questions posted (or atleast I did not found any)
Results could be also calculated with PHP because all the data is output with it.
Sample output:
Player id: 442
Current rating: 1029.97
Highest rating: 1054.32 (on 10-23-2013)
For history graph, 2 values need to be retrieved to be able to draw a history line graph, date and rankingpoints.