SQL - How to get a max value from a table and add it into another (sqlite3) - sql

Just like the title says, how would i get the maximun value from one table and add it into a field into another table from the same database:
I currently have my main table "users":
username | password | Email | Highscore 1 | Highscore 2 | Highscore 3 |
I also have my other tables :
"user_scores1":
username | Score 1 |
"user_scores2":
username | Score 2 |
"user_scores3":
username | Score 3 |
The "user_scores" tables contains all the scores of all the users (for the 3 different game modes) whenever they play. Whenever the user finishes the game for a particular game mode, a new score gets added into a new row as well as their username associaed to it, to the table of scores for that gamemode
I want to filter out all the scores from a user (e.g user1) and then get their highest score from the game modes, (e.g filtering out all the scores of user1 from the user_scores1 table)
With this, i want to get the highest score of that specific user from that specific table , and add it into my main table "users" in the appropite field (e.g like the previous example ,filtering out all the scores of user1 from the user_scores1 table, then getting the highest score and adding that score into my main table "users" into highscores1 where the username is user1 )

Is this what you want?
update users
set highscore1 = (select max(score) from user_scores1 us where us.username = users.name),
highscore2 = (select max(score) from user_scores2 us where us.username = users.name),
highscore3 = (select max(score) from user_scores3 us where us.username = users.name);

Related

exclude some ids associated to determined condition

In the following code I am looking forward to extract the ids associated to accounts with a determined status.
There are 4 status (Active, Inactive, Closed, Verifying)
Almost every account is associated to a phone and one phone could be associated to various accounts, for example:
A phone could be associated to various accounts, 1 Active, 1 inactive and let's say maybe another closed (lets call this account A).
Account B is only associated to a Closed account
Account C is only associated to an Inactive account
With my code I am looking to identify those phones who are ONLY associated to accounts that are not active. I noticed that my code gives me back all phones associated to accounts like A, B and C (Because A is associated to at least 1 NOT 'Active' account), I just want phones associated to accounts like B and C, and exclude ALL type A (if the phone is linked to at least 1 Active account, I don't want it in my db)
select
phone.id,
phone.number,
account.status as status_account
max(date_trunc('day', accountstatuslog.modified)::date) as modif_account_date
from accountstatuslog
join account on account.id = accountstatuslog.account_id
join phone on phone.id = account.phone_id
where
account.status not in ('Active') and
accountstatuslog.status = account.status and
group by
account.status,
account.phone_id
You can use Anti-Join to eliminate the records that you want.
Anti-Join is efficient because it rejects a row at the first occurrence of the value to eliminate.
Table:
postgres=# select * from PhoneStatus;
phoneaccholder | accountstatus
----------------+---------------
Vincent | Active
Vincent | Inactive
Xavier | Active
Benjamin | Closed
Sebastian | Closed
Gabriel | Active
Christopher | Inactive
(7 rows)
SQL:
SELECT phoneaccholder
,accountstatus
-- ,Count(*)
FROM phonestatus x
WHERE NOT EXISTS (SELECT 1
FROM phonestatus y
WHERE y.accountstatus = 'Active'
AND x.phoneaccholder = y.phoneaccholder)
and accountstatus in ('Closed','Inactive')
GROUP BY accountstatus,
phoneaccholder;
Output:
phoneaccholder | accountstatus
----------------+---------------
Benjamin | Closed
Sebastian | Closed
Christopher | Inactive
(3 rows)

SQL query for fetching users and common friends

I know similiar questions have been asked and answered before, I have reviewed them but still can't quite wrap my head around how to do this in my case.
I would like to create a query (I use postgreSQL) that would return users from my database filtered by name, sorted by the number of friends in common with a given user (the user sending the request).
The data structure is as follows:
I have a users table, that has a column called search_full_name which stores name + surname in the format of "ADAM SMITH". This is what I filter with.
I have a user_friends table that stores information about who is friends with whom. So I have two columns in there: user_id and friend_id . The data is symmetric, i.e. for every (1,3) there is a (3,1) entry.
So far in the friend search I was just using a query like
select * from users where users.search_full_name like '%query%'
But now, I would like to additionally order the result by the amount of friends in common with the user asking, so my query would have two inputs: query and userId.
Turns out I am not as good with sql as I thought, and I would really appreciate your help, it would be great to see some explanations too.
I imagine the desired output as:
+---------+------------------+----------------------+--+
| user_id | search_full_name | common_friends_count | |
+---------+------------------+----------------------+--+
| 45 | Adam Smith | 14 | |
| 123 | Adam Cole | 11 | |
| 12 | Adamic Kapi | 0 | |
+---------+------------------+----------------------+--+
for a query like 'Adam'
I have been trying this for a whole day now and I feel my brain has exploded.
Please help, thanks
The basic idea is a self-join. The following gets a match on users who share friends with the specified user:
select uf2.user_id, count(*) as num_friends
from user_friends uf join
user_friends uf2
on uf2.friend_id = uf.friend_id and
uf2.user_id <> uf2.user_id
where uf2.user_id = ?
group by uf2.user_id
order by count(*) desc; -- the user you care about
Ok, so after a few hours I came up with a query that works :) Here it is for future reference:
select u.id, u.search_full_name, count(uf.friend_id) as common_friend_count
from users u left join user_friends uf on (u.id = uf.user_id and uf.friend_id in (select friend_id from user_friends where user_id = ?))
where u.search_full_name like ?
group by u.search_full_name, u.id
order by common_friend_count desc;

