SQL Server : copying columns to another table based on a join - sql

I am pretty inexperienced when it comes to SQL, so I apologize if this is a rookie question.
I need to add columns to a table in a database, based on a join from another database, using a common column between the two tables.

When you say "add columns to a table in a database," do you mean that you have a table, e.g.
create table Targets (
TargetID int identity(1,1) not null ,
constraint pkc_Target primary key clustered ( TargetID ) ,
TargetField1 varchar(64) not null ,
..... )
And you want to add additional columns to that table? If so, you'd do something like
alter table dbo.Targets add TargetNewField1 varchar(64) null
After that, you'd have empty columns in your table, and could then run an update to fill in the blanks, something like:
update dbo.Targets
set dbo.Targets.TargetNewField1 = dbo.Source.SourceField1
from dbo.Targets
inner join dbo.Source
on dbo.Targets.SomeUniqueField = dbo.Source.SomeUniqueField

Related

Best way to delete duplicate rows in an intersection table based on foreign key column

I'm looking for a way to delete dupicate rows from an intersection table based on a foreign key from one of the tables from the opposite ends of the intersection table. For the sake of clarity, I'll say based on a foreign key value from the intersection table on the left 'tableA'.
CREATE TABLE tableA
(
link varchar(64) NOT NULL PRIMARY KEY,
name varchar(64) NOT NULL
)
CREATE TABLE tableB
(
link varchar(64) NOT NULL PRIMARY KEY,
name varchar(64) NOT NULL
)
CREATE TABLE tableA_AND_tableB--Intersection Table
(
link varchar(64) NOT NULL PRIMARY KEY,
LtableA varchar(64) references tableA(link),
LtableB varchar(64) references tableB(link)
)
Basically, I want to delete all duplicate rows in the intersection table based on the 'LtableA' foreign key field. For instance: Say I have 20 duplicates of 'LtableA = id20140722' in 'tableA_AND_tableB', how do I go about deleting all the rows matching the value 'id20140722' in 'tableA_AND_tableB' without affecting anything else?
Hope my question makes sense.
Delete from tableA_AND_tableB where LtableA = 'id20140722'
This will remove all rows from that table sepcifically with that ID. Alternatively you can see this question for something that will delete all duplicates. Though that answer will keep either the first or last duplicate.
If you want to delete duplicates but still keep one distinct copy of each row:
WITH t AS (
SELECT ROW_NUMBER() OVER(PARTITION BY LtableA, LtableB ORDER BY link) row_num
FROM tableA_AND_tableB
)
DELETE
FROM t
WHERE row_num > 1
AND LtableA = 'id20140722'

SQL query, search data and return project name

Hey I'm looking for some help in creating a stored procedure.
Here are the details
I have a table called Partners which holds the partner information (Columns, PartnerID and partnername) I also have another table called ProjectPartners which holds the link between the project and the partners columns( PPID, Partner1, partner2, partner3....partner25) and I have a further table called ProjectDetails which holds the information on the project columns( ProjectDID, Project) The foreign key for projectpartners is within Projectdetails.
I'm looking to create a stored procedure that allows me to enter a partner name, this then displays the projects they are included within. I already have some mock code but it doesn't seem to work.
#partnername nvarchar(50)
AS
SET NOCOUNT ON;
SELECT ProjectDID, Project
FROM Projectdetails
WHERE Partners.PartnerName = #partnername
Any help will be much appreciated
You are missing the joins through your table schema to get the necessary data.
Take a read of this MSDN article about joins.
select ProjectDetails.ProjectDID, ProjectDetails.Project
from ProjectDetails
join ProjectPartners on ProjectPartners.ProjectDID = ProjectDetails.ProjectDID
join Partners on Partners.PartnerId = ProjectPartners.PPID
where Partners.PartnerName = #partnerName
You haven't described the relationship between ProjectPartners and Partner, so I am assuming that the PPID column on ProjectPartners is the relationship
You have also mentioned that your ProjectPartners table has the columns PPID, Partner1, partner2, partner3....partner25. Are you only planning on having 25 partners. If you have 26 will you add a new column? You might want to address that.
Also in column naming conventions, some are a bit muddled.
You have PPID on ProjectPartners. I presume this means ProjectPartnersId.
On the table ProjectDetails you have the column ProjectDID.
This is slightly inconsistent. I guess it should either be PDID on ProjectDetails or ProjectPID on ProjectPartners
Personally, I have always had always had a preference for plain old Id as my Identity column.
UPDATE:
Based on your comments below, it sounds like you might have something a little fundamental wrong with your tables:
create table Partners (
Id int not null primary key identity,
PartnerName nvarchar(100) not null)
go
create table ProjectDetails(
Id int not null primary key identity,
Project nvarchar(100) not null)
go
create table ProjectPartners (
PartnersId int not null,
ProjectDetailsId int not null
)
go
alter table ProjectPartners add constraint FK_ProjectPartners_PartnersId_Partners_Id foreign key (PartnersId) references Partners(Id)
alter table ProjectPartners add constraint FK_ProjectPartners_ProjectDetailsId_ProjectDetails_Id foreign key (ProjectDetailsId) references ProjectDetails(Id)
go
I would suggest changing your database schema to one that is a bit more flexible as per the one provided above.
This will prevent the ever growing ProjectPartners table by adding a new column each time you have a new partner.
It will fix all issues with your foreign keys and make your tables a bit more intuitive.
This would now yield the SQL:
select ProjectDetails.Project, ProjectDetails.Id
from ProjectDetails
join ProjectPartners on ProjectPartners.ProjectDetailsId = ProjectDetails.Id
join Partners on Partners.Id = ProjectPartners.PartnersId
where Partners.PartnerName= #partnerName

