Relational algebra for one-to-many relations - relational-algebra

Suppose I have the following relations:
Academic(academicID (PK), forename, surname, room)
Contact (contactID (PK), forename, surname, phone, academicNO (FK))
I am using Java & I want to understand the use of the notation.
Π( relation, attr1, ... attrn ) means project the n attributes out of the relation.
σ( relation, condition) means select the rows which match the condition.
⊗(relation1,attr1,relation2,attr2) means join the two relations on the named attributes.
relation1 – relation2 is the difference between two relations.
relation1 ÷ relation2 divides one relation by another.
Examples I have seen use three tables. I want to know the logic when only two tables are involved (academic and contact) as opposed to three (academic, contact, owns).
I am using this structure:
LessNumVac = Π( σ( job, vacancies < 2 ), type )
AllTypes = Π( job, type )
AllTypes – LessNumVac
How do I construct the algebra for:
List the names of all contacts owned by academic "John"

List the names of all contacts who is owned by academic "John".
For that, you would join the Academic and Conctact relations, filter for John, and project the name attributes. For efficiency, select John before joining:
πforename, surename (Contact ⋈academicNO = academicID (πacademicID (σforename = "John" Academic))))

You have to extend your operations set with natural join ⋈, Left outer join ⟕ and/or Right outer join ⟖ to show joins.
There is a great Wikipedia article about Relational Algebra. You should definitely read that one!

Related

How can l get a total sum from one table if it is linked with a lot of tables using linq?

l have multiple tables with one to may relationships eg Country -> Region -> Center -> Greater ->Section. The section has a column for census. l am trying to write a linq query for my view to get the total census grouped by the Country. l also need to know in a country how many regions are there, how many centers, how many greaters and the total census. They can be separate queries there is no problem.
In this case, the SelectMany method in LINQ is your friend. Each country has a collection of regions, right? You can use .SelectMany to combine all of the regions from several countries into a single collection of regions. Then you need to get a collection of centers from all of the regions, and so on and so on.
Consider this code:
context.Countries.SelectMany(country => country.Regions)
.SelectMany(region => region.Centers)
.SelectMany(center => center.Greaters)
.SelectMany(greater => greater.Sections)
.GroupBy(country => country.Id)
.Sum(section => section.Census);

Laravel eloquent deep count with relationship

I want to get count from deep table and the relationship is A->B->C->D and I want total count of D.
For example;
A: 3 Boss
B: 5 Managers
C: 8 Human Resources
D: 25 Employees
Imagine that every boss has managers and every manager has human resources and also every human resource has employees. How can I get total count every boss's employees' with Laravel. (For instance, first boss has 7 employees at the end.) Should I have to write hard sql code like joins or can I handle with eloquent?
By the way, my tables:
A: id, name
B: id, name
A and B has pivot table.
C: id, name
B and C has pivot table
D: id, name
C and D has pivot table
So far, I tried to:
$a = Boss::with("a.b.c.d")->where("id", 10)->first();
dd($a->b->c->d->count());
It just gave me d's count but I want to all of a's.
There is no native relationship for this case.
I created a HasManyThrough relationship with unlimited levels: Repository on GitHub
After the installation, you can use it like this:
class A extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function d() {
return $this->hasManyDeep(D::class, ['a_b', B::class, 'b_c', C::class, 'c_d']);
}
}
$count = A::find($id)->d()->count();

Efficient algorithm that takes a Twitter user and finds top users by order of how many of his followers they follow