Creating Burn-Earn credits mapping

I have two tables where for every user earned credits and burned credits are logged. Based on user's purchase loyalty points (credits) are given which are saved in "earned_credits" table. And he can redeem it in next purchases (this data is saved in "burned_credits" table)
I need to find the mapping (relation) for each "burned_credits" transaction with entry in "earned_credits" table
The table structure for earned_credits include:
id | user_id | credits_earned | earn_id | created_at | valid_upto
The table structure for burned_credits include:
id | user_id | credits_burned | burn_id | created_at
The relation between burn_id and earn_id needs to be defined. I tried using loop function in python where earned_credits.valid_upto < burned_credits.created_at and sum(earned_credits.credits_earned) - sum(burned_credits.credits_burned) >= 0 but the logic is failing at point where partial credits are burned.

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

Updating the user ranking with a SQL Server stored procedure

I have two tables, one contains user data and the other contains user ranking information (points needed for the promotion)
Let's say that the user table looks like this:
login | ArticlePoints | PhotoPoints | StageId
and the user ranking information table looks like this:
StageId | StageName | MinimumPoints
and the user information table might contain data like this:
1 | Beginner | 100
2 | Advanced | 200
3 | Expert | 300
What I would like to have is a procedure which does add user points and check whether it is enough for the ranking promotion. Right now I do it like this:
I do have a function which does check "manually" whether the user points is between 100 and 200 and then it does set the user stage = 2, id it's more it check whether it's between 200 and 300 etc.
Stored procedure which does update users set stage = MYFUNCTION from the point 1.
The thing is that it's not a good solution, right now it is not ready for the easy updates(I can't just add Super Expert with minimum 400 points, I'd need to edit the function).
I am trying to prepare a better solution for this problem but I have no idea how to "connect" both tables.
Write an UPDATE query that returns the StageID for the calculated values, something like:
UPDATE t1
SET t1.StageID =
(SELECT TOP 1 StageID
FROM [RANKING_TABLE] t2
WHERE t1.ArticlePoints + t1.PhotoPoints >= t2.MinimumPoints
ORDER BY t2.MinimumPoints DESC)
FROM [USER_TABLE] t1
So if the USER has 250 points in total, Beginner and Advanced would be achieved, using the TOP 1 and the ORDER BY t2.MinimumPoints DESC, would select the highest Stage.