Creating table,queries and relations between the tables - mysql

I need to create 4tables(Products,Customers,Orders,Order Items). Products hold name and price. Customers hold name. Orders hold customer, date and set of order items. Order items hold order, product and quantity. All tables should have auto-increment primary key – id.
After creating the table I need to execute different scripts and I cannot understand why when I run this script:
INSERT INTO Orders VALUES (1,'2015-02-13 13:47:04'), (2,'2015-02-14 22:03:44'), (3,'2015-02-18 09:22:01'), (4,'2015-02-11 20:17:18');
I am getting this error:
Column name or number of supplied values does not match table definition.
I create the table in this way:
Create table Orders
(
OrdersID int not null,
Customer varchar(50),
date date,
Set_Of_Order_Items varchar(50),
primary key(OrdersID)
)
Any suggestions why I am receiving this error?

If you want insert only some columns you must explicitally indicate these columns
INSERT INTO Orders (OrdersID , date)
VALUES (1,'2015-02-13 13:47:04'),
(2,'2015-02-14 22:03:44'),
(3,'2015-02-18 09:22:01'),
(4,'2015-02-11 20:17:18');

Related

Is there any constraint in SQL where I add a value that is a foreign key to one table, it removes that value(primary key) from another table?

I have two tables defined as:
dealership_inventory(vin, dealer_id, price, purchase_date)
where vin is the PK and dealer_id is the FK
transactions(transaction_id, dealer_id, customer_id, vin, cpurchase_date, price)
where transaction_id is PK and dealer_id,customer_id, and vin are FKs
Whenever I add a new transaction to the transactions table with an insert statement, I would like to remove that tuple with matching vin from the dealership_inventory table. Is this possible with some type of constraint?
You don't really need to do the removal of the VIN number from the inventory table. Instead, if you want to find out whether a vehicle be still available, just use an exists query, e.g.
SELECT di.*
FROM dealership_inventory di
WHERE NOT EXISTS (
SELECT 1
FROM transactions t
WHERE t.vin = di.vin
);
If, at some later point, the inventory table gets bogged down with items no longer available, you can run a batch job which moves these sold items to another table.

Create Table (new columns) and columns from different table

So For example. I have 1 table
and the name of the table is Suppliers
Contains :
1. SupplierName
2. SupplierID
I want to create another new table name Contracts
which contain new columns for
1. ContractID (new column)
2. SupplierID(from "Suppliers" table)
3. ContractValue (new column)
How do i do it?
I have researched and most of them told me to use Create table and then select, But it wont work and also ive tried alter table but still not working.
CREATE TABLE Contracts (
ContractID INT NOT NULL,
SELECT SupplierID
FROM Suppliers,
ContractValue INT NOT NULL,
ContractStart DATE NOT NULL)
These codes are not working so I'm not sure what is the solution.
CREATE TABLE Contracts (
ContractID INT NOT NULL,
(SELECT SupplierID
FROM Suppliers),
ContractValue INT NOT NULL,
ContractStart DATE NOT NULL)
I expect the result to be new table with ContractID (new column), SupplierID (from table Suppliers) and another new column named ContractValue
Think of Select query result set as a table or data grid.
So "SELECT [some fields] FROM [some table]" returns data grid where each row contains some fields from the table.
Therefore you can define table as select query with data OR alternatively specify the structure and create empty table. Most likely you don't want to mix those two approaches.
In your case, SupplierID field of contract table is a reference to SupplierID of Supplier table. In SQL it's called "foreign key". Theoretically you can use select statement in order to create new table and when you play a lot with database queries, you'll choose most convenient and faster way depending on your needs.
But when you start learning, it's better to create an empty table with structure and then insert data using new fields and existing data for the foreign key.
Therefore, the query will be something like:
CREATE TABLE Contracts (
ContractID INT NOT NULL,
SupplierID INT NOT NULL,
ContractValue INT,
ContractStart DATE
);
And then you can insert data using existing values from supplier table:
INSERT INTO Contracts (SupplierID)
SELECT SupplierID FROM Suppliers
Of course this is very simplified description
First, you have to specify ContractID as primary key. Then the query above will work only if you specify primary key as auto increment value, otherwise you have to use some logic and specify it explicitly.
In addition you have to specify default values if you want to use NOT NULL fields.
You can also specify SupplierID as foreign key, so only existing values will be added and some other integrity relationships will be supported.
See any MySQL or SQL documentation for details.
I don't know whether the below way could solve your problem
Make a copy of Suppliers table
Delete unnecessary column from the copied table
Add new column that you want to it.
You can use CTAS command.
CREATE TABLE Contracts as
SELECT
0 as ContractID,
SupplierID,
0 as ContractValue,
now() as ContractStart
FROM Suppliers;
This will create a table with all fields. The default value is to specify the dataType. You can update the table with relevant value or have a join in the select clause itself.
The basic syntax for creating a table from another table is as follows
CREATE TABLE NEW_TABLE_NAME AS
SELECT [ column1, column2...columnN ]
FROM EXISTING_TABLE_NAME
[ WHERE ]
Here, column1, column2... are the fields of the existing table and the same would be used to create fields of the new table.
Example
Following is an example, which would create a table SALARY using the CUSTOMERS table and having the fields customer ID and customer SALARY −
SQL> CREATE TABLE SALARY AS
SELECT ID, SALARY
FROM CUSTOMERS;
last week I did, as you want to do.
Only two steps I was followed:
Export existing table.
Open in notepad++ and change the existing table name, add my new columns and Import.
Thanks

