inserting multiple values into one row mySQL - mysql

How can i insert multiple values into one row?
My query
insert into table_RekamMedis values ('RM001', '1999-05-01', 'D01', 'Dr Zurmaini', 'S11', 'Tropicana', 'B01', 'Sulfa', '3dd1');
i cant insert two values into one row. is there another way to do it?

I'm ignorant of the human language you use, so this is a guess.
You have two entities in your system. One is dokter, the other is script (prescription). Your requirement is to store zero or more scripts for each dokter. That is, the relationship between your entities is one-to-many.
In a relational database management system (SQL system) you do that with two tables, one per entity. Your dokter table will contain a unique identifier for each doctor, and the doctor's descriptive attributes.
CREATE TABLE dokter(
dokter_id BIGINT AUTO_INCREMENT PRIMARY KEY NOT NULL,
nama VARCHAR (100),
kode VARCHAR(10),
/* others ... */
);
And you'll have a second table for script
CREATE TABLE script (
script_id BIGINT AUTO_INCREMENT PRIMARY KEY NOT NULL,
dokter_id BIGINT NOT NULL,
kode VARCHAR(10),
nama VARCHAR(100),
dosis VARCHAR(100),
/* others ... */
);
Then, when a doctor writes two prescriptions, you insert one row in dokter and two rows in script. You make the relationship between script and dokter by putting the correct dokter_id into each script row.
Then you can retrieve this information with a query like this:
SELECT dokter.dokter_id, dokter.nama, dokter.kode,
script.script_id, script.kode, script.nama, script.dosis
FROM dokter
LEFT JOIN script ON dokter.dokter_id = script.dokter_id
Study up on entity-relationship data design. It's worth your time to learn and will enhance your career immeasurably.

You can't store multiple values in a single field but there are various options to achieve what you're looking for.
If you know that a given field can only have a set number of values then it might make sense to simply create multiple columns to hold these values. In your case, perhaps Nama obat only ever has 2 different values so you could break out that column into two columns: Nama obat primary and Nama obat secondary.
But if a given field could have any amount of values, then it would likely make sense to create a table to hold those values so that it looks something like:
NoRM
NamaObat
RM001
Sulfa
RM001
Anymiem
RM001
ABC
RM002
XYZ
And then you can combine that with your original table with a simple join:
SELECT * FROM table_RekamMedis JOIN table_NamaObat ON table_RekamMedis.NoRM = table_NamaObat.NoRM
The above takes care of storing the data. If you then want to query the data such that the results are presented in the way you laid out in your question, you could combine the multiple NamaObat fields into a single field using GROUP_CONCAT which could look something like:
SELECT GROUP_CONCAT(NamaObat SEPARATOR '\n')
...
GROUP BY NoRM

Related

When to replace a database column with an ID instead

I'm helping a friend design a database but I'm curious if there is a general rule of thumb for the following:
TABLE_ORDER
OrderNumber
OrderType
The column OrderType has the possibility of coming from a preset list of Order Types. Should I allow VARCHAR values to be used in the OrderType column (ex. Production Order, Sales Order, etc...) Or should I separate it out into another table and have it referenced as a foreign key instead from the TABLE_ORDER as the following?:
TABLE_ORDER
OrderNumber
OrderTypeID
TABLE_ORDER_TYPE
ID
OrderType
If the order type list is set, and will not change, you could opt to not-make a seperate table. But in this case, do not make it VARCHAR, but make it an ENUM.
You can index this better, and you will end up with arguably the same type of database as when you make it an ID with lookup-table.
But if there is any change at all you need to add types, just go for the second. You can add an interface later, but you can easily make "get all types" kind of pages etc.
I would say use another table say "ReferenceCodes" for example:
Type, Name, Description, Code
Then you can just use the Code through out the database and need not worry about the name associated to that code. If you use a name (for example order type in your case), if would be really difficult to change the name later on. This is what we actually do in our system.
In a perfect world, any column that can contain duplicate data should be an id or an ENUM. This helps you make sure that the data is always internally consistent and can reduce database size as well as speed up queries.
For something like this structure, I would probably create a master_object table that you could use for multiple types. OrderType would reference the master_object table. You could then use the same table for other data. For example, let's say you had another table - Payments, with a column of PaymentType. You could use the master_object table to also store the values and meta-data for that column. This gives you quite a bit of flexibility without forcing you to create a bunch of small tables, each containing 2-10 rows.
Brian
If the list is small ( less than 10 items ) then you could choose to model it as your first but put a column constraint to limit the inputs to the values in your list. This forces the entries to belong to your list, but your list should not change often.
e.g. check order_type in ('Val1','Val2',...'Valn')
If the list will ever change, if it is used in multiple tables, you are required to support multiple languages or any other design criteria that demands variability, then create your type table (you are always safe with this choice, it is why it is the most used).
You can collect all such tables into a 'codes' table that generalizes the concept
CREATE TABLE Codes (
Code_Class CHARACTER VARYING(30) NOT NULL,
Code_Name CHARACTER VARYING(30) NOT NULL,
Code_Value_1 CHARACTER VARYING(30),
Code_Value_2 CHARACTER VARYING(30),
Code_Value_3 CHARACTER VARYING(30),
CONSTRAINT PK_Codes PRIMARY KEY (Code_Class, Code_Name)
);
insert into codes ( code_class, code_name, code_value_1 )
values( 'STATE','New York','NY' ),
values( 'STATE, 'California','CA'),
.... );
You can then place and UPDATE/INSERT trigger on the table.column under change that should be constrained to a list of states. Lets say an employee table has a column EMP_STATE to hold state short-forms.
The trigger would simply call a select statement like
SELECT code_name
, code_value_1
INTO v_state_name, v_state_short_name
FROM codes
WHERE code_class = 'STATE'
AND code_value_1 = new.EMP_STATE;
if( not found ) then
raise( some error to fail the trigger and the insert );
end if;
This can be extended to other types:
insert into codes ( code_class, code_name )
values( 'ORDER_TYPE','Production' ),
values( 'ORDER_TYPE', 'Sales'),
.... );
select code_name
, code_value_1
into v_state_name, v_state_short_name
from codes
where code_class = 'ORDER_TYPE'
and code_name = 'Sales';
This last method, although generally applicable can be over-used. It also has the downside that you cannot use different data types (code_name, code_value_*).
The general rule of thumb: create a 'TYPE' (e.g. ORDER_TYPE) table (to hold the values you wish to constrain an attribute to for each type), use an ID as the primary key, use a single sequence to generate all such id's (for all your 'TYPE' tables). The many TYPE tables may clutter your model, but the meaning will be clear to your developers (the ultimate goal).

