SQL - join three table with "where" clause - c#

I want to write an SP that I will use in my c# program. I have three tables: Table1 (id pk, name, ...), Table2 (id PK, name, ...) and Table3((idT1,idT2) PK FK). So, Table3 models the n:n relationship between Table1 and Table2.
I want to retrieve all the Table2.name(s) related to a single Table1.name.
I have already tried to write a query with two inner join
CREATE PROCEDURE slct
#name nvarchar(50)
AS
BEGIN
SET NOCOUNT ON;
SELECT Table2.name from Table2
join Table3 on Table2.id = Table3.idT2 join Table1 on Table1.id = Table3.idT1 where Table1.name = '%'+#name+'%'
END
GO
Table1
|1|abc|
|2|def|
Table2
|1|xyz|
|2|mno|
Table3
|1|1|
|1|2|
|2|2|
As result, I see more records than are needed. I expected a list of Table2.name related to a single Table1.name (specified by #name parameter)
sorry for my english.

select Table2.Names from Table2
inner join
(select Table3.idT1 as SubQueryID1, Table3.idT2 as SubQueryID2
from Table3 inner join Table1 on Table1.id = Table3.idT1)
on
Table2.Id = SubQueryID2

SELECT
Table2.name
FROM Table2
INNER JOIN Table3 ON Table2.id = Table3.idT2
CROSS APPLY(
SELECT TOP 1 * FROM Table1 WHERE Table1.id = Table3.idT1
) t
WHERE
Table1.name = '%'+#name+'%'

I want to retrieve all the Table2.name(s) related to a single Table1.name.
select t2.name
from table2 t2 join
table3 t3
on t3.idT2 = t2.id
group by t2.name
having count(*) = 1;
This returns names in t2 that have only one row in table3. This makes two assumptions (both of which are reasonable for this data structure):
Names are unique in table1 and table2.
Pairs are unique in table3.

I want to retrieve all the Table2.name(s) related to a single Table1.name.
Your query actually has the right join logic. You have to clarify the scope of the where clause.
Table1.Name contains #name: you need the like operator instead of the equal operator.
Table1.Name strictly equals to #name: you have to remove the wildcards.
See below two examples:
select distinct T2.Name
from Table1 as T1
inner join Table3 as T3 on T3.IDT1 = T1.ID
inner join Table2 as T2 on T2.ID = T3.IDT2
where T1.Name like '%'+#name+'%'
or
select distinct T2.Name
from Table1 as T1
inner join Table3 as T3 on T3.IDT1 = T1.ID
inner join Table2 as T2 on T2.ID = T3.IDT2
where T1.Name = #name

Related

Update one table using self-join for other table

I have two tables. I need to update the records of the 1st table performing a join with the 2nd table. But in the 2nd table I also have to put a self join.
UPDATE [T2]
SET T2.NAME = T1.NAME
FROM [TABLE2] T2
JOIN [TABLE1] T1 ON T2.ID = T1.ID
JOIN [TABLE1] T3 ON T1.RECORDTYPE = T3. RECORDTYPE
The purpose is to perform a self-join and update the other table.
Is this what you mean?
UPDATE T2
SET T2.NAME = T1.NAME
FROM T2
JOIN T1
ON T2.ID = T1.ID
AND T2.RECORDTYPE = T1.RECORDTYPE;

(SQL) Select and return all from more than 2 tables that have a common field where a specific value is present in all tables

As above, I would like the result to be one row of all the columns from each table where the value was met. The common field in all tables is the primary key. Any type of UNION does not work as the amount of columns is not the same in each table. I'm using an Access database so FULL OUTER JOINS are not supported. I'm using this query in an application in C#, Visual Studio and for some reason can't get do an inner join without it giving me a syntax error either. I'd ideally like to have this done in one query.
For example lets say I have the tables:
Table1
userID name age
1 Bob 24
2 John 19
Table2
userID col1 col2 col3
1 fd sd gh
...
Table3
userID col4 col5 col6 col7
1 ff hg fd et
...
And I want the result:
userID name age col1 col2 col3 col4 col5 col6 col7
1 Bob 24 fd sd gh ff hg fd et
Perhaps the closest I've got:
SELECT * FROM table1 AS b
INNER JOIN table2 AS c ON c.userID = b.userID
INNER JOIN table3 AS m ON m.userID = b.userID
WHERE userID = 1;
The error I get:
An unhandled exception of type 'System.Data.OleDb.OleDbException'
occurred in System.Data.dll
Additional information: Syntax error (missing operator) in query
expression 'c.userID = b.userID INNER JOIN table3 AS m ON
m.userID = b.UserI'.
I should add that I want the query to be adaptable (let's say I don't know the columns but I know it has userID)
Left joins should work in ms-access:
select *
from Table1 t1
left join Table2 t2
on t1.userID = t2.userID
left join Table3 t3
on t1.userID = t3.userID
This should work in Acces:
Select T1.userID, T1.name, T1.age, T2.col1, T2.col2, T2.col3, T3.col4, T3.col5, T3.col6, T3.col7 from Table1 T1
left join Table2 T2 on T2.userID=T1.userID
left join Table3 T3 on T3.userID=T1.userID
Or if you only want records present in the first table use an inner join:
Select T1.userID, T1.name, T1.age, T2.col1, T2.col2, T2.col3, T3.col4, T3.col5, T3.col6, T3.col7 from Table1 T1
inner join Table2 T2 on T2.userID=T1.userID
inner join Table3 T3 on T3.userID=T1.userID
So in the end I was close.
In MS-Access, when joining more than 2 tables you must use parentheses (around the first join?). Second of all, in my where condition I didn't specify a table for userID. See my amended query below:
SELECT * FROM table1 AS b
(INNER JOIN table2 AS c ON c.userID = b.userID)
INNER JOIN table3 AS m ON m.userID = b.userID
WHERE b.userID = 1;
Select
t1.userID
,t1.name
,tb1.age
,tb2.col1
,tb2.col2
,tb2.col3
,tb3.col4
,tb3.col5
,tb3.col6
,tb3.col7
FROM table1 tb1
INNER JOIN table2 tb2 ON tb1.userID=tb2.userID
INNER JOIN table3 tb3 ON tb1.userID=tb3.userID
WHERE --some conditions if u desire.
I think your problem in where condition.you did not specify the table.
So change.
Where userId=1
To be
Where b.userId=1

Count and display the most to less count in gridview

SELECT t1.CompanyName, COUNT(*) AS TotalOrder
FROM [table1] t1
INNER JOIN [table2] t2 ON t1.CompanyID = t2.CompanyID
GROUP BY t1.CompanyID
ORDER BY COUNT(*) DESC
I have the above code already just that wish to display the most count To the top and less count at the bottom in the gridview how can I do this?
Try This query.
SELECT t1.CompanyName, COUNT(t2.CompanyID) AS TotalOrder
FROM table1 t1 INNER JOIN table2 t2
ON t1.CompanyID = t2.CompanyID
GROUP BY t1.CompanyName
ORDER BY TotalOrder DESC
As far as i understand your question is you want the Company Names listed with row number in descending order. if so try this
SELECT t1.CompanyName, ROW_NUMBER() over (order by CompanyName) AS TotalOrder
FROM table1 t1 INNER JOIN table2 t2
ON t1.CompanyID = t2.CompanyID order by CompanyName desc

SQL Server NULL value with inner join

I am using C# and SQL Server.
Take a look at the following SQL:
SELECT table1.id, table1.description, table2.name, table2.surname
FROM table1
INNER JOIN table2 ON table1.EmpID = table2.EmpID
It is straight forward and works fine. It retrieves the data from table1 table just fine and inner joins table1.empid to table2.name and table2.surname correctly.
Now, sometimes table1.empid is null and when it is, this SQL just ignores the "row" with the null value; which is pretty normal basing on the criteria.
What I need here is to also get the "rows" with the null values and when table1.empid is null I need to set a custom value to table2.name and table2.surname.
I have been playing with isnull() but all I did is make it even worst.
Any suggestions?
Thanks
You need to do a LEFT JOIN:
SELECT table1.id, table1.description, table2.name, table2.surname FROM table1
LEFT JOIN table2 ON table1.EmpID = table2.EmpID;
Try using a UNION:
SELECT table1.id, table1.description, table2.name, table2.surname
FROM table1
INNER JOIN table2 ON table1.EmpID = table2.EmpID
UNION
SELECT table1.id, table1.description, 'Table 2 Null', 'Table 2 Null'
FROM table1
WHERE table1.empId is null
If table 1 is null and you still need the records that you cannot start with that. Start with table2 and join table1.
SELECT table1.id, table1.description, ISNULL(table1.empid, "some new value") AS name, table2.surname
FROM table2
LEFT OUTER JOIN table1 ON table2.EmpID = table1.EmpID
SELECT table1.id
,table1.description
,COALESCE(table2.name, 'DEFAULT') AS name
,COALESCE(table2.surname, 'DEFAULT') AS surname
FROM table1
LEFT JOIN table2
ON table1.EmpID = table2.EmpID
Now note, that this will also include people when the EmpID is not null but nevertheless "invalid" if they have an EmpID in table1, but it isn't found in table2, so if that's something you want to avoid, another option is this:
SELECT table1.id
,table1.description
,table2.name
,table2.surname
FROM table1
INNER JOIN table2
ON table1.EmpID = table2.EmpID
UNION ALL
SELECT table1.id
,table1.description
,'DEFAULT' AS name
,'DEFAULT' AS surname
FROM table1
WHERE table1.EmpID IS NULL
Select table1.id table1.description
, Case When table1.EmpID Is Null Then 'Some Value' Else table2.name End As Table2Name
, Case When table1.EmpID Is Null Then 'Some Value' Else table2.surname End As Table2Surname
From table1
Left Join table2
On table2.EmpID = table1.EmpID
Where table1.EmpID Is Null
Or table2.EmpID Is Not Null

Join 4 tables in DB with Stored Procedure?

in my database there is a table has 3 FK to other 3 tables i want to select the data in this table + data in the other 3 tables when the FK value = the PK values in the other tables
SELECT *
FROM t1
JOIN t2
ON t2.id = t1.t2_id
JOIN t3
ON t3.id = t1.t3_id
JOIN t4
ON t4.id = t1.t4_id
SELECT t1.Field1, t2.Field2, t3.Field3, t4.Field4
FROM Table t1
INNER JOIN Table2 t2 ON t1.ID = t2.ID
INNER JOIN Table3 t3 ON t1.ID = t3.ID
INNER JOIN Table4 t4 ON t1.ID = t4.ID
If there aren't always matching rows in Tables 2 - 4, and you want those records return still then change the INNER JOINs to LEFT JOIN
SELECT * FROM ParentTable as pt
LEFT JOIN table1 as t1
ON pt.t1_ID = t1.ID
LEFT JOIN table2 as t2
ON pt.t2_ID= t2.ID
LEFT JOIN table3 as t3
ON pt.t3_ID= t3.ID
This will return a record even if there are not matches in table1,2 or 3. #Ada and #Q's will exclude those records.
SELECT * FROM TBL1 T1
RIGHT JOIN TBL2 T2
ON T1.id = T2.id
RGIHT JOIN TBL3 T3
ON T3.id = T2.id
This will return all the records from Right table and matching records from Left table.

Categories