Self join- When i'm trying to do a self join, my query is displaying matching and non matching values

Friends-
I have 2 tables, 1st one contains the details about history, 2nd contains details on current product details, i want to fetch the product whose prod.description has changed in the current. I got the answer for this.Now i have another table which contains both current and history details of the product, now i need the products whose description has changed, i'm trying this with self join,but i'm seeing both current and previous description
i have used the below query
select h.ProdName,h.ProdId, h.MfgDate, h.ProdDescription
from historycurrent c join historycurrent h on c.ProdId=h.ProdId where
h.ProdDescription != c.ProdDescription;
but i need only the last 3 records from the output.
What you want to do seems impossible with your current schema. This is because your table is de-normalized into a hybrid object table / transaction table. To produce the output you have, your table undoubtedly has six rows. The first three inserts added three objects ("D-Cold", "Otrivin" and "ZanduBalm") but the last three inserts updated those objects with a new description (and thus change the old records forever).
You need to split the table into two. So this:
create table historycurrent (
ProdName VARCHAR(20),
ProdId INT,
MfgDate VARCHAR(20),
ProdDescription VARCHAR(50)
);
Needs to become (something like):
create table product (
prodId INT PRIMARY KEY,
prodName VARCHAR(?),
mfgDate DATE
);
create table history (
historyId INT,
prodId INT, -- foreign key
changeDate DATE,
prodDescription VARCHAR(?)
);
Then you can query the history and do a simple join for the product info

Database relation and inserting a row

