So I have 2 tables, one is an contact table like
ContactId BigInt PK
Name varchar
Phone varchar
Address varchar
and a second table Vendor
CompanyName varchar
ContactId BigIn FK
I want to load vendors into the tables such that
When I load vendors with a CSV it will put them in the contact table and load them into the vendor table
123423234, bob smith, 333-444-5555, 123 stree dr., CompanyOne
123123234, john doe, 444-333-2222, 423 SomeStreet st., Another Company
I kept the tables small and simple for the post, yes there is more but the key here is I need to use the ContactID from the contact table in the Vendor table. and I want to load them both from the same cvs. I know how to do this if it was just the one table but not sure with the 2 tables.
Thanks!
You may be able to do this with all SQL, or it might require/be easier with a scripting language like PHP. But here is the basic pseudo code idea.
CREATE an unnormalized table that your CSV file can fit into pretty directly (we'll call it tempTable). Then put the data from the CSV into there. (Pretty sure this will require some scripting).
Insert contact info into contact table:
INSERT INTO contact (name, phone, address) (SELECT DISTINCT name, phone, address FROM tempTable);
Add a contactID column to tempTable and update it with the IDs from the contacts table by JOINing:
UPDATE tempTable JOIN contact ON
tempTable.name = contact.name
AND tempTable.phone = contact.phone
AND tempTable.address = contact.address
SET tempTable.contactID = contact.contactID
Then INSERT into vendor much like the way we inserted in to contact:
INSERT INTO VENDOR (companyName, contactID) (SELECT company, contactID FROM tempTable);
Related
I have a old database (using MariaDB) and I have to make a new one that's close to the same but has a few differences, and I have to insert all the data from the old one into the new one. I've populated the new one with all the equal data, but I'm stuck on getting the 'new' data into it.
The change is in the old database there was a column in multiple tables containing a country name, but in the new database Country has it's own table, so instead of a country name in a column, it is instead just the foreign key CountryID from the country table.
So the issue is I have to populate the new columns CountryID with whatever the Countries CountryID is. For example, if the country field in the customers table in the old database was USA, when I translate the data, instead of putting USA it has to go to the new Country table, find the CountryID that is equal to USA, and put that ID in the field instead. (Something like this)
Old Customers Table
--------------------
Country
USA
Canada
New Customers Table
-------------------
CountryID
3
7
CountryTable
----------
CountryID CountryName
3 USA
7 Canada
I know it's probably just a simple insert into with some condition but can't figure out the proper syntax for it.
I've tried different insert into statements similar to the following but keep getting errors:
insert into newDatabase.customers(CountryID)
select oldDatabase.customers.Country
from oldDatabase.customers
where oldDatabase.customers.country = newDatabase.countryTable.CountryName;
insert into newDatabase.customers(CountryID)
select oldDatabase.customers.Country
from oldDatabase.customers
inner join newDatabase.countryTable as c on c.countryName = oldDatabase.customers.Country
where oldDatabase.customers.country = newDatabase.countryTable.countryName;
The end goal is you want to insert the id from CountryTable into your new customers table, which means you are going to need that table. You are inserting the data from the old customers table, so it'll look like this:
INSERT INTO newdb.customers(CountryID)
SELECT ct.CountryID
FROM olddb.customers as oldc
INNER JOIN newdb.country_table as ct
ON ct.CountryName = oldc.Country;
You don't need a WHERE clause because you aren't trying to filter the rows from the old customers table. You just need the ID from the country table to be mapped with your old customers table. For that reason you are JOINing by the country's name to the country table to get that extra information.
A client needs to migrate a large volume of data and I feel this question could be generic enough for SO.
Legacy system
Student profiles contain fields like names, emails etc, as well as university name. The university name is represented as a string and as such is repeated which is wasteful and slow.
Our new form
A more efficient solution is to have a table called university that only stores the university name once with a foreign key (university_id) and the HTML dropdown just POSTs the university_id to the server. This makes things much faster for doing GROUP BY queries, for example. New form data going into the database works fine.
The problem
How can we write a query that will INSERT all the other columns (first_name, last_name, email, ...) but then rather than inserting the university string, find out its university_id from the university table and INSERT the corresponding int instead of the original string? (scenario: data is in a CSV file that we will manipulate into INSERT INTO syntax)
Many thanks.
Use INSERT INTO ... SELECT with a LEFT JOIN. Left is chosen so that student record won't get discarded if it has a null value for university_name.
INSERT INTO students_new(first_name, last_name, email, university_id)
SELECT s.first_name, s.last_name, s.email, u.university_id
FROM students_old s
LEFT JOIN university u ON s.university_name = u.university_name
Table and column names are to be replaced for real ones. Above assumes that your new table for students holding foreign key to university is students_new while the old one (from before normalisation) is students_old.
I have a problem with database query. I have three tables projects, developers and email. In developers table, there are a lot of rows with same name but different email. I have to insert the distinct names but all the emails(in the row of name to which they belong) in email table i.e
example
/////////////////////////////////////////////
developers table have records:-
id_developer project_id name email
0 1 umar umar#gmail.com
1 1 umar umar#developers.com
Now i want to inert the data in email table as:-
user_id name email_ids
0 umar umar#gmail.com
umar#developers.com
////////////////////////////////////////////
projects
----------
id_project
name
----------
developers
----------
id_developer
project_id
name
email
----------
email
----------
user_id
name
email_ids
----------
Following is my current query. Please help me. Thanks in advance
INSERT INTO email(user_id, dev_name, email_ids)
SELECT p.id_project,
d.name,
d.email
FROM projects p
INNER JOIN developers AS d
ON p.id_project = d.project_id
WHERE d.name IN (SELECT name
FROM developers
GROUP BY name HAVING(COUNT(name) > 1 ))
GROUP BY(d.name)
After some conversation in the comments what you really need is a proper data modeling here.
Having the data the way you wan't in the database is a very bad practice.
user_id name email_ids
0 umar umar#gmail.com
umar#developers.com
You will end it up having problems in the future to retrieves this data because you will have to figure out a way how to retrieve or split this data when you need then.
So, based on your current model to attend your requirement you would need just to change the table email a bit. Your model would be this way:
projects developers email
---------- ------------- ------------
id_project id_developer id
name project_id id_developer
name email
---------- ------------- ------------
So, since you already have the data in the developers table lets first drop table table email and recreate it the right way. You will need to execute:
drop table email;
create table dev_email( -- changed the name because there is a field with same name
id INTEGER AUTO_INCREMENT NOT NULL,
id_developer INTEGER NOT NULL, -- this column should be the same type
-- as id_developer in the table developers
email VARCHAR(150) NOT NULL
PRIMARY KEY pk_email (id),
CONSTRAINT uk_developer_email UNIQUE (id_developer, email), -- that will avoid duplicates,
CONSTRAINT fk_dev FOREIGN KEY (developer_id)
REFERENCES developers(id_developer)
ON UPDATE RESTRICT ON DELETE RESTRICT
);
Now lets fill this table with the right data:
INSERT INTO dev_email (id_developer, email)
SELECT min(id_developer), email
FROM developers
GROUP BY email;
After that we must delete the duplicated data from the developers table like so:
DELETE FROM developers d
WHERE NOT EXIST (SELECT 1
FROM dev_email de
WHERE de.id_developer = d.id_developer);
Then we drop the column that is no longer needed in the developers table:
ALTER TABLE developers DROP COLUMN email;
This should give you a proper normalized model.
Now if you need to retrieve the developer with all emails concatenated (which is simpler than to split it) you just do:
SELECT d.id_developer,
d.name,
GROUP_CONCAT(e.email, ', ') as emails
FROM developers d
INNER JOIN dev_email e
ON d.id_developer = e.id_developer
GROUP BY d.id_developer,
d.name
PS.: I did all of this out of my head, please run it in a test environment first (a copy of your current database to be safe). It should be ok but better safe than sorry right?
Say, I have a customer profile with many contacts. That means I will have separated contact table from customer table.
tbl_customer
CustomerId (PK, NOT NULL, UNIQUE, AUTO_INCREMENT)
CustomerName
Address
(etc)
tbl_contact
ContactId (PK, NOT NULL, UNIQUE, AUTO_INCREMENT)
CustomerId (FK REFERENCES tbl_customer(CustomerId), CONSTRAINT)
Contact Type
Contact Number
So now let say, a customer called John Leweinsky has 4 contacts.
ContactType1: Fax
ContactType2: Office Phone
ContactType3: Personal Phone
ContactType4: Personal Phone
Can this be done in one query transaction without knowing CustomerId?
Thanks for advance if you have answered this.
Try like this
START TRANSACTION;
insert into (feilds name) values(Values);
insert into tbl_contact(CustomerId ,ContactType,ContacNumber)
values((select max(CustomerId) from tbl_customer),'type1','Fax');
COMMIT;
Pass all other contacttype
Assuming the name is unique, you can do this as:
insert into tbl_contact(CustomerId, ContactType, ContactNumber)
select cust.CustomerId, c.ContactType, c.ContactNumber
from (select 'Fax' as ContactType, Faxnumber as ContactNumber union all
select 'Office', Officenumber union all
select 'PersonalPhone', PersonalPhone union all
select 'PersonalPhone', PersonalPhone
) c cross join
Customers cust
where cust.CustomerName = 'John Leweinsky';
If name is not unique, you need some way to disambiguate the customers.
No, the only way to properly add something to tbl_contact is with the CustomerId. You're Customer Name is not unique ( nor should it be ) so you have no way to link your contacts with John Leweinsky, unless this is just a toy example and you want to pretend that John Leweinsky is unique.
You can add the contacts without knowing the CustomerId ( in some database engines, PostgreSQL for exapmle ) but the won't be connected to John Leweinsky.
I have a contact management system and an sql dump of my contacts with five or six columns of data in it I want to import into three specific tables. Wondering what the best way to go about this is. I have already uploaded the sql dump...its a single table now in in my contact management database.
The tables in the crm require in the companies table only the contactID...and in the songs table:
companyID,
contactID,
date added (not required) and
notes (not required)
Then there is the third table, the contact table which only requires contactname.
I have already uploaded data to each of the three tables (not sure if my order is correct on this) but now need to update and match the data in the fourth table (originally the sql dump) with the other three and update everything with its unique identifier.
Table Structures:
+DUMP_CONTACTS
id <<< I dont need this ID, the IDs given to each row in the CRM are the important ones.
contact_name
company
year
event_name
event_description
====Destination Tables====
+++CONTACTS TABLE++
*contactID < primary key
*contact_name
+++COMPANIES TABLE+++
*companyID < primary key
*name
*contact_ID
*year
++++Events++++
*EventID < primary key
*companyID
*contactID
*eventname
*description
There are parts of your post that I still don't understand, so I'm going to give you SQL and then you can run them in a testing environment and we can take it from there and/or go back and start again:
-- Populate CONTACTS_TABLE with contact_name from uploaded dump
INSERT INTO CONTACTS_TABLE (contact_name)
SELECT contact_name FROM DUMP_CONTACTS
-- Populate COMPANIES with information from both CONTACTS_TABLE + dump
INSERT INTO COMPANIES (name, contact_ID, year)
SELECT d.company, c.contactID, d.year
FROM DUMP_CONTACTS AS d
INNER JOIN CONTACTS_TABLE AS c
ON d.contact_name = c.contact_name
-- Populate SONGS_TABLE with info from COMPANIES
INSERT INTO SONGS_TABLE (companyID, contactID)
SELECT cm.companyID, cm.contact_ID
FROM COMPANIES AS cm
-- Populate Events with info from COMPANIES + dump
INSERT INTO Events (companyID, contactID, eventname, description)
SELECT cm.companyID, cm.contact_ID, d.event_name, d.event_description
FROM DUMP_CONTACTS AS d
INNER JOIN COMPANIES AS cm
ON d.company = cm.name
I first populate CONTACTS_TABLE and then, since the contactID is required for records in COMPANIES, insert records from CONTACTS_TABLE joining the dump. SONGS_TABLE takes data directly from COMPANIES, and lastly the Events gets its data by joining COMPANIES and the dump.