mysql group by set id - mysql

MYSQL Database:
I have a table of data that I need to put into two tables.The one table contains persons and an animal. Every record is a person and an animal. I am chaning this to a multi table database and want to group by the persons name, and then give the group an id (like a customer id) and then in my other table pass the customer ID to the idcustomer to join the two tables. To simplfy this i dont mind if these newly created ids are in the single table with new column names. I can after the fact export them out and import them.
The question really is, how can I create a group by customer name, give that customer and ID and then use that same id in a column to do the join.
To describe the scheme:
I have taken over a project. The database as of now is one table. In this one table is:
persons name, address, childsname, description of child
What would like it to be at least to start with is:
id_person, person name, childsname, childparent, description of child.
The id of the person and the childsparent should be the same. When I break the table down, and put the child information in the child table, the child will have a parent id.
I still plan on having two tables. But I can export and create the tables, my problem is assiging the parent id to the child column with the current data.
An example of a couple rows would be:
person_name, address, childsname, description
mark twain, 23 st., Buckweat, short smart kid
mark twain, 23 st., Daniel, short kinda smart
Instead i would like to have 2 tables, one for the parents and the other table is their children.
The way this database was setup, if one person has more than one child, there is another row that lists all of the same information.
What I have planned is to have multiple tables with a join.
The original database has no index, or unique identifier.
What I want to do is loop through the records, since there is no unique id, if the customer name is identical, meaning they are listed twice, then they must have more than one child.
In that case, i want to be able to go through the database and assign a id for the parents. and also ad another colum called parentid, which will be the child table.

To create the table you need you can use a temporary table - to which you will insert all parent names and give them IDs. Then you can update the existing table:
CREATE TABLE name_to_id (
`id` INT(11) AUTO_INCREMENT,
`name` VARCHAR(256),
PRIMARY KEY (`id`));
INSERT INTO name_to_id (name)
SELECT DISTINCT name FROM my_table;
ALTER TABLE my_table
ADD COLUMN id INT(11) FIRST,
ADD COLUMN parent_id INT(11) AFTER childsname;
UPDATE my_table t
JOIN name_to_id n ON t.name = n.name
SET t.id = n.id, t.parent_id = n.id;
To create the parents and children separate tables you can use:
CREATE TABLE parents AS
SELECT id, name, address FROM my_table
GROUP BY id;
CREATE TABLE children AS
SELECT childsname, parent_id, description
FROM my_table;
You would probably want to ALTER those tables later to add a primary keys and other needed indexes.

Related

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

What is an elegant solution to ensure inserts are limited to the root ownership in a hierarchical tree in MySQL?

So I have the following hierarchical database structure:
Table person has columns id and some other fields.
Table car has columns id, owner (with a foreign key constraint to person.id) and some other field
Table bumpersticker has columns id, car (with a foreign key constraint to car.id) and some other fields
I want to INSERT a row in to bumpersticker and have values to populate the row. I also have a person.id value of the person trying to add the bumpersticker.
What is the best practice to ensure that the car.owner value selected from the bumpersticker.car is in fact the same person.id as I have?
I guess one obvious way is to first execute a select query, on the car table and select the car.owner and validate that this value is the same value as the id of the person trying to add the bumpersticker and then execute an insert query.
but this seems like something there must be an elegant solution to in MySQL. at least not having to do two separate queries.
Most thankful for your help!
You can insert from a SELECT query that tests if the owner matches the criteria
INSERT INTO bumpersticker (car, sticker_text)
SELECT c.id, "If you can read this you're too close"
FROM car AS c
WHERE c.id = #car_id AND c.owner = #person_id
#car_id is the ID of the car you're adding the bumpersticker for, and #person_id is the ID of the user doing the insert. If the owner ID doesn't match, the SELECT query will return no rows, so nothing gets inserted.
DEMO

having trouble with foreign key queries

I'm new to SQL and I'm having a hard time figuring out how to execute queries with foreign keys on MySQL Workbench.
In my example, I have three tables: people, places, and people_places.
In people, the primary key is people_id and there's a column called name with someone's name.
In places, the primary key is places_id and there's a column called placename with the name of a place.
People_places is a junction table with three columns: idpeople_places (primary key), people_id (foreign key), and places_id (foreign key). So this table relates a person to a place using their numerical IDs from the other two tables.
Say I want the names of everyone associated with place #3. So the people_places table has those associations by number, and the people table relates those numbers back to the actual names I want.
How would I execute that query?
Try this to find all the people names who are associated with place id 3.
SELECT p.name
FROM people as p
INNER JOIN people_places as pp on pp.people_id = p.people_id
WHERE pp.places_id = 3
OK, so you need to "stitch" all three tables together, yeah?
Something like this:
select people.name
from people -- 1. I like to start with the table(s) that I want data from, and
, people_places -- 2. then the "joining" table(s), and
, places -- 3. finally the table(s) used "just" for filtering.
where people.people_id = people_places.people_id -- join table 1 to table 2
and people_places.place_id = places.place_id -- join table 2 to table 3
and places.name = "BERMUDA" -- restrict rows in table 3
I'm sure you can do the rest.
Cheers. Keith.

How to migrate a recursive table?

Let's say I have a table, category, which has 3 columns, id, parent_id and name.
I have several tables like this, and I want to consolidate them into one. At present, their IDs will clash (not unique across DBs) so I need to re-ID them. If I make id an auto_increment I can copy all the other columns over just fine, but then parent_id won't link up properly anymore. Is there some magical way I can get the parent_id to point to the correct new ID?
Looking for something like
INSERT INTO newtable (parent_id, name) SELECT ???, name FROM oldtable
How about
Generate a new table with a column containing the name of the old table and old id (oldid, oldtablename) along with a new ID
Add a new column 'newparentid'
Update each row's newparentid to be (SELECT newid FROM newtable nt WHERE oldtablename = row.oldtablename and nt.oldid = row.parent_id)
I imagine you could add an old_id column so that you'll still have the original id and you can run successive updates to the table to modify all the parent_ids to point to the new auto_inc ids. You would obviously have to kill any foreign keys requirements on the table first and reinstitute them after all the changes were made – Patrick