I am building a employees page.
Some of the information goes into an 'employees' table but some of it goes into a 'availability' table that is referenced to the 'employee' table:
availability:
id / employeeid (unique id from employees table) / monday available / and on and on /
So I don't have that unique ID from the employees table until I create them.
Is it fine to do a query where I set the employee info and then a query to get the last created row in the employee table and then use the unique id from that to set the availability...
Or is that messy and should I have a create employee page and THEN a set availability page?
So basically I want to know if it is cleaner and 'better' coding to separate the two functions?
Adding to #Quassnoi's answer:
You would add the employee record, then use the MySQL LAST_INSERT_ID() function to find the autoincremented unique id for the employee record you added. You can then feed that value back into the availability INSERT statement.
More details are on the MySQL manual page at http://dev.mysql.com/doc/refman/5.1/en/example-auto-increment.html
It's important that you not use a SELECT statement (e.g. SELECT MAX(employee.id)) since there might be other uses adding records as well. LAST_INSERT_ID() is specific to your connection
Of course create employee first, availability then.
If your tables are InnoDB, you can do it in a transaction so that you can rollback the whole update if something goes wrong.
Is it fine to do a query where I set
the employee info and then a query to
get the last created row in the
employee table and then use the unique
id from that to set the
availability...
Yes, that sounds OK. If you use an autoincrement column for employeeid, you can then use mysql_insert_id() or equivalent to retrieve that last inserted id safely. Don't do SELECT MAX(employeeid) FROM ...., because you might get problems when loads of people are using it concurrently.
You can easily get the last insered record via
mysql_insert_id()
After that, you can insert an availability record for the desired employee.
Note: I would choose a framework that takes care of these issues, like Symfony or Cake.
Using the "last created row" may not always work the way that you're expecting and may complicate things in the future if there's growth or if another programmer assumes the project. If I understand what you're looking for, you should instead have 3 tables. One table for employees, one table for availability, and a third table should be used to store unique records for the association. In the association table each row will have columns for : a unique ID, the employee id, the availability id.
Related
I am trying to develop a system to assign room numbers to tenants of a hostel upon registration, using the auto increment feature of sql.
However, it automatically increases by one after every entry. Because the hostel accommodates four people in one room, I want to change this to 4, so that after every 4 entries I get only one id/room number.
How do I go about this? I am using php and sql. If the autoincrement feature is not possible can you please suggest another way to achieve this? Thanks.
You would need:
http://dev.mysql.com/doc/refman/5.1/en/replication-options-master.html#sysvar_auto_increment_increment
It works like this:
mysql> SET ##auto_increment_increment=4;
So when you insert 4 rows, the auto increment column will be:
4,8,12,16
as best of my knowledge you cannot change the steps of auto-increment field. I suggest add another field and write a trigger to update its value based on auto-increment field (auto-increment/4).
I don't think this is possible with autoincrement..
Maybe you can do something like this:
//Pseudo code
//First you get the count of the highest id, to see how many users are in the last room.
SELECT COUNT(*) FROM table WHERE id=(SELECT id FROM table ORDER BY id DESC LIMIT 1)
//If the result of the last query is >= 4 then insert the next customer with id +1
Don't use auto_increment for this - it can't handle a situation where multiple records will share the same number and although you can reset it manually (see below) it's also not designed for a situation where numbers may get reused in a random order.
You could just have a room_number field with one of the mysql integer types (e.g. tinyint, smallint, mediumint…) or you could separate your database into two tables, one for people (each of whom have an id) and a second to map those ids to rooms.
However you do it, you'd then write a select query to check which room numbers are available before you add the person's details to the database.
You may need to read up on relational databases if that doesn't sound very clear.
If you do need to reset the auto_increment (sometimes it's nice to do it if you've filled a database with test data which you're about to wipe, and you want the real "production" data to begin at 1) you can use:
ALTER TABLE [tablename] AUTO_INCREMENT = 1
https://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
Is it possible? If yes, how?
I am using xampp for my database and I wanted to make a database with "students" table, only one column for the list of student IDs, and every student ID has another table inside. (I was considering making tables for every student ID so that it can be done directly but it seems that it PHP/MySQL does not allow integers as table name).
No, you cannot put tables inside a row in SQL. That's not compatible with the concept of a relational database. What you can do is provide a foreign key to another table where you can collect the data you need to link to your first table.
What you need is to have one table with all you want about the students, and add a field with their ID.
So, yo don't have to get the information from student #123 as
SELECT * FROM 123
but
SELECT * FROM students_table WHERE IdStudent = 123
I'm having a hard time figuring how to link database rows in a PHP / MySql project. My order submission script currently splits information and stores it into 2 tables.
The first one is called "Orders" and contains:
$OrderId, $CustomerName, $CustomerEmail, $OrderTotal, $OrderTaxes
//and other infos about the ORDER
The second one is called "Items" and contains all the BOUGHT products infos:
$ProductId, $OrderedQty
//for each one and such...
It has to be this way because the "Items" table will be searched by different "departments" who will only be shown the parts of the orders they are responsible for.
But they all have to get the "Orders" infos for shipping purposes.
Knowing that the "OrderId" column is a primary key generated on the "Orders" table itself, and that my INSERT TO commands are both executed at the same time, how can I link an "Order Id" column in both tables ?
Do I have to generate some random key to match them ?
If I were to use a foreign key, how would the database know which product goes with which order since they are submited at the same time ?
Or is it fast enough to INSERT in "Orders" -> SELECT $OrderID -> INSERT in "Items" ?
How does one usually do this ? Can't figure this one out.
Thanks in advance for your precious help!
The bought product info should have an extra column the bought product tables called orderid, so you know which products belong to which order.
As for the inserting in to the database this depends on what you are using to execute the queries. Some query classes allow you to run multiple query statements in one go, if this is the case you could run something similar to:
INSERT INTO Orders (OrderId, CustomerName, CustomerEmail, OrderTotal, OrderTaxes) Values(...)
SET #order_id = LAST_INSERT_ID();
INSERT INTO boughtItems (OrderId,ProductId,OrderedQty) Values (#order_id, :productid_1, :name_1),(#order_id, :productid_2, :name_2),(#order_id, :productid_3, :name_3) ....
In order cases you would need to run the insert statement on orders and then obtain the primary key.
Take a look at these links:
In other cases you could use a class which allows you to obtain the last inserted id. This id is connection bound so should give no issues (as long as the insert works, you are not doing multiple inserts in one query, do rollbacks or other weird stuff).
In this case you would do an insert and then call a secondary function to get the inserted id.
See these links:
mysqli insert id
pdo last insert id
mysql insert id
Alternatively you could also execute 2 queries. First the insert query followed by this query:
SELECT LAST_INSERT_ID() as id;
Other related links:
mysql - last_insert_id function
Related post on dba stackexchange
I am implementing a request mechanism where the user have to approve a request. For that i have implemented a temporary table and main table. Initially when the request is added the data will be inserted to the temporary table, on approval it will be copied to the main table.
The issue is there will be more than 5k rows to be moved to the main table after approval + another 3-5 row for each row in the detail table (stores the details).
My current implementation is like this
//Get the rows from temporary table (batch_temp)
//Loop through the data
//Insert the data to the main table (batch_main) and return the id
//Get the details row from the temporary detail table (batch_temp_detail) using detail_tempid
//Loop through the data
//Insert the details to the detail table (batch_main_detail) with the main table id amount_id
//End Loop
//End Loop
But this implementation would take atleast 20k queries. Is there any better ways to implement the same.
I tried to create a sqlfiddle but was unable to create one. So i have pasted the query in pgsql.privatepaste.com
I'm sorry that I'm not familiar with PostgreSQL. My solution is in MySQL, I hope it can help since if they (MySQL & PostgreSQL) are same.
First, we should add 1 more field into your batch_main table to track the origin batch_temp record for each batch_main record.
ALTER TABLE `batch_main`
ADD COLUMN tempid bigint;
Then, on approval, we will insert 5k rows by 1 query:
INSERT INTO batch_main
(batchid, userid, amount, tempid)
SELECT batchid, userid, amount, amount_id FROM batch_temp;
So, with each new batch_main record we have its origin batch_temp record's id. Then, insert the detail records
INSERT INTO `batch_main_detail`
(detail_amount, detail_mainid)
SELECT
btd.detail_amount, bm.amount_id
FROM
batch_temp_detail `btd`
INNER JOIN batch_main `bm` ON btd.detail_tempid = bm.tempid
Done!
P/S:
I'm confuse a bit about the way you name your fields, and since I do not know about PostgreSQL and by looking into your syntax, can you use same sequence for primary key of both table batch_temp & batch_main? If you can, it's no need to add 1 more field.
Hope this help,
Simply need to update your Schema. Instead of having two tables: one main and one temporary, you should have all the data in main table, but have a flag which indicates whether a certain record is approved or no. Initially it will be set to false, and once approved it will simply be set to true and then the data can display on your website etc. That way you will not need to write the data two times, or even have to move it from one table to another
You haven't specified RDBMS you are using, but good old INSERT with SELECT in it must do the trick in one command:
insert main (field1,...,fieldN) select field1,...,fieldN from temporary
I'm creating a game in actionscript that requires the use of an external database to store user details and scores.
This database will contain multiple tables, currently there are two.
My first table contains the headers - ID, email, username, password.
My second table contains the headers - ID, lvl1Score, lvl2Score, lvl3Score.
In my game, when a new user is created it creates an entry in the first table with the ID auto-incrementing.
My question is - Is there anyway to automatically create an entry in my second table with its default values and the same ID when I add to my first table?
I've read about joins, but everything i've read just talks about looking up data over multiple tables.
Also, is my table structure correct in the sence that the ID value can be used using the JOIN keywork to look up an entry from both tables.
I would suggest you to go for triggers.
create or replace trigger trigger_name after
insert on table1
for each row
begin
insert into table2 values(new.id,"value for lvl2score","value for lvl3score");
end
Something like this.
If the tables truly have a one-to-one relation, I would recommend that you simply make one table having all the fields.
Or did you mean this should store multiple scores for each individual user? In this case, you should not insert a default record for the user. Instead, the score.ID field should instead reference user.ID and allow duplicates.
I suggest you to use triggers and for more flexibility create a many-many relationship between "user" and "level", so you will end up with 3 tables:
user
level
user_level (this will contain the foreign keys: user_id, level_id)