CREATE TABLE AS - how to add column with PK?

I have to create a table (H2 embedded database) using fields from other tables. I decided to use CREATE TABLE AS statement.
My code:
CREATE TABLE DOC AS
SELECT I.ID, I.STATUS, A.REMINDERINFORMATION
FROM IE802 I JOIN IE802_ATTRIBUTES A ON A.IE802_ID=I.ID;
Each row which is generated from the code above additionally must have DOCID PrimaryKey. How can I add this column and make it autoincrement and PK at the same time?
Thanks for any tips and other solutions!
Alternatively, how can I make existing I.ID to be PK?
I'm still getting an error: Column "ID" must not be nullable; SQL statement:
ALTER TABLE DOC ADD PRIMARY KEY (ID) [90023-147]
H2 supports column definitions in CREATE AS SELECT:
CREATE TABLE DOC(
ID INT PRIMARY KEY,
STATUS INT,
REMINDERINFORMATION VARCHAR(255)
)
AS SELECT I.ID, I.STATUS, A.REMINDERINFORMATION
FROM IE802 I JOIN IE802_ATTRIBUTES A ON A.IE802_ID=I.ID;

How to move data between multiple database's table while maintaining foreign-key relationships/referential integrity?

I'm trying to figure out the best way to move/merge a couple tables of worth of data from multiple databases into one.
I have a schema similar to the following:
CREATE TABLE Products(
ProductID int IDENTITY(1,1) NOT NULL,
Name varchar(250) NOT NULL,
Description varchar(1000) NOT NULL,
ImageID int NULL
)
CREATE TABLE Images (
ImageID int IDENTITY(1,1) NOT NULL,
ImageData image NOT NULL
)
With a foreign-key of the Products' ImageID to the Images' ImageID.
So what's the best way to move the data contained within these table from multiple source databases into one destination database with the same schema. My primary issue is maintaining the links between the products and their respective images.
In SQL Server, you can enable identity inserts:
SET IDENTITY_INSERT NewTable ON
<insert queries here>
SET IDENTITY_INSERT NewTable OFF
While idenitity insert is enabled, you can insert a value in the identity column like any other column. This allows you to just copy the tables, for example from a linked server:
insert into newdb.dbo.NewTable
select *
from oldserver.olddb.dbo.OldTable
I preposition the data in staging tables (Adding a newid column to each). I add a column temporarily to the table I'm merging to that is Oldid. I insert the data to the parent table putting the currect oldid inthe oldid column. I use the oldid column to join to the staging table to populate the newid column in the staging table. Now I have the New FK ids for the child tables and ccan insert using them. If you have SQL server 2008, you can use the OUTPUT clause to return the old and newids to a temp table and then use from there rather than dding the column. I prefer, to have the change explicitly stored ina staging table though to troubleshoot issues in the conversion. At the end nullout the values inteh oldid column if you are then going to add records from a third database or drop it if you are done. Leave the staging tables in place for about a month, to make research into any questions easier.
In this case you could move the images and then move the products. This would ensure that any image a product has a reference to will already be in place.

creating multiple tables with single sql command

I searched for this here and on google and surprisingly couldn't find an answer. I tried to create syntax to submit to mysql that would create multiple tables with the same columns, but it returned an error. Can you point out what is wrong with my syntax, or if this is even possible?
CREATE TABLE news, life
(
id int PRIMARY KEY AUTO_INCREMENT ,
name varchar( 30 ) ,
email varchar( 50 ) ,
COMMENT text,
datetime datetime,
ip varchar( 20 )
)
you are in mysql so you can use the LIKE clause of the CREATE TABLE command; that way you will also get column attributes and indexes copied over e.g.
CREATE TABLE new_tbl LIKE orig_tbl;
see http://dev.mysql.com/doc/refman/5.1/en/create-table.html
Use LIKE to create an empty table
based on the definition of another
table, including any column attributes
and indexes defined in the original
table: CREATE TABLE new_tbl LIKE
orig_tbl; The copy is created using
the same version of the table storage
format as the original table. The
SELECT privilege is required on the
original table. LIKE works only for
base tables, not for views. CREATE
TABLE ... LIKE does not preserve any
DATA DIRECTORY or INDEX DIRECTORY
table options that were specified for
the original table, or any foreign key
definitions.
It's not possible like that.
Think about your table design. This sounds like you should consider creating a single table and adding another column type that will be news or life (or a reference to another table defining types).
If you really need two tables, create your first table:
CREATE TABLE news
(
id int PRIMARY KEY AUTO_INCREMENT ,
name varchar( 30 ) ,
email varchar( 50 ) ,
COMMENT text,
datetime datetime,
ip varchar( 20 )
)
and then
CREATE TABLE life AS ( SELECT * FROM news where 1=2 );
Indexes and constraints (UNIQUE, PRIMARY KEY, FOREIGN KEY) will not be copied though. You will have to handle them yourself.