Inner join between different database - sql

I want to create a table using the following script in a database called DeltaDatabase:
CREATE TABLE [dbo].[OutStatus](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[OutId] [int] NOT NULL,
[StatusType] [varchar](255) NULL,
[StatusDate] [datetime] NULL)
I would then like to INNER JOIN a column into this table from another database called CoreDatabase.
The column name is sourceId from the table Client. So in other words OutId needs to be foreign key of SourceId.
How do I join that column into my OutStatus table from the other database using the create table script?

The basic syntax to retrieve data would be:
SELECT *
FROM CoreDatabase.dbo.Client c
INNER JOIN DeltaDatabase.dbo.OutStatus os ON c.SourceId = os.OutId
You need to fully qualify the tables name with: DatabaseName.Schema.TableName
You may wish to limit the columns or add a where clause to reduce the data that is returned.
As far as creating a foreign key across databases goes, it's not something you can do. You would have to use triggers or some other logic to maintain referential integrity between the primary and foreign keys.

Try the below query
Select * from DeltaDatabase.dbo.OutStatus OUS
Inner Join CoreDatabase.dbo.Client CL on OUS.OutId=CL.sourceId

Related

Retrieving data from a many-to-many relationship in a recipes database

I am attempting to create a recipes database where a user can input ingredients and it will output a list of potential recipes. I have created three tables:
CREATE TABLE [dbo].[Ingredients] (
[Ingredient_ID] INT IDENTITY (1, 1) NOT NULL,
[Name] VARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([Ingredient_ID] ASC)
);
CREATE TABLE [dbo].[recipes] (
[Recipe_ID] INT IDENTITY (1, 1) NOT NULL,
[Name] VARCHAR (50) NOT NULL,
[Instructions] TEXT NULL,
[Preperation_Time] FLOAT (53) NULL,
[Author] VARCHAR (50) NULL,
CONSTRAINT [PK.recipes] PRIMARY KEY CLUSTERED ([Recipe_ID] ASC)
);
CREATE TABLE [dbo].[RecipeIngredients] (
[Recipe_ID] INT NOT NULL,
[Ingredient_ID] INT NOT NULL,
PRIMARY KEY CLUSTERED ([Recipe_ID] ASC, [Ingredient_ID] ASC),
CONSTRAINT [FK_RecipeIngredients_To_Ingredients] FOREIGN KEY ([Ingredient_ID]) REFERENCES [dbo].[Ingredients] ([Ingredient_ID]),
CONSTRAINT [FK_RecipeIngredients_To_Recipes] FOREIGN KEY ([Recipe_ID]) REFERENCES [dbo].[recipes] ([Recipe_ID])
);
I have populated all tables and I am now attempting to retrieve the recipes based on what the user has entered.
I have a created a test SQL statement to retrieve all recipes that contain 'Eggs' using:
string sqlString = "SELECT recipes.Name, Instructions, recipes.Preperation_Time, Author FROM RecipeIngredients" +
" INNER JOIN recipes ON recipes.Recipe_ID = RecipeIngredients.Recipe_ID" +
" INNER JOIN Ingredients ON Ingredients.Ingredient_ID = RecipeIngredients.Ingredient_ID" +
" WHERE ingredients.Name = 'Eggs'";
The data does not show up in my dataGridView, but I am unsure if it is because the statement is wrong or other factors.
Is the statement correct? I am unfamiliar with the INNER JOIN command.
I am also unsure how to design an Sql statement that can take a varying amount of ingredient names without creating an Sql statement for every possibility.
Thanks in advance, if you need me to expand on anything I have asked please ask.
Here is the query that should work. Use of aliases is recommended
SELECT r.Name, r.Instructions, r.Preperation_Time, r.Author
FROM Ingredients i
join RecipeIngredients ri on i.Ingredient_ID = ri.Ingredient_ID
join recipes r on ri.Recipe_ID = r.Recipe_ID
where i.Name = 'Eggs'
You may want to run it through SQL Server Management Studio to ascertain return of result before coding it in C# solution.

