I'm new working with mysql and I'm trying to insert data into a table from a different table. I've searched and I've found that I need to do something like this:
INSERT INTO Customers (CustomerName, City, Country)
SELECT SupplierName, City, Country FROM Suppliers;
These are the tables' composition:
Credit_request:
Fieldname DataType
| request_id | int(10) unsigned
| customer_id | int(11)
| total_credit_value | int(11)
| Credit_request_checked | set('yes','no')
| does_apply | enum('yes','no')
| creation_time | datetime
Customers:
Fieldname DataType
| Customer_id | int(11) unsigned
| name | varchar(70)
| lastname | varchar(70)
| sex | enum('M','F')
| personal_id | varchar(16)
| phone_number | varchar(20)
| email | varchar(70)
| birthdate | date
| address | varchar(70)
| city | varchar(70)
| job | varchar(60)
| salary | int(11)
| registration_date | datetime
+-------------------+------------------
but when I try, I get a syntax error. This is my code:
INSERT INTO Credit_request(null,'Carlos',custormer_id
,default,default,
default,default,default,default)
SELECT Customer_id FROM Customers WHERE Customer_name ='Carlos';
these defaults values are supposed to be there, I've set them however, I've noticed in order to do this kind of insert I have to reference to each field name but in this case I just want one piece of information from the other table. Any help would be appreciated.
If you want to insert only secific columns, you can specify those column names and rest of the columns will be assinged default values. Your script would be:
INSERT INTO Credit_request(custormer_id)
SELECT Customer_id FROM Customers WHERE Customer_name ='Carlos';
This will add one row into Credit_request table with Carlos's customer_id in customer_id column and null in other columns.
You've got your syntax a little mixed up. The INSERT statement should declare the columns you're inserting into, the SELECT statement declares the values. For columns that have a default, you can omit them. Nullable columns always default to NULL unless otherwise stated.
INSERT INTO Credit_request(
`customer_id`,
`creation_time`
) SELECT
`Customer_id`,
NOW()
FROM `Customers`
WHERE `Customer_name` ='Carlos';
Related
I have this table:
mysql> desc Customers;
+------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+-------+
| CustomerID | int(10) unsigned | NO | PRI | NULL | |
| Name | char(50) | NO | | NULL | |
| Address | char(100) | NO | | NULL | |
| City | char(30) | NO | | NULL | |
+------------+------------------+------+-----+---------+-------+
Now, If I want to insert sample data:
mysql> insert into Customers values(null, 'Julia Smith', '25 Oak Street', 'Airport West');
ERROR 1048 (23000): Column 'CustomerID' cannot be null
I know I cannot make the ID null, but that should be job of mysql to set it numbers and increment them. So I try to simple not specifying the id:
mysql> insert into Customers (Name, Address, City) values('Julia Smith', '25 Oak Street', 'Airport West');
Field 'CustomerID' doesn't have a default value
Now I am in trap. I cannot make id null (which is saying for mysql "increment my ID"), and I cannot omit it, becuase there is no default value. So how should I make mysql to handle ids for me in new insertions?
Primary key means that every CustomerID has to be unique. and you defined it also as NOT NULL, so that an INSERT of NULL is not permitted
instead of >| CustomerID | int(10) unsigned | NO | PRI | NULL |
Make it
CustomerID BIGINT AUTO_INCREMENT PRIMARY KEY
and you can enter your data without problem
ALTER TABLE table_name MODIFY CustomerID BIGINT AUTO_INCREMENT PRIMARY KEY
#Milan,
Delete the CustomerID var from the table. And add this field again with the following details:
Field: CustomerID,
Type: BIGINT(10),
Default: None,
Auto_increment: tick in the checkbox
Click SAVE button to save this new field in the table. Now I hopefully it will work while inserting the new record. Thanks.
I am looking to allow my users to store their email lists and I am using MySQL.
I want to allow users to decide what fields their email list may have. eg. Name, Email, Location, Birthday
Each user may want different fields and each list may have different fields to each other.
I'm really stuck as to how I should structure my databases to allow for this. Any help would be appreciated.
Since the number of fields and the types of fields are possibly unknown, and could change depending on the user, it might not make sense to hard code them as columns. Instead, I would recommend that you use a key value pair approach here. First define a table email_fields looking something like this:
user_id | id | field
1 | 1 | Name
1 | 2 | Email
1 | 3 | Location
1 | 4 | Birthday
Above user 1 has configured his email lists to have four fields, which are the ones you gave as an example in your question. Adding more fields for this user, or adding more users, just means adding more records to this table, without changing the actual columns.
Then, in another table email_lists you would store the actual metadata for email address and user:
id | user_id | field_id | value
1 | 1 | 1 | Sam Plan
1 | 1 | 2 | sam.plan#somewhere.com
1 | 1 | 3 | Gonesville, AL
1 | 1 | 4 | 1967-03-28
In other words, the basic idea is that every email, for every user, would be represented a set of records corresponding to a bunch of key value pairs.
I am looking to allow my users to store their email lists and I am using MySQL.
This means that a given user may have more than one email list.
So the appropriate table for storing the email lists should be like this one:
+---------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| user_id | int(10) unsigned | NO | | NULL | |
| title | varchar(255) | NO | | NULL | |
+---------+------------------+------+-----+---------+----------------+
Each user may want different fields and each list may have different fields to each other.
The fields will be text or numerical. The user could create his own fields
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| email_list_id | int(10) unsigned | NO | | NULL | |
| field | varchar(255) | NO | | NULL | |
| value | longtext | YES | | NULL | |
+---------------+------------------+------+-----+---------+----------------+
Here is the SQL query to create those tables:
CREATE TABLE `email_list` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`user_id` int unsigned NOT NULL,
`title` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `email_list_data` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`email_list_id` int unsigned NOT NULL,
`field` varchar(255) NOT NULL,
`value` longtext DEFAULT NULL,
PRIMARY KEY (`id`)
);
In another approach, you will use a different table for storing the fields and another one for storing the values.
CREATE TABLE `email_list` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`user_id` int unsigned NOT NULL,
`title` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `email_list_fields` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`email_list_id` int unsigned NOT NULL,
`field` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `email_list_field_values` (
`email_list_id` int unsigned NOT NULL,
`field_id` int unsigned NOT NULL,
`field_value` longtext DEFAULT ''
);
The other answers remove around metadata. This is great, though it isn't meant for large amounts of data or relationships based on a "record" because there would be no Contact model. You would return 30 records if there were 30 fields specified for the contacts in the list.
It would take 2 parts that are highly complicated to implement, but would be more structured in the end.
1) Tenant DB Structure
There are some tutorials out there that can help with this. Essentially, you would have 1 master database that stores your teams, etc. Then, each of your teams would get their own database. We have a project that implements this structure and it works well. You can be connected to both the main and the specific tenant database at the same time.
2) Generating migration files
I have never done this part before, but I assume it is possible..
Try making a flexible schema-file builder. You can execute system commands via PHP to save a file you generated into a directory structured on your teams, such as /migrations/teams/1/37284_user_submitted_migration or something like that.
Execute
You can then run the artisan migration command on that specific file, for that specific tenant database (use the Artisan::run() facade helper). Each of your teams could have whatever structure they wish, as if you had built it for them.
This can all be executed within the same job.
Following is my table schema, we are using mysql 5.7 version
CREATE TABLE rule_reports (
pkey int(11) NOT NULL AUTO_INCREMENT,
email varchar(250) DEFAULT NULL,
domain varchar(250) NOT NULL,
rule_id bigint(20) unsigned NOT NULL,
rule_type varchar(250) NOT NULL,
log_time datetime DEFAULT NULL,
count int(11) DEFAULT NULL,
PRIMARY KEY (pkey),
KEY dwl (domain,rule_id,log_time)
)
I want to increment count column instead of new row in the table, if
combination of values of domain,rule_id,rule_type already exists in the table row
Sample rows of table
+------+-------------------------+---------+------------------+------------------+-------------------------+----------
| pkey | email | domain | rule_id | rule_type | log_time | count
+------+-------------------------+---------+------------------+------------------+-------------------------+-----------
| 1 | user1#yopmail.com | user1 | 566 | type1 | 2016-09-13 17:23:02.000 | 1
| 2 | user2#yopmail.com | user2 | 567 | type2 | 2016-09-13 17:23:02.000 | 1
-----------------------------------------------------------------------------------------------------------------------
Suppose if statement like below should not create a row because same values for domain,rule_id,rule_type already exists in table so I need a count column increment here
insert into rule_reports(domain,rule_id,rule_type,count) values('user1',566,'type1',1)
Statement like below should create a new row in table
insert into rule_reports(domain,rule_id,rule_type,count) values('user3',568,'type3',1)
Add a unique index on the columns involved, and the use ON DUPLICATE KEY UPDATE to increment the count if the record already exists.
ALTER TABLE rule_reports ADD UNIQUE unique_index(domain, rule_id, rule_type);
INSERT INTO rule_reports (domain, rule_id, rule_type, count)
VALUES ('user1', 566, 'type1', 1)
ON DUPLICATE KEY UPDATE count = count + 1
So, here's basically the problem:
For starter, I am not asking anyone to do my homework, but to just give me a nudge in the right direction.
I have 2 tables containing names and contact data for practicing
Let's call these tables people and contact.
Create Table for people:
CREATE TABLE `people` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`fname` tinytext,
`mname` tinytext,
`lname` tinytext,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Create Table for contact:
CREATE TABLE `contact` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`person_id` int(10) unsigned NOT NULL DEFAULT '0',
`tel_home` tinytext,
`tel_work` tinytext,
`tel_mob` tinytext,
`email` text,
PRIMARY KEY (`id`,`person_id`),
KEY `fk_contact` (`person_id`),
CONSTRAINT `fk_contact` FOREIGN KEY (`person_id`) REFERENCES `people` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
When getting the contact information for each person, the query I use is as follows:
SELECT p.id, CONCAT_WS(' ',p.fname,p.mname,p.lname) name, c.tel_home, c.tel_work, c.tel_mob, c.email;
This solely creates a response like:
+----+----------+---------------------+----------+---------+---------------------+
| id | name | tel_home | tel_work | tel_mob | email |
+----+----------+---------------------+----------+---------+---------------------+
| 1 | Jane Doe | 1500 (xxx-xxx 1500) | NULL | NULL | janedoe#example.com |
| 2 | John Doe | 1502 (xxx-xxx 1502) | NULL | NULL | NULL |
| 2 | John Doe | NULL | NULL | NULL | johndoe#example.com |
+----+----------+---------------------+----------+---------+---------------------+
The problem with this view is that row 1 and 2 (counting from 0) could've been grouped to a single row.
Even though this "non-pretty" result is due to corrupt data, it is likely that this will occur in a multi-node database environment.
The targeted result would be something like
+----+----------+---------------------+----------+---------+---------------------+
| id | name | tel_home | tel_work | tel_mob | email |
+----+----------+---------------------+----------+---------+---------------------+
| 1 | Jane Doe | 1500 (xxx-xxx 1500) | NULL | NULL | janedoe#example.com |
| 2 | John Doe | 1502 (xxx-xxx 1502) | NULL | NULL | johndoe#example.com |
+----+----------+---------------------+----------+---------+---------------------+
Where the rows with the same id and name are grouped when still showing the effective data.
Side notes:
innodb_version: 5.5.32
version: 5.5.32-0ubuntu-.12.04.1-log
version_compile_os: debian_linux-gnu
You could use GROUP_CONCAT(), which "returns a string result with the concatenated non-NULL values from a group":
SELECT p.id,
GROUP_CONCAT(CONCAT_WS(' ',p.fname,p.mname,p.lname)) name,
GROUP_CONCAT(c.tel_home) tel_home,
GROUP_CONCAT(c.tel_work) tel_work,
GROUP_CONCAT(c.tel_mob ) tel_mob,
GROUP_CONCAT(c.email ) email
FROM my_table
GROUP BY p.id
An invoice can contain 1 or more orders, how to archive this?
Example of Invoice:
OrderID | Order Date | Amount
31 10/02/2011 £1.50
43 12/02/2011 £1.50
74 13/02/2011 £5.00
=======
Total £8.00
If the Total is minus (eg: -8.00), it mean client owes me money.
Without minus, I pay client some money.
Here what I came up with:
Orders Table
CREATE TABLE IF NOT EXISTS `orders` (
`OrderID` int(11) NOT NULL AUTO_INCREMENT,
`Total` decimal(6,2) NOT NULL,
`OrderDate` datetime NOT NULL,
`Status` int(11) NOT NULL,
`userID` int(11) NOT NULL,
`InvoiceID` int(11) NOT NULL,
PRIMARY KEY (`OrderID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
Invoice Table
CREATE TABLE IF NOT EXISTS `invoice` (
`InvoiceID` int(11) NOT NULL DEFAULT '0',
`InvoiceDate` datetime NOT NULL,
`Amount` decimal(6,2) NOT NULL,
`Status` int(11) NOT NULL,
PRIMARY KEY (`InvoiceID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
invoice.Status (0 Processing, 1 Invoice Sent, 2 Cancelled, 3 Completed)
or what better status can be?
Payment Table
CREATE TABLE IF NOT EXISTS `payment` (
`PaymentID` int(11) NOT NULL AUTO_INCREMENT,
`InvoiceID` int(11) NOT NULL,
`Amount` decimal(6,2) NOT NULL,
`DatePayment` datetime NOT NULL,
`PaymentType` int(11) NOT NULL,
PRIMARY KEY (`PaymentID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
payment.PaymentType = (1: Payment Received From Customer (Owes Money), 2: Payment Sent To Customer)
Database Result:
mysql> select * from orders;
+---------+-------+---------------------+--------+--------+-----------+
| OrderID | Total | OrderDate | Status | userID | InvoiceID |
+---------+-------+---------------------+--------+--------+-----------+
| 1 | 20.00 | 2011-06-18 15:51:51 | 1 | 123 | 1 |
| 2 | 10.00 | 2011-06-19 15:51:57 | 1 | 123 | 1 |
| 3 | 5.00 | 2011-06-20 15:52:00 | 1 | 123 | 1 |
+---------+-------+---------------------+--------+--------+-----------+
mysql> select * from invoice;
+-----------+---------------------+--------+--------+
| InvoiceID | InvoiceDate | Amount | Status |
+-----------+---------------------+--------+--------+
| 1 | 2011-06-30 15:55:21 | 35.00 | 1 |
+-----------+---------------------+--------+--------+
mysql> select * from payment;
+-----------+-----------+--------+---------------------+-------------+
| PaymentID | InvoiceID | Amount | DatePayment | PaymentType |
+-----------+-----------+--------+---------------------+-------------+
| 1 | 1 | 35.00 | 2011-06-29 15:56:16 | 1 |
+-----------+-----------+--------+---------------------+-------------+
Im I on the right path? What can be improved/changed or suggestion?
Thanks.
Ok, you have some serious issues here. Orders have mulitple items, invoices have multiple orders and payments may apply to mulitple orders and invoices. Orders may appear on multiple invoices (if they don't pay right aways which is common).
So what you need are linking tables. You should start with an ORDERINVOICE table which has both the order id and the invoice ID. Then an ORDERPAYMENT table with paymentid and Order id.
You also need to consider that in an ordering situation, you must record the details of the order as it occurred at the time. That means that while you should have the user_id to link to the current user, you should record the user's name, billing address and shipping addres as it was at the time of the order. You will need this information later to deal with any questions on the order. Further you need to ensure that you store the details of the order in a separate table called ORDERDETAILS which store the indivdual line items, the price at the time of the order and the name of the item ordered. You will need this for accounting reasons. You do not under any cuircumstances want to rely on a join to a product table to figure out the price of an order in the past. This will cause your finanacial records to be inaccurate.
Looks good.
The only thing I would add are some details like transaction id / check number to the payment table. This way you keep all the payment details together.
It looks alright to me, this is what i would have done aswell.
(I would think a payment is linked with an order, but if you intended to link it to an invoice this is fine)
Regards,
MN
Without knowing more about your requirements, so far so good.
Be sure to store your Invoice Status and Payment Type decodes in a lookup table so that they can be enforced in the database and don't have to rely on programmers coding it correctly.