Assigning an alias to a table made by a join - sql

I am joining 3 tables as shown below -
select *
from Employee as e inner join [Grant] as g
on e.EmpID = g.EmpID -- "virtual table"
inner join Location as l
on l.LocationID = e.LocationID
Code from select to GrantID seems to be a "virtual table". So, it can be joined with another table (Location) to perform a 3 table join. I want to give this virtual table an alias. Is that possible ? If yes, then how do i do it ?
NOTE -
i use sql server 2008 express

Can't you just do this?
SELECT <columns>
FROM (SELECT <columns 2> FROM Employee as e INNER JOIN [Grant] as g on e.EmpID = g.EmpID) as t1
INNER JOIN Location as l on t1.LocationID = l.LocationID
I don't know what columns you're trying to select, thus the placeholder.

How about a CTE (Common Table Expression)? Like this:
WITH my_cte
AS ( SELECT e.EmpID as e_EmpID, g.* -- expand column list to only include required columns
FROM Employee AS e
INNER JOIN [Grant] AS g ON e.EmpID = g.EmpID -- "virtual table"
)
SELECT *
FROM my_cte
INNER JOIN Location AS l ON l.LocationID = my_cte.LocationID;
Just know that if you refer to a CTE multiple times in the subsequent query the entire query is re-executed. If you need to refer to the CTE multiple times consider storing the results in a temp table first, then executing your query to join against the temp table.

Perhaps this will do.
select *
from (select * from Employee as e
inner join [Grant] as g on e.EmpID = g.EmpID) as vt
inner join Location as l on l.LocationID = vt.LocationID
Just make sure that column names do not repeat themselves in Employee and Grant.

Related

Left join with multiple inner join

How can we make multiple left and inner join in SQL Server
Following query not returning all Employees because of Inner join
SELECT * from Employee E
LEFT JOIN Participants P on E.EmpID=P.EmpID
INNER JOIN HRDetails H on D. DeptID=H.DeptID
Left JOIN SalaryDetails S on S.participantID=P.participantID
You have used an alias D. which does not refer to any table, this may cause error.
But to answer your question I think inner join would reduce the number of rows if not all DeptID matches between two tables.

Three table join in sql

I'm trying to join three tables.
Tables:
HumanResources.Employees: Employee_ID(Primary Key), First_Name, Title -- also known as Employee_Title,
ProjectDetails.TimeCards: Employee_ID(Foreignkey), Project_ID (Foreign Key)
ProjectDetails.Projects: Project_Name, Project_ID(Primary Key)
I tried joining them using a temporary table.
select b.First_Name, b.Title, c.Project_ID from HumanResources.Employees b -- select statement
inner join ProjectDetails.TimeCards c on b.Employee_ID = c.Employee_ID -- first join seems to be the only one working.
inner join (select d.Project_Name as Project_Name, Project_ID from ProjectDetails.Projects d) as d on d.Project_ID=c.Project_ID -- second join doesn't seem to work.
The use of the subquery is redundunt at best, and also the common alias of "d" may be a source of error.
Just do:
select b.First_Name, b.Title, c.Project_ID
from HumanResources.Employees b
inner join ProjectDetails.TimeCards c on b.Employee_ID = c.Employee_ID
inner join ProjectDetails.Projects d on d.Project_ID=c.Project_ID
In the inner query for Project_ID use column alias name and then join on the alias column name.also try to have a different alias name for the sub query.
I don't see the benefit of using a subquery in your query. Could you try the below query?
Make sure in your table Projects has matching Project_ID otherwise of course nothing would come up.
SELECT b.First_Name
,b.Title
,c.Project_ID
FROM HumanResources.Employees b
INNER JOIN ProjectDetails.TimeCards c ON b.Employee_ID = c.Employee_ID
INNER JOIN ProjectDetails.Projects d ON d.Project_ID = c.Project_ID

SQL Server Circular Query

I have 4 tables, in that I want to fetch records from all 4 and aggregate the values
I have these tables
I am expecting this output
but getting this output as a Cartesian product
It is multiplying the expenses and allocation
Here is my query
select
a.NAME, b.P_NAME,
sum(a.DURATION) DURATION,
sum(b.[EXP]) EXPEN
from
(select
e.ID, a.P_ID, e.NAME, a.DURATION DURATION
from
EMPLOYEE e
inner join
ALLOCATION a ON e.ID = a.E_ID) a
inner join
(select
p.P_ID, e.E_ID, p.P_NAME, e.amt [EXP]
from
PROJECT p
inner join
EXPENSES e ON p.P_ID = e.P_ID) b ON a.ID = b.E_ID
and a.P_ID = b.P_ID
group by
a.NAME, b.P_NAME
Can anyone suggest something about this.
The following should work:
SELECT e.Name,p.Name,COALESCE(d.Duration,0),COALESCE(exp.Expen,0)
FROM
Employee e
CROSS JOIN
Project p
LEFT JOIN
(SELECT E_ID,P_ID,SUM(Duration) as Duration FROM Allocation
GROUP BY E_ID,P_ID) d
ON
e.E_ID = d.E_ID and
p.P_ID = d.P_ID
LEFT JOIN
(SELECT E_ID,P_ID,SUM(AMT) as Expen FROM Expenses
GROUP BY E_ID,P_ID) exp
ON
e.E_ID = exp.E_ID and
p.P_ID = exp.P_ID
WHERE
d.E_ID is not null or
exp.E_ID is not null
I've tried to write a query that will produce results where e.g. there are rows in Expenses but no rows in Allocations (or vice versa) for some particular E_ID,P_ID combination.
Use left join in select query by passing common id for all table
Hi I got the answer what I want from some modification in the query
The above query is also working like a charm and have done some modification to the original query and got the answer
Just have to group by the inner queries and then join the queries it will then not showing Cartesian product
Here is the updated one
select a.NAME,b.P_NAME,sum(a.DURATION) DURATION,sum(b.[EXP]) EXPEN from
(select e.ID,a.P_ID, e.NAME,sum(a.DURATION) DURATION from EMPLOYEE e inner join ALLOCATION a
ON e.ID=a.E_ID group by e.ID,e.NAME,a.P_ID) a
inner join
(select p.P_ID,e.E_ID, p.P_NAME,sum(e.amt) [EXP] from PROJECT p inner join EXPENSES e
ON p.P_ID=e.P_ID group by p.P_ID,p.P_NAME,e.E_ID) b
ON a.ID=b.e_ID and a.P_ID=b.P_ID group by a.NAME,b.P_NAME
Showing the correct output

