using joins combine two or more tables into one Table - sql

I have two types of databases like,
Db1:
Degrees:
ID
Name
Type
Qualifications:
Id
CandidateId
DegreeId
specialization
DB2:
UG_LIST :
Name
ID
PGLIST :
Name
ID
DoctorateList:
Name
ID
Here Degrees table is single one. All degrees like Ug, Pg, doctorate are stored single table called Degrees.But In database -2, every item created as separate tables. So I have to take these three table values store into Qualifications table.
I used joins for this. But I can't create the select query for this.
SELECT top(50) 'INSERT INTO CandidateQualifications(candidateId,DegreeId,specialization) VALUES('+
Cast(c.CandidateID as varchar(50))+',''' +
Isnull(Cast(u.Id as varchar(50)),'NULL') Or cast(p.Id as varchar(50)) or cast(d.Id as varchar(50))+','+
IsNull(''''+c.ugspecification+'''', 'NULL')+')'
FROM candidatedetails as c
right join UG_List As u ON c.qualification=u.UGName
right join PG_List As p ON c.qualification=u.pgname
right join Docorate_List As d ON c.qualification=u.docorate
Please tell how to do this? I use Or operator but it is not accepting.
Any idea?

Replace:
Isnull(Cast(u.Id as varchar(50)),'NULL') Or cast(p.Id as varchar(50)) or cast(d.Id as varchar(50))
With:
Cast(Coalesce(u.Id,p.Id,d.Id)as varchar(50))
I'd expect the joins to be left
SELECT top(50) 'INSERT INTO CandidateQualifications(candidateId,DegreeId,specialization) VALUES('+
Cast(c.CandidateID as varchar(50))+',''' +
Cast(Coalesce(u.Id,p.Id,d.Id)as varchar(50))+','+
IsNull(''''+c.ugspecification+'''', 'NULL')+')'
FROM candidatedetails as c
LEFT join UG_List As u ON c.qualification=u.UGName
LEFT join PG_List As p ON c.qualification=p.pgname
LEFT join Docorate_List As d ON c.qualification=d.docorate

Related

How can I run my SQL, to get the result such as "John Doe, plumbing"

I have table category, with id and cat_name
Example: 152, Plumbing
I have table user, with category_id and name
Example: 152, John Doe
When I do
SELECT name, category_id FROM user
As a result I will have something like
John Doe, 152
Question:
How can I run my SQL, to get the result such as
John Doe, plumbing
It is quite easy to get this, Please use below query for the same
SELECT User.Name, Category.cat_name FROM User
INNER JOIN Category ON Category.Id = User.category_id
Happy coding :-)
Try basic JOINS
SELECT C.cat_name, U.Name
FROM category C JOIN User U ON C.id = U.category_id
this will work:
select a.name,b.cat_name from user a, category b
where a.category_id=b.id
As you can understand you have two tables, and there is some 1 to 1 relationship between records of these tables(user & category).
So here we will use a simple join to connect this two table.
SELECT c.cat_name, u.name
FROM category as c, user as u
WHERE c.id = u.category_id
When I do category as c, this is called aliasing. This has two benefits. One is to keep our query short and sweet(no need to repeat category, just use c) and second is SQL query engine has 100% clarity of what we want to select.
Let's you also want to select id, then you should use c.id or u.category_id.
Check these alternate methods-
IF OBJECT_ID('Category') IS NOT NULL
DROP TABLE Category
IF OBJECT_ID('User') IS NOT NULL
DROP TABLE [User]
CREATE TABLE Category
(ID INT,Cat_name VARCHAR(20))
CREATE TABLE [User]
(Category_id INT,[Name] VARCHAR(20))
INSERT INTO Category(ID ,Cat_name)
VALUES (152,'Plumbing')
INSERT INTO [User](Category_id ,[Name])
VALUES (152,'John Doe')
--Method 1 (using CROSS APPLY)
SELECT U.[Name], C.Cat_name FROM [User] U CROSS APPLY Category C WHERE U.Category_id=C.ID
--Method 2 (using INNER JOIN)
SELECT U.[Name], C.Cat_name FROM [User] U INNER JOIN Category C ON U.Category_id=C.ID
--Method 3 (using WHERE and WITHOUT JOIN)
SELECT U.[Name], C.Cat_name FROM [User] U,Category C WHERE U.Category_id=C.ID

Joining same table multiple times

