Click here to Skip to main content
15,881,938 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi.. I have a table named A .it has fields

Id   Name     Mark  Attendence  Total 

1    Aswathi     30        30      50


And table named B


Name     Test1  Test2

Aswathi  20      40




I need to concatenate two tables as

Id   Name      Test1  Test2 Mark Attendence   Total

1    Aswathi      20     40  30    20          50



table B is dynamic..We can create any no of test and the average of that shows in table A.How it is possible in sql??


Thanks ,
Posted

This can be simply achieved using an INNER JOIN.
SQL
SELECT
   A.ID, A.Name, B.Test1, B.Test2, A.Mark, A.Attendence, A.Total
FROM 
   TableA A
INNER JOIN 
   TableB B 
ON A.Name = B.Name


NOTE: Though, I would like to point you out that the joining field out here is Name - an alphanumeric field. It is suggestible that an integer based ID field be foreign key for easy comparison and avoid issues.
 
Share this answer
 
Comments
Rahul Rajat Singh 20-Jul-12 0:13am    
Perfect. +5.
Since Table B is dynamic, and there are possibilities for dynamic column with varying column name, there can be challenge in specifically mention the column name as B.Test1, B.Test2 as there can be Test3, Test4, etc unless dynamic query is applied.

Result using dynamic query (with sample records):
SQL
BEGIN TRAN

DECLARE @TestColumns NVARCHAR(MAX)
SET @TestColumns = N'B.TEST1,B.TEST2';

CREATE TABLE A (Id INT,  Name VARCHAR(100),    Mark INT, Attendence INT, Total INT);

INSERT INTO A VALUES (1,'Aswathi',30,20,50);
INSERT INTO A VALUES (2,'Benny',20,30,50);

CREATE TABLE B (Name VARCHAR(100),  Test1 INT, Test2 INT);

INSERT INTO B VALUES('Aswathi',20,40)
INSERT INTO B VALUES('Benny',10,30)

DECLARE @QuerySQL NVARCHAR(MAX)
SET @QuerySQL = N'
SELECT
    A.ID, A.Name, ' + @TestColumns + ', A.Mark, A.Attendence, A.Total
    FROM A
INNER JOIN B
    ON A.Name = B.Name'


EXECUTE(@QuerySQL)

ROLLBACK TRAN



Suggest, instead of creating dynamic column in respect with number of Test, each Test and corresponding marks can be recorded as each Table record like,

SQL
CREATE TABLE B (Name VARCHAR(100),  Test VARCHAR(25), Mark INT);
INSERT INTO B VALUES('Aswathi','Test1',20)
INSERT INTO B VALUES('Aswathi','Test2',40)

INSERT INTO B VALUES('Benny','Test1',10)
INSERT INTO B VALUES('Benny','Test2',30)



Using this structure, result can be achieved using the query below.

SQL
BEGIN TRAN
CREATE TABLE A (Id INT,  Name VARCHAR(100),    Mark INT, Attendence INT, Total INT);

INSERT INTO A VALUES (1,'Aswathi',30,30,0);
INSERT INTO A VALUES (2,'Benny',20,30,0);


CREATE TABLE B (Name VARCHAR(100),  Test VARCHAR(25), Mark INT);
INSERT INTO B VALUES('Aswathi','Test1',20)
INSERT INTO B VALUES('Aswathi','Test2',40)

INSERT INTO B VALUES('Benny','Test1',10)
INSERT INTO B VALUES('Benny','Test2',30)

SELECT Name, AVG(Mark) Mark INTO #tmp FROM B GROUP BY Name

DECLARE @PivotColumnHeaders VARCHAR(MAX)
SELECT @PivotColumnHeaders =
 COALESCE(
  @PivotColumnHeaders + ',[' + [Test] + ']',
  '[' + [Test] + ']'
 )
FROM (SELECT DISTINCT TEST FROM B) TMP
ORDER BY Test

DECLARE @PivotTableSQL NVARCHAR(MAX)
SET @PivotTableSQL = N'
SELECT A.Id,TMP1.*,TMP2.Mark,A.Attendence,TMP2.Mark + A.Attendence Total FROM
(SELECT * FROM b
    PIVOT (
        AVG(Mark)
        FOR Test IN (' + @PivotColumnHeaders + ')) AS PivotTable
) TMP1
INNER JOIN #TMP TMP2
    ON TMP1.Name = TMP2.Name
INNER JOIN A
    ON A.Name = TMP1.Name
'
EXECUTE(@PivotTableSQL)


ROLLBACK TRAN


Note: You may avoid DISTINCT clause by refer to any Test master if available.
Mark is calculated using AVG. Based on your requirement this can be changed to SUM.
 
Share this answer
 
v2
Why can't we just do like this?

SQL
SELECT A.Id, B.*, A.Mark, A.Attendence, A.Total
FROM dbo.A
INNER JOIN dbo.B ON A.Name = B.Name
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900