Is it good to have multiple inner joins in SQL select statement?

I have a table which looks like this:
CREATE TABLE [dbo].[Devices]
(
[Device_ID] [nvarchar](10) NOT NULL,
[Series_ID] [int] NOT NULL,
[Start_Date] [date] NULL,
[Room_ID] [int] NOT NULL,
[No_Of_Ports] [int] NULL,
[Description] [text] NULL
);
I want to show this table in a gridview, but instead of showing the [Series_ID] column, I want to show 3 columns Series_Name, Brand_Name, and Type_Name from another 3 columns, and instead of showing the [Room_ID] column, I want to show 3 columns Site_Name, Floor_Name, Room_Name from another 3 columns
I can do that by more than 6 inner joins. I am a beginner in SQL and I want to know is this right to have a lot of inner joins in one statement in point of performance?
Based on your query explanation, I assume it will be 2 inner joins instead of 6.
If Series_Name, Brand_Name and Type_Name are in one table with Series_Id as ForeignKey, then you would need one join.
Similarly, If Site_Name, Floor_Name, Room_Name are in one table with Room_ID as ForeignKey, then you would need another innjer join.
Again, it is difficult to tell the exact number of joins without understanding table structure of the other referential tables.

Get value of PRIMARY KEY during SELECT in ORACLE

For a specific task I need to store the identity of a row in a tabel to access it later. Most of these tables do NOT have a numeric ID and the primary key sometimes consists of multiple fields. VARCHAR & INT combined.
Background info:
The participating tables have a trigger storing delete, update and insert events in a general 'sync' tabel (Oracle v11). Every 15 minutes a script is then launched to update corresponding tables in a remote database (SQL Server 2012).
One solution I came up with was to use multiple columns in this 'sync' table, 3 INT columns and 3 VARCHAR columns. A table with 2 VARCHAR columns would then use 2 VARCHAR columns in this 'sync' table.
A better/nicer solution would be to 'select' the value of the primary key and store this in this table.
Example:
CREATE TABLE [dbo].[Workers](
[company] [nvarchar](50) NOT NULL,
[number] [int] NOT NULL,
[name] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Workers] PRIMARY KEY CLUSTERED ( [company] ASC, [number] ASC )
)
// Fails:
SELECT [PK_Workers], [name] FROM [dbo].[Workers]
UPDATE [dbo].[Workers] SET [name]='new name' WHERE [PK_Workers]=#PKWorkers
// Bad (?) but works:
SELECT ([company] + CAST([number] AS NVARCHAR)) PK, [name] FROM [dbo].[Workers];
UPDATE [dbo].[Workers] SET [name]='newname' WHERE ([company] + CAST([number] AS NVARCHAR))=#PK
The [PK_Workers] fails in these queries. Is there another way to get this value without manually combining and casting the index?
Or is there some other way to do this that I don't know?
for each table create a function returning a concatenated primary key. create a function based index on this function too. then use this function in SELECT and WHERE clauses

Update Query with NVARCHAR(max) in SQL Server