I have 2 tables Person an Department - where each person has multiple departments registered against him.
Person
id|name|dept1|dept2|dept3
1 |Jane|100 |102 |106
Dept
id |Name
100|Accounts
...
102|HR
...
106|Admin
Whats the most elegant sql to display Jane's record as follows:
Jane|Accounts|HR|Admin
Use this. And work on your naming convention to make all column names unique independent of table.
SELECT
Person.id, Person.name, dept1.Name, dept2.Name, dept3.Name
LEFT JOIN Dept dept1 ON dept1.id = Person.dept1
LEFT JOIN Dept dept2 ON dept2.id = Person.dept2
LEFT JOIN Dept dept3 ON dept3.id = Person.dept3
Something like this will let you join the same table multiple times. You just give each join a different alias
SELECT *
FROM Person AS P
INNER JOIN Dept AS D1 ON P.dept1 = D1.id
INNER JOIN Dept AS D2 ON P.dept2 = D2.id
WHERE P.name = 'Jane'
Ideally you would normalise the data in your Person table and have a linking table between Person and Dept e.g. PersonDepartmentLinking (or whatever convention you have for linking table naming conventions), assuming you have any control over the schema and it's possible to add the relationship that way.
You can use STUFF in this case
Select name,
Stuff((Select distinct ', ' + cast(Name as varchar(20))
From #Dept t2
Where t2.Id = t1.Id
FOR XML PATH('')),1,1,'')
From Person t1
The only way that I know is a join for each column.
But if you are in the way of designing the tables, i suggest you to normalize the DB.
If a person need an extra dept column, you need to alter the table to add a new property of person.
For me, 3 entities are needed:
- Person
- Department
- person_department_assignation

Join query on comma separated values

This is my 1st table :
this is another table on which i want to perform join operation :
I want to retrieve first_name for "activity_cc" column
For example, I want to show Pritam,Niket for activity_id=2
How can I retrieve those values?
From http://mikehillyer.com/articles/an-introduction-to-database-normalization/
The first normal form (or 1NF) requires that the values in each column
of a table are atomic. By atomic we mean that there are no sets of
values within a column.
Your database design violates the first normal form of database design. It is a simply unworkable design and it must be changed (and frankly the database designer who created this should be fired as this is gross incompetence) or there will be severe performance problems and querying will always be difficult. There is a reason why the very first rule of database design is never store more than one piece of information in a field.
Yes you could use some hack methods to get the answer you want, but they will cause performance issues and they are the wrong thing to do. A hack to fix this data into a related table used one-time is fine, a hack to continuallly query your database is simply a poor choice. It will cost less time in the long run to fix this cancer at the heart of your database right now. But in general the process to fix this is to split the data out into a related table using some version of fn_split (look up the various implementations of this for a script to create the function). You can use a temp table in your query or do the right thing and fix the database.
If you want to retrieve the result on the basis of Join then why don't you join your both tables on the "registration_id" by using inner-join. And please clearify me you want to perform the join on the active_cc, but its actually not present in your second table. So how you preform join in that case.
I completely agree with #HLGEM, but to solve this particular problem cost will be high.
I had given a try to want you want to achive here. Please modify the join if needed.
Let me know if any further help needed.
Sample Schema
create table tableC (ACTIVITY_ID int, REG_ID int,PROJ_ID int,DOSS_ID int,ACTIVITY_TO int, ACTIVITY_CC varchar(500))
insert into tableC select 4, 1,1,1,1, '3,4';
insert into tableC select 5, 2,2,2,2, '5,6';
insert into tableC select 6, 3,3,3,3, '3,5';
create table tableD (REG_ID int , FIRST_NAME VARCHAR(100), LAST_NAME VARCHAR(100))
insert into tableD select 3, 'Pritam', 'Sharma';
insert into tableD select 4, 'Pratik', 'Gupta';
insert into tableD select 5, 'Niket', 'Vaidya';
insert into tableD select 6, 'Ajinkya', 'Satwa';
Sample Query
with names as
(
select C.ACTIVITY_ID,C.ACTIVITY_CC
,Names = D.FIRST_NAME
from tableC C
inner join tableD D on charindex(cast(D.REG_ID as varchar), C.ACTIVITY_CC) > 0
)
select
C.ACTIVITY_ID,C.REG_ID,PROJ_ID,DOSS_ID,ACTIVITY_TO,ACTIVITY_CC
,Names = stuff
(
(
select ',' + Names
from names n
where n.ACTIVITY_ID = D.REG_ID
for xml path('')
)
, 1
, 1
, ''
)
from tableD D
inner join tableC C on C.ACTIVITY_ID = D.REG_ID
Added to SQLFiddle also
Considering Pratik's structure
CREATE TABLE tableC
(
ACTIVITY_ID int,
REG_ID int,
PROJ_ID int,
DOSS_ID int,
ACTIVITY_TO int,
ACTIVITY_CC varchar(500)
);
INSERT INTO tableC select 4, 1,1,1,1, '3,4';
INSERT INTO tableC select 5, 2,2,2,2, '5,6';
INSERT INTO tableC select 6, 3,3,3,3, '3,5';
CREATE TABLE tableD
(
REG_ID int,
FIRST_NAME VARCHAR(100),
LAST_NAME VARCHAR(100)
);
INSERT INTO tableD select 3, 'Pritam', 'Sharma';
INSERT INTO tableD select 4, 'Pratik', 'Gupta';
INSERT INTO tableD select 5, 'Niket', 'Vaidya';
INSERT INTO tableD select 6, 'Ajinkya', 'Satwa';
You can do this:
SELECT tableD.FIRST_NAME
FROM tableD
JOIN tableC ON tableC.ACTIVITY_CC LIKE CONCAT('%', tableD.REG_ID, '%')
GROUP BY tableD.FIRST_NAME;
OR
SELECT FIRST_NAME
FROM tableD, tableC
WHERE tableC.ACTIVITY_CC LIKE CONCAT('%', tableD.REG_ID, '%')
GROUP BY tableD.FIRST_NAME;