The title is very wordy. So I'll explain with an example.
We have a database of 10,000 twitter users with each following up to 2000 users. The algorithm takes as input one random never before seen user (including the people that follow him), and returns the twitter users from the database by order of how many of his followers they follow.
i.e.
We have:
User A follows 1,2,3,4
User B follows 3,4,5,6
User C follows 4,8,9
We enter user X who has users 3,4,5 following him.
The algorithm should return:
B: 3 matches (3,4,5)
A: 2 matches (3,4)
C: 1 match (4)
Store the data as a sparse integer matrix A of size 10^5x10^5 with ones at the appropriate places. Then, given a user i, compute A[i,] * A (matrix multiplication). Then sort.
Assuming you have a table structure similar to this:
Table Users
Id (PK, uniqueidentifier, not null)
Username (nvarchar(50), not null)
Table UserFollowers
UserId (FK, uniqueidentifier, not null)
FollowerId (uniqueidentifier, not null)
You can use the following query to get the common parents of followers of the followers of the user in query
SELECT Users_Inner.Username, COUNT(Users_Inner.Id) AS [Total Common Parents]
FROM Users INNER JOIN
UserFollowers ON Users.Id = UserFollowers.FollowerId INNER JOIN
UserFollowers AS UserFollowers_Inner ON UserFollowers.FollowerId = UserFollowers_Inner.UserId INNER JOIN
Users AS Users_Inner ON UserFollowers_Inner.FollowerId = Users_Computed.Id
WHERE (UserFollowers.UserId = 'BD34A1FF-FCF5-4D35-B8A3-EFFB1587A874')
GROUP BY Users_Inner.Username
ORDER BY COUNT(Users_Inner.Id) DESC
would something like this work?
for f in followers(x)
for ff in followers(f)
count[ff]++ // assume it is initially 0
sort the ff-s by their counts
Unlike the matrix solution, the complexity of this is proportional to the number of people involved rather than the number of users on twitter.

SQL to Relational Algebra

How do I go about writing the relational algebra for this SQL query?
Select patient.name,
patient.ward,
medicine.name,
prescription.quantity,
prescription.frequency
From patient, medicine, prescription
Where prescription.frequency = "3perday"
AND prescription.end-date="08-06-2010"
AND canceled = "Y"
Relations...
prescription
prescription-ref
patient-ref
medicine-ref
quantity
frequency
end-date
cancelled (Y/N))
medicine
medicine-ref
name
patient
Patient-ref
name
ward
I will just point you out the operators you should use
Projection (π)
π(a1,...,an): The result is defined as the set that is obtained when all tuples in R are restricted to the set {a1,...,an}.
For example π(name) on your patient table would be the same as SELECT name FROM patient
Selection (σ)
σ(condition): Selects all those tuples in R for which condition holds.
For example σ(frequency = "1perweek") on your prescription table would be the same as SELECT * FROM prescription WHERE frequency = "1perweek"
Cross product(X)
R X S: The result is the cross product between R and S.
For example patient X prescription would be SELECT * FROM patient,prescription
You can combine these operands to solve your exercise. Try posting your attempt if you have any issues.
Note: I did not include the natural join as there are no joins. The cross product should be enough for this exercise.
An example would be something like the following. This is only if you accidentally left out the joins between patient, medicine, and prescription. If not, you will be looking for cross product (which seems like a bad idea in this case...) as mentioned by Lombo. I gave example joins that may fit your tables marked as "???". If you could include the layout of your tables that would be helpful.
I also assume that canceled comes from prescription since it is not prefixed.
Edit: If you need it in standard RA form, it's pretty easy to get from a diagram.
alt text http://img532.imageshack.us/img532/8589/diagram1b.jpg

Relations between tables

I have 3 tables: A, B and C.
Table A is in relation (n:1) with B and with C.
Typically I store in A the B.Id (or the C.Id) and the table name.
e.g.
A.ParentId = 1
A.TableName = "B"
A.ParentId = 1
A.TableName = "C"
A.ParentId = 2
A.TableName = "B"
Is it a good solution? Are there any other solutions?
Why not 2 parentid columns?
A.ParentIdB = 1
A.ParentIdC = 3
Another possibility is to introduce another table Content (D) that serves as a "supertype" to Posts and Images. Then a row in Comments (A) would reference a primary key in Content as would each row in Posts (B) and Images (D). Any common fields in Posts and Images would be moved to Content (perhaps "title" or "date") and those original tables would then only contain information specific to a post or image (perhaps "body" or "resolution"). This would make it easier to perform joins than having the table names in a field, but it does mean that a real-world entity could be both a post and a comment (or indeed, be multiply a post or comment!). Really, though, it depends on the situation that you're trying to model.

Resources