How to write a Sql query to finds all participating rows in another table?

There are 3 tables: events, eventClients and clients.
Write a query that finds events that all clients have access to?
Inner join doesn't guarantee that all rows in a table participate so this doesn't help:
select * from events e
inner join eventclients ec on e.id = ec.eventid
inner join clients c on etc.clientid = c.id
You can use a nested NOT EXISTS to check this:
SELECT e.*
FROM events e
WHERE NOT EXISTS(
SELECT 1 FROM client c
WHERE NOT EXISTS(
SELECT 1 FROM eventclients ec
WHERE ec.eventid = e.id AND c.id= ec.clientid
)
)
Demo
You can also do
SELECT e.id, e.name
FROM events e LEFT JOIN eventclients ec
ON e.id = ec.eventid LEFT JOIN clients c
ON ec.clientid = c.id
GROUP BY e.id, e.name
HAVING COUNT(ec.clientid) =
(
SELECT COUNT(*) FROM clients
)
Here is SQLFiddle demo
Assuming that you mean event has a many-to-many relationship with client and event_client is the bridge table between them, then you should any of the many other questions asking about a SQL join across a many-to-many relationship.
SQL many to many select
How to filter SQL results in a has-many-through relation

Query extensibility with WHERE EXISTS with a large table

The following query is designed to find the number of people who went to a hospital, the total number of people who went to a hospital and the divide those two to find a percentage. The table Claims is two million plus rows and does have the correct non-clustered index of patientid, admissiondate, and dischargdate. The query runs quickly enough but I'm interested in how I could make it more usable. I would like to be able to add another code in the line where (hcpcs.hcpcs ='97001') and have the change in percentRehabNotHomeHealth be relfected in another column. Is there possible without writing a big, fat join statement where I join the results of the two queries together? I know that by adding the extra column the math won't look right, but I'm not worried about that at the moment. desired sample output: http://imgur.com/BCLrd
database schema
select h.hospitalname
,count(*) as visitCounts
,hospitalcounts
,round(count(*)/cast(hospitalcounts as float) *100,2) as percentRehabNotHomeHealth
from Patient p
inner join statecounties as sc on sc.countycode = p.countycode
and sc.statecode = p.statecode
inner join hospitals as h on h.npi=p.hospitalnpi
inner join
--this join adds the hospitalCounts column
(
select h.hospitalname, count(*) as hospitalCounts
from hospitals as h
inner join patient as p on p.hospitalnpi=h.npi
where p.statecode='21' and h.statecode='21'
group by h.hospitalname
) as t on t.hospitalname=h.hospitalname
--this where exists clause gives the visitCounts column
where h.stateCode='21' and p.statecode='21'
and exists
(
select distinct p2.patientid
from Patient as p2
inner join Claims as c on c.patientid = p2.patientid
and c.admissiondate = p2.admissiondate
and c.dischargedate = p2.dischargedate
inner join hcpcs on hcpcs.hcpcs=c.hcpcs
inner join hospitals as h on h.npi=p2.hospitalnpi
where (hcpcs.hcpcs ='97001' or hcpcs.hcpcs='9339' or hcpcs.hcpcs='97002')
and p2.patientid=p.patientid
)
and hospitalcounts > 10
group by h.hospitalname, t.hospitalcounts
having count(*)>10
You might look into CTE (Common Table Expressions) to get what you need. It would allow you to get summarized data and join that back to the detail on a common key. As an example I modified your join on the subquery to be a CTE.
;with hospitalCounts as (
select h.hospitalname, count(*) as hospitalCounts
from hospitals as h
inner join patient as p on p.hospitalnpi=h.npi
where p.statecode='21' and h.statecode='21'
group by h.hospitalname
)
select h.hospitalname
,count(*) as visitCounts
,hospitalcounts
,round(count(*)/cast(hospitalcounts as float) *100,2) as percentRehabNotHomeHealth
from Patient p
inner join statecounties as sc on sc.countycode = p.countycode
and sc.statecode = p.statecode
inner join hospitals as h on h.npi=p.hospitalnpi
inner join hospitalCounts on t.hospitalname=h.hospitalname
--this where exists clause gives the visitCounts column
where h.stateCode='21' and p.statecode='21'
and exists
(
select p2.patientid
from Patient as p2
inner join Claims as c on c.patientid = p2.patientid
and c.admissiondate = p2.admissiondate
and c.dischargedate = p2.dischargedate
inner join hcpcs on hcpcs.hcpcs=c.hcpcs
inner join hospitals as h on h.npi=p2.hospitalnpi
where (hcpcs.hcpcs ='97001' or hcpcs.hcpcs='9339' or hcpcs.hcpcs='97002')
and p2.patientid=p.patientid
)
and hospitalcounts > 10
group by h.hospitalname, t.hospitalcounts
having count(*)>10