Select persons which have overlap with other table

I didn't even know how to come up with a good title, so I hope I can describe my problem in a right way :)
So I have a person table, and it has a N:N relationship with keywords via the table PersonKeywords.
Then I also have a Search table, and it also has a N:N relationship with keywords via the table SearchKeywords.
Now the person can have a relationship with keyword A and B, and the search record can have a relationship with the keywords A and C.
Now I want the person in my resultset, because it has at least one (in this 'A') of the keywords the search record has.
I also want the person who has 'A', the one with 'C', the one with 'A' and 'C', but not the one with only B.
So it's a match on two lists, but I don't know where to start to create such a statement...
So you have three people...
declare #persons table (id int identity(1,1), name varchar(10))
insert #persons (name) values ('Babs'),('Ken'),('Neville'),('Sue')
Babs has A and B, Ken has A and C, Neville has B only and Sue has C only
declare #personkeywords table (personid int, keyword varchar(5))
insert #personkeywords values (1,'a'),(1,'b'),(2,'a'),(2,'c'),(3,'b'),(4,'c')
The search is for A or C
declare #searchkeywords table (searchid int, keyword varchar(5))
insert #searchkeywords values (1,'a'),(1,'c')
So...
select distinct persons.*
from #persons persons
inner join #personkeywords personkeywords on persons.id = personkeywords.personid
inner join #searchkeywords searchkeywords on personkeywords.keyword = searchkeywords.keyword
where
searchkeywords.searchid = 1
Gives
1 Babs
2 Ken
4 Sue
Although I don't have very much information to work with, the following should at least help you...
SELECT s.SearchID, k.Keyword, p.PersonID, p.Name
FROM Search s
INNER JOIN SearchKeywords sk ON s.SearchID = sk.SearchID
INNER JOIN Keywords k ON sk.KeywordID = k.KeywordID
LEFT OUTER JOIN PersonKeywords pk ON k.KeywordID = pk.KeywordID
LEFT OUTER JOIN Person p ON pk.PersonID = p.PersonID
WHERE k.Keyword = 'mykeyword'
GROUP BY s.SearchID, k.Keyword, p.PersonID, p.Name

How to write the right SQL query statement using join condition?

There are three fields in a table, all of them refer the same field in another table, like this:
table1
-------
! a_term_id* ! b_term_id* ! c_term_id* !
! ! ! !
table2
-------
! term_id ! term_title ! term_description !
! ------- ! ! !
columns a_term_id, b_term_id, c_term_id all refer to term_id
How should I write the SQL statement to retrieve the three fields' info?
I think you need to know how Sql_Join works. Here on W3Schools you can find useful examples.
A simple example:
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
INNER JOIN Orders
ON Persons.P_Id=Orders.P_Id
ORDER BY Persons.LastName
EDIT
You can try something like this:
SELECT * FROM tableA
inner join tableB on tableA.term_id = tableB.term_id
inner join tableC on tableA.term_id = tableC.term_id;
It an example you can modify as per your need.
Edit 2
SELECT * FROM tableB
JOIN tableA AS tableA1 ON tableB.term_id = tableA1.a_term_id
JOIN tableA AS tableA2 ON tableB.term_id = tableA2.b_term_id
JOIN tableA AS tableA3 ON tableB.term_id = tableA3.c_term_id
Here is an example. Suppose that we have two tables - Employees and Companies:
CREATE TABLE Employees(
Id int,
Name varchar(128),
CompanyId int);
CREATE TABLE Companies(
Id int,
Name varchar(128),
Address varchar(1024),
DateFounded datetime);
The following SQL query will join the tables:
SELECT * FROM Employees
INNER JOIN Companies
ON Employees.CompanyId = Companies.Id
Your question is a bit unclear, but I'll guess that you have a table A with three fields, each of which identifies a (possibly different) row from table B. You want to retrieve info from each of those rows of table B based on the field values of a single row of table A.
To do this, you will need to join table A to table B three times, once for each field of table A. Each join should be given an alias and then you can refer to the fields in the joined table by qualified field names.
SELECT b1.info, b2.info, b3.info
FROM A JOIN B AS b1 ON field1 = b1.field
JOIN B AS b2 ON field2 = b2.field
JOIN B AS b3 ON field3 = b2.field
WHERE ...
SELECT
t.a_term_id, a.term_title, a.term_description,
t.b_term_id, b.term_title, b.term_description,
t.c_term_id, c.term_title, c.term_description
FROM abc_terms t JOIN ( terms_info a, terms_info b, terms_info c )
ON ( t.a_term_id = a.term_id
AND t.b_term_id = b.term_id
AND t.c_term_id = c.term_id )