I have two tables and did an inner join on them based on id. Now I need to name this joined table. How do I do that? The reason I want to name this table is because I have to join this result table with some other tables.
You created what is commonly referred t as a relvar, not another table. You can join to it by placing it's SELECT definition in a sub query like this:
SELECT
FROM (
-- original join SQL
) t
INNER JOIN table2 on ...
You can create an alias for the result of a join using a subquery. For example:
select *
from (
select *
from tbl1
join tbl2
on tbl1.id = tbl2.id
) as JoinAlias
join tbl3
on JoinAlias.id = tbl3.id
You can often make do without such an alias. For example, consider a third join:
select *
from tbl1
join tbl2
on tbl1.id = tbl2.id
join tbl3
on tbl3.col1 = tbl1.col1
and tbl3.col2 = tbl2.col2
As you can see, the third join's condition can refer to columns from all earlier tables.
select * from (
select * from TableA a join TableB b on a.id = b.a_id
) as p;
As per the comments, it seems that a view might be what you are looking for:
create view MyView
as
select * from TableA a join TableB b on a.id = b.a_id;
It won't be listed in the tables (rather in the views), but will behave just like a table in your sql editor.
Related
I am trying to join only select columns from 3 different tables and haven't been successful.
Table 1, Patient, has the following columns I need:
ExternalID, UserDefinedXML, ServiceSiteUid
Table 2, PDI, has the following columns I need:
Patient ID, FirstName, LastName, State
Table 3, ListServiceSite has the following columns I need:
ServiceSiteUid, Name
I need to join Patient and PDI based on the common ID columns ExternalID and PatientID, and then join Patient and ListServiceSite by ServiceSiteUid.
Here's what I have that has been unsuccessful:
SELECT
*
FROM
(SELECT
ExternalID, UserDefinedXml, ServiceSiteUid
FROM
Patient) A
INNER JOIN
(SELECT
[Patient ID], FirstName, LastName, State
FROM
PatDemogImport) B ON A.ExternalID = B.[Patient ID]
WHERE
UserDefinedXml IS NOT NULL;
I am very new to SQL so please have patience! Thank you in advance.
This should do it
SELECT *
FROM Patient as p
JOIN PatDemogImport as pdi
ON p.ExternalID = pdi.[Patient ID]
JOIN ListServiceSite as lss
ON lss.ServiceSiteUid = p.ServiceSiteUid
WHERE p.UserDefinedXml IS NOT NULL;
SELECT * FROM PATIENT
JOIN
PDI on PATIENT.ExternalID = PDI.ExternalID AND PATIENT.PatientID = PDI.PatientID
JOIN
ListServiceSite on ListServiceSite.ServiceSiteUid = PATIENT.ServiceSiteUid
where
UserDefinedXml IS NOT NULL;
That should give you what you're looking for. There's no need for subselects in this instance.
Essentially what you are doing is joining the tables based on the relationship between columns. So in the above we join PDI and PATIENT based on their 2 shared columns and ListServiceSite and PATIENT on ServiceSiteUid.
Please note that when you do a SELECT *, you will get duplicate columns in the result (since you're basically getting all the columns across all those tables) so I'd recommend specifying what you select. i.e. SELECT PATIENT.ExternalID, ....
Finally, I'd recommend reading up on the different kind of joins. The above is just a regular join but there are several others like OUTER JOIN INNER JOIN RIGHT JOIN LEFT JOIN and they all have differences.
SELECT Patient.*
FROM Patient INNER JOIN PatDemogImport as pdi ON
Patient.ExternalID=pdi.Patientid
Inner join ListServiceSite on
Patient.ServiceSiteUid=ListServiceSite.ServiceSiteUid
WHERE Patient.UserDefinedXml IS NOT NULL
Isn't it just as simple as this? You want an inner join and you just need to specify the columns you need. This should give you exactly the answer you're looking for. These other answers have the same idea, but they assume that the tables contain only the columns listed and no other columns. PatientID should be the same as ExternalID so no need to specify that column and C.ServiceSiteUid should be the same as in Patient.
SELECT A.ExternalID, A.UserDefinedXML, A.ServiceSiteUid,
B.FirstName, B.LastName, B.State,
C.Name
FROM Patient A
INNER JOIN PatDemogImport B ON B.PatientID = A.ExternalID
INNER JOIN ListServiceSite C ON C.ServiceSiteUid = A.ServiceSiteUid
WHERE A.UserDefinedXML IS NOT NULL
I am having a SQL Query which is having join with the View.
View Consist of two table simple join.
So i replaced the view with join to the base table join.
Earlier Query Was
SELECT DISTINCT sts.st_id,md.MarketId,fc.ct_desc MarketName
INTO #tempReviewMarketIds
FROM #MarketIds md
JOIN [dbo].[table1] fc ON md.MarketId = fc.ct_id
JOIN [dbo].[viewname] sts ON fc.ct_pkey = sts.ct_pkey
Structure Of View:
create view viewname as
select s.st_id, c.ct_pkey from
table1 c
join table2 a on c.ct_pkey = a.ae_ctpkey
join table3 s on a.ae_pkey = s.st_aepkey;
Final Query :
SELECT DISTINCT s.st_id,md.MarketId,fc.ct_desc MarketName
FROM #MarketIds md
JOIN [dbo].[table1] fc ON md.marketid = fc.ct_id
JOIN table2 a ON fc.ct_pkey = a.ae_ctpkey
JOIN table3 s ON a.ae_pkey = s.st_aepkey;
Earlier That query cost was 80% but now the query cost increased to 86%.
I am putting values in the temp table.Mainly Insert option increases in %age.
I have learned that join with view always slows the query and more I/O,O/P.
Can anyone tell me the reason?
I have a SQL query that looks like this
Select a.*
From table1 a
where a.ColumnName in
(Select MAX(b.ColumnName)
from table2 b
where b.ColumnName2 in
(
Select MAX(c.columnName)
from table3 c
Group by c.ColumnName2
)
Group by b.ColumnName2
)
I am trying to write this in a join statement. I am positive inner join is what I need to get the right information. If someone could translate this to a join statement, I would be really glad.
Thank you.
EDIT 1:
I tried the typical Join statement that a rookie would.
Select a.*
from table1 a
inner join table2 b
on a.columnname = (Select max(b.columnName) from table2)
inner join table3 c
on b.columnName = (select max(c.columnName) from table3)
Obviously, that didn't work because I get 100,000+ results when I should be getting 800. I tried using an alias for table2 and table3 INSIDE the subselect statements and selecting the columnname using THAT alias like this:
Select max(bPart.columnName from table2 bPart)
Select max(cPart.columnName from table3 cPart)
Still the same result.
PERHAPS....
Though I'm not sure why a join is needed. Performance wise exists would likely be fastest, and since you're not returning values from table2 or 3 it seems like it would be the best approach.
SELECT a.*
FROM table1 a
INNER JOIN (SELECT MAX(ColumnName) MColumnName, columnname2
FROM table2
GROUP BY columnName2) B
ON A.columnName = B.mColumnName
INNER JOIN (SELECT MAX(columnName) mColumnName
FROM table3
GROUP BY ColumnName2) C
ON B.columname2 = C.MColumnName
I have a SQL Server query for an inner join...
SELECT *
FROM tableA
INNER JOIN tableB on tableA.my_id = tableB.my_id
How would I find all the records that did NOT match in this join?
You can use a FULL JOIN to combine the two tables, then use a WHERE clause to filter the results down to only non-matching rows by checking for a NULL in each tables primary key value.
Full outer join All rows in all joined tables are included, whether they are matched or not.
SELECT a.pk, b.pk
FROM tableA a
FULL JOIN tableB b ON a.pk=b.fk
WHERE
a.pk IS NULL
OR b.pk IS NULL
SELECT A2.* FROM TableA A2
WHERE A2.my_id NOT IN
(Select tableA.my_id FROM
tableA
inner join
tableB
on tableA.my_id = tableB.my_id)
you could similarly do the above starting SELECT B2.* FROM TableB B2, in order to separately query unmatched records in Table B
if you want all records in one table you could UNION ALL the two queries, depending on the table field structures being the same or how you specify the fields you select - what are you doing with the data?
SELECT * FROM tableA where my_id NOT IN (SELECT my_id from tableB)
UNION ALL
SELECT * FROM tableB where my_id NOT IN (SELECT my_id from tableA)
I am trying to write a query that join to a TableA another TableB if TableA.Column1 contains numeric values and Join to TableA another TableC if TableA.Column1 contains varchar values.
Is there a way to write such a query?
How about something like this? You will need to cast the columns appropriate to some middle ground.
SELECT *
FROM TableA a
INNER JOIN TableB b ON b.Columns1 = a.Column1
AND ISNUMERIC(a.Column1) = 1
WHERE 1=1
UNION
SELECT *
FROM TableA a
INNER JOIN TableC c ON c.Columns1 = a.Column1
AND ISNUMERIC(a.Column1) = 0
The table design sounds questionable, but I think this query is a simple way to achieve what you're asking for.
SELECT
TableA.Column1,
TableB.Column2,
TableC.Column2,
ISNULL(TableB.Column2, TableC.Column2)
FROM TableA
LEFT OUTER JOIN TableB ON
ISNUMERIC(TableA.Column1) = 1
AND TableA.Column1 = TableB.Column1
LEFT OUTER JOIN TableC ON
ISNUMERIC(TableA.Column1) = 0
AND TableA.Column1 = TableC.column1
As Mike Cheel points out, you may need to do some casting.
Also, with this approach you will need to consider the possibility that there is a record in TableA that does not match anything in TableB or TableC, because this is using outer joins. If you don't want those records in your result, you can just exclude them with a condition in your WHERE clause.
Along the lines of JNK's comment, here's a way where you could go about it which at least tries to encapsulate the design issue a bit, by add 2 Computed columns to your table, which represent placeholders for the INT and VARCHAR foreign keys.
ALTER TABLE MyTable ADD IntJoinColumn AS
CASE WHEN ISNUMERIC(BadJoinColumn) = 1
THEN CAST(BadJoinColumn AS INT)
ELSE NULL
END;
ALTER TABLE MyTable ADD VarCharJoinColumn AS
CASE WHEN ISNUMERIC(BadJoinColumn) = 1
THEN NULL
ELSE BadJoinColumn
END;
You can then join in a more 'readable' manner, like so:
SELECT mt.*
FROM MyTable mt
INNER JOIN MyIntJoinTable ON IntJoinColumn = MyIntJoinTable.Id
UNION ALL
SELECT mt.*
FROM MyTable mt
INNER JOIN MyVarCharJoinTable ON VarCharJoinColumn = MyVarCharJoinTable.VarCharId;
SQLFiddle Here
(The NULL mapping has the effect of filtering out the 'incorrect' data types by eliminating them during the INNER JOIN.)