MYSQL inserting specific datas from columns - mysql

I have a table named Pupils and a table named Bus.
Bus contains an ID,Destination (where it goes to) and Time (when it leaves).
Pupils contains Name,Location(Where it lives) and BusID (Which bus it needs to take).
I want to fill the 'BusID' column with the correct 'ID' from the 'Bus' table (depending on the pupil's location and time selected).
For example, the pupil lives in Tel Aviv and wants a bus at 10:00.
I need to fill his 'BusID' column AND ROW ( there are many pupils) with the same 'ID' in the bus table where Destination equals Tel Aviv and Time equals 10:00.
Is it in anyway possible? I was thinking about using Insert into/Insert into select but it doesn't really fits my needs.

As I meanwhile understood: the pupils are somewhere else (presumably not in T.A.) and want to find the bus that brings them back to T.A. at 10:00 hrs.
This can then be achieved with
-- The id of the bus that travels at 10:00 to T.A.:
select id from bus where destination='Tel Aviv' and time='10:00:00';
-- Update the pupil's record with the bus-id:
update pupils set busid=... where location='Tel Aviv';
-- Together (and that's the answer):
update pupils set busid=(select id
from bus
where destination='Tel Aviv'
and time='10:00:00')
where location='Tel Aviv';
Note that this assumes there is exactly one result row in the first query, i.e. exactly one 10 o'clock bus to T.A.

Related

How to use joins to fetch unique data from a single table in mysql?

I've 4 tables in the database which are:-
branch
deposit
borrow
customers
Query: Find loan no, loan city, deposit account number, deposit city of those customers who are living in Nagpur city?
I've written a query below which successfully fetches three data.
Loan No
Loan City
Deposit Account number
But while fetching Deposit city, I'm getting same data as of Loan city.
Below I'm sharing my code so that you can find where I'm wrong
My tried code:
SELECT borrow.loanno,
branch.city AS 'Borrow city',
deposit.actno,
branch.city AS 'Deposit city',
customer.city As 'Customer_city'
FROM customer
JOIN borrow
ON borrow.cname = customer.cname
JOIN branch
ON borrow.bname = branch.bname
JOIN deposit
ON deposit.cname = customer.cname
AND customer.city = 'Nagpur';
By running the above code, Output I get is
loanno Borrow city Deposit city actno Customer_city
321 Mumbai Mumbai 104 Nagpur
375 Mumbai Mumbai 105 Nagpur
Output I want is:-
loanno Borrow city Deposit city actno Customer_city
321 Mumbai Delhi 104 Nagpur
375 Mumbai Banglore 105 Nagpur
For more understanding I'm sharing my dB fiddle link so that you get a clear idea.
https://www.db-fiddle.com/f/gaUYxuwuJLsWA4kFeMn9u6/6
Please dont take this the wrong way, but what you have does not appear to be a good database design. Typically, each table would have an auto-increment integer-based ID key that is unique and carried through to each underlying table. You have string values for your primary keys.
I know this looks like the beginning of a database design, but you really need some assistance moving forward.
So lets say, you have 5 people named "Anil", what do you do then... your done. "Anil" is the primary key and you cant change it. By having an auto-increment, you could have 1000 Anil customers, each with additional information to ensure uniqueness... first name, last name, address, other unique info.
Now on to your branch lookup table. Same applies. you have multiple branches in the city of Mumbai. WOULD there ever be a duplicate name? Possible??? Hence having an ID column auto-increment would resolve, and additional info like customer would ensure uniqueness like the address. Such as the "Kranti" branch. "IF" you had a Kranti branch on X-street vs Kranti branch on Y-street you would be safe with unique auto-increment numbers.
Now on to deposit and borrow tables. I know its sample data, but just to show how an oops can happen. Your branch info has a name "Chandani", but your deposit table has "Chandni" (missing the second "a"). I know type-o.
When you have your data entry screens and you find a customer or a branch, the system will have the given "id" of the record to store in your given deposit or borrow table. Don't do based on strings per the customer example of Anil -- which one if you have 100 Anil customers. The ID will ensure the correct customer. Similar with branch. The ID columns for customer and branch should be used instead (based on a modified database/table structures).
Finally to your query. You are trying to join the borrow table with the deposit for a given person. This is just going to give you headaches. There is no guarantee of a deposit for a borrow (or vice-versa). Now, if you have 5 borrows and 7 deposits for Anil, and you try to query both the way you have it, you will get 35 records being returned (a Cartesian product) because for every record in the borrow table with matching customer will be applied to those deposits.
So, enough for you to consider, sit back, take a breath and digest it. I can show you a better table structure to handle some context presented here.
As for writing queries, you really need to present it in simple English what you are TRYING to get, then show how you are ATTEMPTING. Also, there appears to be no match such as a deposit being applied to a given borrow, so what's the point / logic on this.
Again, sincere on what you are up against and would like to help but you may be farther off than you realize.
FEEDBACK
Ok, so it is an assignment -- a bad one, but one none-the-less. So the issue is you only used one instance of the branch based on the borrower. What you need is the branch table joined TWICE... once to the borrower, once for the deposit. In each, I "aliased" it. When joining to the borrow table I aliased it as "BBranch" for "borrow branch". For the deposit, I aliased as "DBranch" for "deposit branch". So each one is joined respectively, so each one will point to its own and pull the city respectively.
select
borrow.loanno,
BBranch.city as 'Borrow city',
deposit.actno,
DBranch.city as 'Deposit city',
customer.city
from
customer
join borrow
on customer.cname = borrow.cname
join Branch BBranch
on borrow.bname = BBranch.bname
join deposit
on customer.cname = deposit.cname
and customer.city = 'Nagpur'
join branch DBranch
on deposit.bname = DBranch.bname
Also, indentation to see how / where the tables are joined shows. You can see it goes
customer
borrow
branch for borrow
deposit
branch for deposit
Then you can always see the relationships down stream and not overlapping others / criss-crossing.
The last item is the and customer.city = 'Nagpur'. Don't even know if that was a requirement, but it was in your query.

Summing Columns up with some exceptions

I am working on a database with two different tables.
The first contains every change in the database like a transaction table. It contains the object that was bought/sold, how many of them where bought/sold, when this tranaction happend and in which place.
The second table contains the total value of every object that should be available in those places.
Now here is my question:
I want to automaticly sum up every entry with the same object and location inside of table one and save this value inside of table two.
BUT
Sometimes there are special entrys in table one which should not be summed up with the other values. They should overwrite the value.
I have an example of how this summing up should look like:
n = normal value, s = special value
n: 1 sum: 1
n: 2 sum: 3
s: 7 sum: 7
n: 5 sum: 12
n: 4 sum: 16
n: 7 sum: 23
s: 20 sum: 20
To help you help me I have some additional informations:
There are 4 columns inside of table one
The first one is called object and contains the object number for which this entry takes effect.
The second column contains the amount of that object. Whether it was bought or sold.
The third column tells me on which locations this transaction belongs to. Which also means that every object has different amounts depending on the location.
The fourth column contains an information why this transaction happend. It tells me if this transaction happend because I bought something or because I sold something OR because I counted my stock.
This is the special indicator which should tell my database not to sum up this value but instead overwrite the previous one with this.
The fifth and last column contains the date when this transaction happend. This is very important because the whole table is sorted by the date. And it tells when those special values come in place.
The other table just contains the summed up value for every object in every location.
This below will return the sum of each record for a particular Object 'MyObj' starting from the last instance of a 'Special' entry (inclusive).
(Untested)
SELECT Sum(a.Amount) AS TheSum
FROM tblMyTable a
WHERE ID_PK> = nz((
SELECT max(ID_PK)
FROM tblMyTable
WHERE Object=a.Object AND IsSpecial=1
),0)
AND a.Object='MyObj'

How do I structure MySQL tables where one field could contain multiple values (but might not)?

I'm designing a web app which allows users to attend events and search for specific types of events.
Say, for instance, that these events are taking place in Hogwarts. The students have their own table where their studentID is held as a primary key, and this also contains which house they are a part of (of which there are 4), the subject they take, and which year of study they are in (e.g. 1 or 4 or 5, etc). The events can be for all students, specifically for 4th year students in the Ravenclaw house, or anywhere in between.
The events are held in an events table, which contains an eventID as the primary key, but I'm not sure how to hold the data for the house/year/subject it is aimed at. Obviously if an event were only aimed at 3rd year Hufflepuffs who take Potions, or something similarly specific, I could hold it within the same table. However, what if the event is for any year of Hufflepuffs (and not any Slytherins, etc)? Or if all students from all years, houses and subjects are eligible to attend? Will I need a table which holds all the years for each event and a separate table for which houses it's for and a further separate table for the subject it's aimed at?
Any advice or links are appreciated.
I think there are two ways but you definitely need at least one more table for the associations. Either you want to be very specific, about the combinations possible or you want to do it generally, like: only third years, only hufflepuffs, then the combination of the two values will be only third year hufflepuffs.
What I am trying to say are these two options.
1) One table that holds rows with very specific details:Event ID and the explicit combinations of all possible options (Here you will have a lot of rows)
This would mean that the event can be associated with second and third year hufflepuffs, but only second year slytherins.
association_id event_id year_id house_id subject_id
1 1 second hufflepuff potions
2 1 third hufflepuff potions
3 1 second slytherin potions
2) One table per property (here the disctinction is not as clear but you only have to create one row per property etc.
The following two tables could be used to store that all hufflepuffs and all slytherins that are in second or third year might attend
association_id event_id year_id
1 1 second
2 1 third
association_id event_id house_id
1 1 hufflepuff
2 1 slytherin
Does that answer your question or at least help you to find a solution?
Mybe if you can describe the target you are aiming at more closely one can find a solution suitable for your Problem together.

SELECT Last x Rows from Table and use last index number of selection (+1) for start of next same query

I need to capture last data added to a mysql table in blocks to files every 5 mins (cron)
I need to use last index number as the beginning of next query (+1) .. and so on.
Basically I need to capture blocks of unique records to individual text files with no overlap of records.
I.E.
Index_No Forename Surname
1012 bob Smith
1013 Ann Smith
1014 Mike Hope
First run query would get a certain number of events up to 1014.
The next query would run automatically 5 minutes later (cron ?) and start with 1015 upwards.
Etc etc ... every 5 minutes.
I have looked everywhere on www for answer but not yet found one. I am looking specifically for last record from previous query (+1) up to last current entry cycling every 5 minutes.
I think if I was implementing this requirement, I would write a little program that runs the query and spits the output into a file. The program would also use some kind of persistant data store (text file/db/whatever) to keep track of the last record.
You can then just use cron to invoke your program.
HTH
Have a log table with index_No and update it with the last No whenever you query. Something like this
Create table index_log(Index_no int)
Insert into index_log(Index_no)
select 1014
select columns from source_table
where index_no>(select index_no from index_log)
Update index_log
set index_no=(select max(index_no) from source_table

Schedule a snapshot of a MySQL Table

It is possible to schedule a snapshot of a MySQL table?
The situation:
I have a table that collects votes (up and down) from a website. It registers the number of votes (that can be either a vote up, “+1”, or a vote down, “-1”), and records the score (for example, if one ID received 5 votes, 3 voting "up" (+1) and 2 voting "down" (-1), then the table would record that number of votes was "5", and that the vote score was "2". It is recorded in a table that has the following column headers/fields:
ID | Score | nvotes
…where ID is the reference of the item being voted on; 'score' is the actual score that is calculated (from the number of “+1” and “-1” votes), and 'nvotes' is the number of votes that have been received
This is great for looking at the website at any point in time and seeing what the score is, and how many people have voted.
However, I now want to be able to chart the trend for the ID – to look back over time and see how the score has gone up and down over time.
Is there a facility in MySQL to be able to take a snapshot at the end of each day, recording where that particular ID was at the end of that day in terms of their score and the number of votes received, and store this in another table so that I can create charts and analysis over time?
Or, failing that, can anyone think of a better, more intelligent way of trying to acheive what I need?