FaunaDB: iterate on documents while updating them - faunadb

I'm using FaunaDB, and I have a collection of documents I'd like to iterate over while updating them and coupling them.
Some simplified samples from the collection in CSV format:
ID; Status; Owner; CouplingFactor
1; WAITING; Alice A
2; WAITING; Bob A
3; CLOSED; Chad A
4; WAITING; Alice B
5; WAITING; Alice A
6; WAITING; Chad B
The main idea is to loop over them to couple them based on the value of coupling factor, but only if they are owned by different persons and if they're in WAITING state; as soon as I find a matching couple, I must set the status to CLOSED and create another document in another collection.
So, the final result of the loop over the above collection should be the creation of 2 documents:
Document 1: referencing ID 1 and ID 2 (both A-WAITING, owned by different persons)
Document 2: referencing ID 4 and ID 6 (both B-WAITING, owned by different persons)
ID 3 is CLOSED, cannot be used. ID 5 can be used but there's no other A-WAITING document available not owned by Alice.
Final result of the initial collection will be:
ID; Status; Owner; CouplingFactor
1; CLOSED; Alice A
2; CLOSED; Bob A
3; CLOSED; Chad A
4; CLOSED; Alice B
5; WAITING; Alice A
6; CLOSED; Chad B
How to do this in a single transaction? I cannot find the best way (or better: A way) to do this with FQL without doing a lot of single queries from the application layer (which I think I should avoid, because I need atomicity: no one can change those documents while I'm iterating).

Related

Keeping an updated tally of changing records

I have a list of students and their subjects:
id | student | subject
---|---------|--------
1 | adam | math
2 | bob | english
3 | charlie | math
4 | dan | english
5 | erik | math
And I create a tally from the above list aggregating how many students are there in each subject:
id | subject | students
---|---------|--------
1 | math | 3
2 | english | 2
The student list will keep on expanding and this aggregation will be done at regular intervals.
The reason I'm keeping the Tally in a separate table in the first place is because the original table is supposed to be massive (this is just a simplification of my original problem) and so querying the original table for a current tally on-the-fly is unfeasible to do quickly enough.
Anyways, so the aggregating is pretty straight forward as long as the students don't change their subject.
But now I want to add a feature to allow students to change their subject.
My previous approach was this: while updating the Tally, I keep a counter variable up to which row of students I've already accounted for. Next time I only consider records added after that row.
Also the reason why I keep a counter is because the Students table is massive, and I don't want to scan the whole table every time as it won't scale well.
It works fine if all students are unique and no one changes their subject.
But it breaks apart now because I can no longer account for rows that come before the counter and were updated.
My second approach was using a updated_at field (instead of counter) and keep track of newly modified rows that way.
But still I don't know how to actually update the Tally accurately.
Say, Erik changes his subject from "math" to "english" in the above scenario. When I run the script to update the Tally, while it does finds the newly updated row but it simply says {"erik": "english"}. How would I know what it changed from? I need to know this to correctly decrement "math" in the Tally table while incrementing "english".
Is there a way this can be solved?
To summarize my question again, I want to find a way to be able to update the Tally table accurately (a process that runs at regular interval) with the updated/modified rows in the Student table.
I'm using NodeJS and PostgreSQL if it matters.
Why don't you do it when student add subject, remove subject, or change subject.
When student add new subject: Just increase UPDATE tbl_tally SET student = student + 1 WHERE subject = :subject;
When student remove subject: Just decrease UPDATE tbl_tally SET student = student - 1 WHERE subject = :subject;
When student change subject: Just increase new subject by one and decrease old subject by one
UPDATE tbl_tally SET student = student - 1 WHERE subject = :old_subject;
UPDATE tbl_tally SET student = student + 1 WHERE subject = :new_subject;
I am not familiar with PostgreSQL, but in MySQL, you can even do it with trigger. I think PostgreSQL also has trigger.

SQL - Tracking student exam records as they move between schools

I'd like to pick some of your glorious minds for an optimal solution to my dilemma.
Scenario:
Schools have children and children take tests.
The tests point to the child, not the school.
If the child moves school, the test records are taken to the new school and the previous school has no record of the test being done as they are linked to the child.
Obviously, this isn't ideal and is the result of the database not being designed with this in mind. What would the correct course of action be; I’ve currently identified the 3 possibilities listed below which would solve the current problem. However, i cannot be sure which is best for the issue at hand - and if any better solutions exist.
Have each test store the school & student within the test records (requiring current records to be updated & increasing the size of the database)
Create a new child record, duplicating the existing data for the new school with a new ID so the test remains linked to the previous school (complicating the ability to identify previous test scores)
Separately keep track of moves to other schools, then use this additional table to identify current and previous using the timestamps (increased complexity and computational requirements)
EDIT:
So i tried to use a basic example, but requests for the task at hand have been requested.
Here's the DB Schema for the tables (simplified for problem, note: Postnatal is not important):
Patients: ID, MidwifeID, TeamID
Midwives: ID
Groups: ID
GroupsMidwives: MidwifeID, GroupsID
PatientObservations: ID, MidwifeID, PatientID
Using a query as follows:
SELECT Some Information
from Postnatals
JOIN Midwives on Postnatals.MidwifeID = Midwives.ID
JOIN Patients on Patients.PatientID = Postnatals.PatientID
JOIN GroupsMidwives on GroupsMidwives.MidwifeID = Midwives.ID
JOIN Groups on Groups.ID = GroupsMidwives.GroupID
JOIN PatientObservations on PatientObservations.PatientID =
Postnatals.PatientID
WHERE groups.Name = ?
*some extra checks*
GROUP BY Midwives.Firstname, Midwives.Surname, Midwives.ID
However, in the event that a midwife is moved to a different team, the data associated with the previous team is now owned by the newly assigned team. As described in the example detailed previously.
Thus a modification (which modification is yet to be realised) is required to make the data submitted - prior to a team change - assigned to the previous team, as of current, because of the way the records are owned by the midwife, this is not possible.
You should below suggestion as per you concern.
Step 1 ) You need to create School Master Table
ID | School | IsActive
1 | ABC | 1
2 | XYZ | 1
Step 2 ) You need to create Children Master having school id as foreign key
ID | School | Children Name| IsActive
1 | 2 | Mak | 1
2 | 2 | Jak | 1
Step 3 ) You need to create test table having children id as foreign key
ID | Children_id | Test Name | IsActive
1 | 2 | Math | 1
2 | 2 | Eng | 1
Now whenever child moves school then make child record inactive and create another active record with new school. This will help you to bifurcate the old test and new test.
do let me know in case morehelp required