mysql - add columns to a table or create new table and join

I have the following setup:
A table with n columns that contain let's say... pizza details. There are 4 kind of pizzas at this point
Until now all pizzas had same details, each detail saved in a column.
But now a new kind of pizza called super pizza appeared, that has 2 more types of details that needs to be saved.
There are 2 ways to do this (that I can think about):
Add to columns to the existing table, and leave them blank/null/whatever for the rest of 4 pizzas types
Create a new table with 3 columns (idPizza, newDetail1 and newDetail2), save pizza as the rest of pizzas, and when I get data join the 2 tables
First option has the disadvantage that I keep useless data for all pizzas except the new type (80% of the table at an average pizzas distribution).
Second option has the disadvantage that each time I get the new kind of pizza I need to make a join. Also the db will be kind of "messy"... having part of pizza element stored in a table and other part in another.
I know that ultimately is a matter of taste but how do you think I should proceed? I incline a bit to first option but a second opinion is welcomed.
As a note: There are lots of entries in the tables (like tens of thousands).
Second note (based on an answer): Can't refactor the "pizza" table, just add to it.
instead of this you can use flat table concept as follows whic hwill be easy for adding no of characteristic in future for new pizzas having some more details
CREATE TABLE pizza
(
id int auto_increment primary key,
name varchar(20),
details varchar(30)
);
INSERT INTO pizza
(name, details)
VALUES
('pizza1', 'nice pizaa'),
('pizza2', 'nice pizza#sqlfiddle');
CREATE TABLE details
(
id int auto_increment primary key,
name varchar(20)
);
INSERT INTO details
(name)
VALUES
('pizza_size'),
('price');
CREATE TABLE pizza_details
(
id int auto_increment primary key,
pizza_id int(10) ,
details_id int(10) ,
details_value varchar(20)
);
INSERT INTO pizza_details
(pizza_id,details_id,details_value)
VALUES
(1,1,'small'),
(1,2,'Rs 20'),
(1,1,'big'),
(1,2,'Rs 50');
and fire the query
select pizza.name as pizza_name,details.name as detail,pizza_details.details_value from pizza_details left join details ON pizza_details.details_id = details.id
left join pizza On pizza_details.pizza_id = pizza.id;
SQL Fiddle
I suggested for use first option. Because 2nd option reserve more resources than 1st option and it will take more time process.
As the disadvantages of 1st option you have mentioned is quite obvious,but when you need more column then add new to that existing table.
Well I suggest just create a table with attributes (idPizza, newDetail) and save data as below
idPizza, newDetail1
1 1 detail
2 2 detail
3 super detail
3 super detail second
MAke idPizza, newDetail1 as primary

MySQL database with user created tables with custom column numbers