Have an issue with SQL Server performance and wanted to see if anyone can give some tips about improving the performance of an update query.
What I'm doing is updating one table with data from another table. Here's some of the basics:
SQL Server 2008 R2
Data is pumped to WO table originally from other system (pumped in using datareader and sqlbulkcopy in ADO.NET)
Additional data is pumped to TEMP_REMARKS (pumped in using datareader and sqlbulkcopy in ADO.NET)
Unfortunately, combining the WO and REMARKS in the originating system (via the reader query) is not possible (mainly performance reasons)
Update to WO occurs using value from TEMP_REMARKS where two columns are updated
Note that the column being transferred from TEMP_REMARKS to REMARKS is a nvarchar(max) and is being placed into another nvarchar(max) column (actually two - see query)
WO has 4m+ records
TEMP_REMARKS has 7m+ records
For the join between the two, the following is what is being used:
/* === UPDATE THE DESCRIPTION */
UPDATE WO
SET WO_DESCRIPTION = TEMP_REMARKS.REMARKS
FROM WO
INNER JOIN TEMP_REMARKS ON WO.WO_DESCRIPTION_ID = TEMP_REMARKS.REMARKS_ID;
/* === UPDATE THE FINDINGS */
UPDATE WO
SET FINDINGS = TEMP_REMARKS.REMARKS
FROM WO
INNER JOIN TEMP_REMARKS ON WO.FINDINGS_ID = TEMP_REMARKS.REMARKS_ID;
The problem at this point is that the update to the WO table is taking over two hours to complete. I've tried using the MERGE statement with no success. I've got other more completed procedures in the db that don't take nearly as long, so I'm convinced that it is not the configuration of the SQL Server itself.
Is there something that should be done when updating nvarchar(max) columns?
What can be done to improve the performance of this query?
Here are the table definitions:
CREATE TABLE [dbo].[WO](
[DOCUMENT_ID] [decimal](18, 0) NOT NULL,
[WO_DESCRIPTION_ID] [decimal](18, 0) NULL,
[WO_DESCRIPTION] [nvarchar](max) NULL,
[FINDINGS_ID] [decimal](18, 0) NULL,
[FINDINGS] [nvarchar](max) NULL,
.... bunch of other fields
CONSTRAINT [PK_WO] PRIMARY KEY CLUSTERED
(
[DOCUMENT_ID] ASC
)
This is the table definition for the TEMP_REMARKS:
CREATE TABLE [dbo].[TEMP_REMARKS](
[REMARKS_ID] [decimal](18, 0) NOT NULL,
[REMARKS] [nvarchar](max) NULL
) ON [PRIMARY]
I think, first of all you should consider to create primary key on TEMP_REMARKS, or at least some index on REMARKS_ID

Sql instead of insert trigger - insert data if does not exist

I have the following trigger on a table that redirects data and includes data from two other tables based on a LEFT OUTER JOIN.
If i.ndl_DeviceID does not exist in BBOwnerMap then that column will be null which is fine.
What I want to do is, if i.ndl_DeviceID does not exist in BBOwnerMap then i want to insert it into there and return the resulting autonumber BBOwnerMap.OwnerID
Trigger is as follows:-
ALTER TRIGGER [dbo].[Redirect]
ON [dbo].[ndl_dump]
instead of insert
AS
BEGIN
INSERT INTO ndl_data
(ndl_Image,ndl_Text,ndl_Lat,ndl_Lng,ndl_CategoryID,ownerID)
SELECT i.ndl_Image,
i.ndl_Text,
i.ndl_Lat,
i.ndl_Lng,
ndl_config.ndl_CategoryID,
BBOwnerMap.OwnerID
FROM inserted i
LEFT OUTER JOIN
ndl_config
ON i.ndl_Category = ndl_config.ndl_CategoryName
LEFT OUTER JOIN
BBOwnerMap
ON i.ndl_DeviceID = BBOwnerMap.DeviceID
END
BBOwnerMap table is like this:-
[dbo].[BBOwnerMap](
[OwnerID] [int] IDENTITY(1,1) NOT NULL,
[DeviceID] [varchar](50) NOT NULL,
[DeviceNumber] [varchar](50) NOT NULL,
CONSTRAINT [PK_BBOwnerMap] PRIMARY KEY CLUSTERED
Any help on how to modify this would be much appreciated.
Thanks.
You should be able to just add another insert statement at the top of your trigger. Always remember that the inserted table can have more than one row, so you are dealing with sets, not rows. Code assumes SQL Server. I like LEFT JOINs that don't find matches, but you could do the same with a NOT EXISTS where clause:
Insert into bbownermap (deviceid, devicenumber)
Select i.ndl_DeviceID, <deviceNum>
From inserted i
Left join bbownermap b on i.deviceid=b.deviceid
Where b.ownerid is Null