I am building a cash register for my work place. I am having a trouble with Mysql.
I have db with three tables.
orders (where it stores : list_id, order_id (FK from order_line table),Id (FK for product id from product table), qty, total).
order_line (Where it stores : order_id, order_date, order_time )
products (id,product_name,product_desc,price)
What i want to do is to add the order in database. Insert into order_line a date and time and order_id(auto increment)
Also insert the items into orders table where it can retrieve order_id from order_line table so i can have same order_num for each item in orders table.
so far, this is what i tried;
INSERT INTO order_line
VALUES('','04/25/2015','11.52.06');
INSERT INTO orders
VALUES ('','orders_ibfk_2','orders_ibfk_1','2',30.00);
and recieved an error: Cannot add or update a child row: a foreign key constraint fails (shoelacestore.orders, CONSTRAINT orders_ibfk_1 FOREIGN KEY (id) REFERENCES products (id))
Any help will be appreciated. Thank You
I think your id column data types are not integer. Make it integer if it is ok.
when you execute following query
INSERT INTO order_line
VALUES(0,'04/25/2015','11.52.06');
You will get a value for order_id. Just assume it is 344
And assume in your products table you have a product with id 98
Then you can use follwing query to insert into
INSERT INTO orders
VALUES (0,344,98,'2',30.00);
i assume all ids are integers
Guys i found the solution.
INSERT INTO T1 (col1,col2) VALUES (val1,val2);
SET #last_id_in_T1 = LAST_INSERT_ID();
INSERT INTO T2 (col1,col2) VALUES (#last_id_in_T1,val2);
so basicly, T1 is the table for order_line which creates an auto increment order_id. SET #last_id_in_T1 = LAST_INSERT_ID(); copies the last order_id and inputs into orders table as i wished.
I hope this will help others as well.

Update table with sequential ints

I have inherited a company database which issues an order number as a GUID. Not exactly user friendly when you want to quote your order number! So what I want to do is add a new int column and add a unique sequential order number to each existing order (which has been ordered by datetime).
It's a great idea, but I'm stuck on how to actually do it as an update query! Any help would be greatly appreciated.
Add an identity column to your table and the numbering will be taken care of for you.
alter table YourTable add YourTableID int identity
One way.
alter table t add order_id int identity
This will add an auto-incrementing int identity column. There is no guarantee as to the order in which the ids will be assigned to the existing rows, but a unique id will be assigned to each existing row. Each new row inserted after this change will get a new unique id.
Before applying this to a real application consider whether existing code will work with an identity column. Often this approach is a really harmless upgrade. Code that tries to insert an identity column fails, unless it uses set identity_insert. You can't remove the identity property without dropping the column.
To round this out might want a unique constraint on the new id, both for retrieval speed and to enforce uniqueness if the id column is ever updated.
Unfortunately if you just add an IDENTITY column to the table, the existing orders will not necessarily get the IDENTITY values assigned in order of the OrderDate, so they will be "out of order" if you wanted to assign order ID values based on order date (which seems logical). Quick example:
CREATE TABLE dbo.Orders
(
OrderGUID UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY,
OrderDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
INSERT dbo.Orders(OrderDate) VALUES
('20120101'), ('20120102'), ('20120103');
GO
ALTER TABLE dbo.Orders ADD OrderID INT IDENTITY(1,1);
GO
SELECT OrderID, OrderGUID, OrderDate = CONVERT(DATE, OrderDate)
FROM dbo.Orders
ORDER BY OrderDate;
Results (obviously yours will differ):
OrderID OrderGUID OrderDate
------- ------------------------------------ ----------
2 C5CE909E-0469-45AE-A828-647C7F54AA14 2012-01-01
1 70D8EEB1-FDA8-4E56-874F-771999C6DB84 2012-01-02
3 8E7B42C3-6C4D-4860-8A82-AFADDBA96A4A 2012-01-03
If this is not acceptable you should probably create a new table and insert all the old orders into it (at which point you can also drop the GUID column as I alluded to in my comment).
CREATE TABLE dbo.OrdersCopy
(
OrderID INT IDENTITY(1,1) PRIMARY KEY,
... other columns ...
);
INSERT dbo.OrdersCopy (OrderDate, ... other columns ...)
SELECT OrderDate, ... other columns ...
FROM dbo.Orders
ORDER BY OrderDate
OPTION (MAXDOP 1); -- single-threaded is important!
EXEC sp_rename 'dbo.Orders', 'OrdersOld', 'OBJECT';
EXEC sp_rename 'dbo.OrdersCopy', 'Orders', 'OBJECT';
(If you want to keep the old GUID for reference, temporarily, while you clean up other tables, that's probably fine, but you shouldn't make it auto-populate anymore, and you should plan to remove it since it's wide and redundant.)