I have a person table and I want users to be able to create custom many to many relations of information with them. Educations, residences, employments, languages, and so on. These might require different number of columns. E.g.
Person_languages(person_fk,language_fk)
Person_Educations(person,institution,degree,field,start,end)
I thought of something like this. (Not correct sql)
create Tables(
table_id PRIMARY_KEY,
table_name_fk FOREIGN_KEY(Table_name),
person_fk FOREIGN_KEY(Person),
table_description TEXT
)
Table holding all custom table name and descriptions
create Table_columns(
column_id PRIMARY_KEY,
table_fk FOREIGN_KEY(Tables),
column_name_fk FOREIGN_KEY(Columns),
rank_column INT,
)
Table holding the columns in each custom table and the order they are to be displayed in.
create Table_rows(
row_id PRIMARY_KEY,
table_fk FOREIGN_KEY(Tables),
row_nr INT,
)
Table holding the rows of each custom table.
create Table_cells(
cell_id PRIMARY_KEY,
table_fk FOREIGN_KEY(Tables),
row_fk FOREIGN_KEY(Table_rows),
column_fk FOREIGN_KEY(Table_columns),
cell_content_type_fk FOREIGN_KEY(Content_types),
cell_object_id INT,
)
Table holding cell info.
If any custom table starts to be used with most persons and becomes large, the idea was to maybe then extract it into a separate hard-coded many-to-many table just for that table.
Is this a stupid idea? Is there a better way to do this?
I strongly advise against such a design - you are on the road to an extremely fragmented and hard to read design.
IIUC your base problem is, that you have a common set of (universal) properties for a person, that may be extended by other (non-universal) properties.
I'd tackle this by having the universal properties in the person table and create two more tables: property_types, which translates a property name into an INT primary key and person_properties which combines person PK, propety PK and value.
If you set the PK of this table to be (person,property) you get the best possible index locality for the person, which makes requesting all properties for a person a very fast query.

Best practice MySQL UPDATE/INSERT

Disclaimer: I didn't design these tables, and am aware they're not the best way to store this data. I need advice on the best way to handle the situation.
I have two MySQL tables:
`students`
id int; primary, unique
prof1_id varchar
prof2_id varchar
prof3_id varchar
`professors`
id int; primary, unique, auto-increment
username varchar
fname varchar
fname varchar
students_id int
comment text
A professor's username may be in any of the last three columns in the students table. Professors will need to provide one comment for each student who has them in their row in the students table.
The application that is the front end to this database expects two more columns in the professors table: student_id and comment. Since each student may have any 3 professors in their row, new rows will need to be added to professors whenever they are listed for multiple students. This means that the professors id field will need to auto increment for each new student comment.
What is the best way to accomplish this data transfer with a MySQL query? I've tried looking at UPDATE in combination with JOIN, but I'm not sure there is even a valid way to do this. Also, do I need to create another primary key for professors since the multiple rows will have the same id?
I suspect that a VIEW might be the best way to accomplish this, but the application on the front end expects the information to be stored in the professors table.
One other thing I was considering was that I could create a new table by joining the two tables and have a two-column primary key, students.id, professor.id.
Thanks!
Also, do I need to create another primary key for professors since the
multiple rows will have the same id?
Yes. This is good idea.
I wrote simple query that merges data from first table into 2 columns. This is not complete answer, but it can help you a lot:
SELECT id, prof1id as profid
UNION
SELECT id, prof2id
UNION
SELECT id, prof3id
UNION;
You may use this for view, inserts, but im not familiar with specyfic MySQL syntax and i dont want to misslead you. Please give feedback if it work.
"UNION" removes duplicate rows, you may need to use "UNION ALL" to keep duplicates (like duplicated values in 2 or 3 professors columns).

MySQL: LIKE Query Help?

I have a column in my table called student_id, and I am storing the student IDs associated with a particular record in that column, delimited with a | character. Here are a couple sample entries of the data in that column:
243|244|245
245|1013|289|1012
549|1097|1098|245|1099
I need to write a SQL query that will return records that have a student_id of `245. Any help will be greatly appreciated.
Don't store multiple values in the student_id field, as having exactly one value for each row and column intersection is a requirement of First Normal Form. This is a Good Thing for many reasons, but an obvious one is that it resolves having to deal with cases like having a student_id of "1245".
Instead, it would be much better to have a separate table for storing the student IDs associated with the records in this table. For example (you'd want to add proper constraints to this table definition as well),
CREATE TABLE mytable_student_id (
mytable_id INTEGER,
student_id INTEGER
);
And then you could query using a join:
SELECT * FROM mytable JOIN mytable_student_id
ON (mytable.id=mytable_student_id.mytable_id) WHERE mytable_student_id.student_id = 245
Note that since you didn't post any schema details regarding your original table other than that it contains a student_id field, I'm calling it mytable for the purpose of this example (and assuming it has a primary key field called id -- having a primary key is another requirement of 1NF).
#Donut is totally right about First Normal Form: if you have a one-to-many relation you should use a separate table, other solutions lead to ad-hoccery and unmaintainable code.
But if you're faced with data that are in fact stored like that, one common way of doing it is this:
WHERE CONCAT('|',student_id,'|') LIKE '%|245|%'
Again, I agree with Donut, but this is the proper query to use if you can't do anything about the data for now.
WHERE student_id like '%|245|%' or student_id like '%|245' or student_id like '245|%'
This takes care of 245 being at the start, middle or end of the string. But if you aren't stuck with this design, please, please do what Donut recommends.