How to give two strings the same ID if they have 80% similarity?

There are two id descriptions which are similar that is have say 80% similarity. I need both to be given same id.
There are other id descriptions having say 60% similarity. These should retain their own ids. Once an id desc has been considered and modified, it should not be taken as a reference. Further
example:
id id description
1 pepsodent
2 pepsodent salt
3 pepsod
4 pepsodent and salt
5 peps
Now, pepsodent matches with pepsodent salt.therefor both should be given id as 1
Now as pepsodent salt has already been modified,it cannot be used as a scale of reference further.
As I said in my comment above, you need to define exactly what the rules are for matching two records. In this example, I am giving the a New ID to any records that contain the entire string 'pepsodent'. The New ID for these records will be 999 but you can modify as you see fit:
SELECT ID, ID_Description,
CASE
WHEN ID_Description LIKE 'Pepsodent%' THEN 999
ELSE ID
END AS New_ID
FROM Table

SQL Server - Execute Dynamic SQL for Each Row in Recordset

I have a population of students who are registered to take courses for the Fall semester, with each course having it's own particular prerequisite requirements.
LastName FirstName Course Prerequisite(s)
Smith John ET212 (NS292 And NS262 And NS271) OR (( NS272 OR CR313 ) AND CS134)
Smith John ET452 HC111
Apon Jim EG442 EG243
Apon Jim EG497 EG382 And EG431
Jones Greg MS160 MS150
Jones Greg NV222 NV101 Or NV212
Serandon Susan EG261 EG101
I created a function that finds the the prerequisites for a course and builds a predicate string in proper SQL (or at least close to it - I haven't been able to test), with consideration for the AND / OR combinations of different prerequisite courses:
NOT EXISTS (SELECT * FROM TRANSCRIPT WHERE ID = 'P000021210' AND COURSE = 'ET211') And NOT EXISTS (SELECT * FROM TRANSCRIPT WHERE ID = 'P000021210' AND COURSE = 'ES251')
I was hoping to use this function to build a SQL statement for each row in my recordset (every class that every student is registered to take), execute that statement, and then return a bit; yes, they meet the prerequisite requirements to take the course, or no, they don't. BUT, apparently you can't use sp_executesql or EXECUTE() within a function.
So the root of my question is, since it does not appear possible to execute a dynamic SQL statement unique to each row in a recordset, how else could I accomplish this?

Create a Parent–Children Web Part Page

I am trying to figure out how to do something that I would think is commonplace, but I cannot find how to do.
Given two Custom Lists, one with a field that is essentially a primary key, and the other with what is essentially a foreign key, I want to show all the rows from the first in one area of the display, and the related records for the selected row of the first, in a second part of the screen.
I am thinking this would be side–by–side web parts on a web-part page.
So:
ID pkID Data ID fkID Data
___________________ ______________________________
| 1 100 Row one. | | 8 100 Related one/one |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ | 9 100 Related one/two |
2 113 Row two. | 10 100 Related one/three |
3 118 Row n. ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
11 113 Related two/one
12 113 Related two/two
13 118 Related n/one
(That is my attempt to show what is established between the two lists. Top row selected on the left, related records from the other row on the right.)
Surely this is common enough that there is a way to readily do this?
I suppose I might need to create a means of asserting that a row is 'selected.'
You will note that I am not useing the ID field that "belongs" to SharePoint.
You can create look up fields to establish that relationship, sharepoint 2010 even allows you to enforce the relationship like in a SQL database. so for instace you can declare what happens if you try to delete a parent if there is childs (Cascade, Prevent, etc).
Have a read here:
http://office.microsoft.com/en-au/sharepoint-server-help/create-list-relationships-by-using-unique-and-lookup-columns-HA101729901.aspx
About visually displaying them, you might have to create some webparts for it, as the only support OOB is the link to the child entity from the main entity on the parent list.