I tried the below query to display data
select e.Name,ic.Code,t1.pyear,t1.pmonth,t2.Amount
from t1
inner join t2 on t2.id=t1.id
inner join t3 on t3.Code=t2.Code
inner join t4 e on t4.employeeindex=t1.employeeindex
where t1.pyear=2016 and t1.pmonth=1
union all
select e.Name,ic.Code,t1.pyear,t1.pmonth,t2.Amount
from t1
inner join t2 on t2.id=t1.id
inner join t3 on t3.Code=t2.Code
inner join t4 e on t4.employeeindex=t1.employeeindex
where t1.pyear=2016 and t1.pmonth=2
and the data i am getting is like this-
scode amount month year e_name
abc 3847 1 2016 john
ABC 20938 2 2016 john
XYZ 2838 1 2016 david
XYZ 29384 2 2016 david
now i want to display data like this
s_code amount1 amount2 month1 month2 year e_name
abc 3847 20938 1 2 2016 john
xyz 2838 29384 1 2 2016 david
any solution ?
edit
You could try to use cte. The following is just an example, adjust the column names by yourself because it's a bit of a mess
WITH unionall AS (
select ic.Code, t2.Amount, t1.pmonth, t1.pyear, e.Name
from t1
inner join t2 on t2.id=t1.id
inner join t3 on t3.Code=t2.Code
inner join t4 e on t4.employeeindex=t1.employeeindex
where t1.pyear=2016 and (t1.pmonth=1 OR t2.pmonth=2)
)
SELECT r1.scode, r1.amount as amount1, r2.amount as amount2
FROM unionall r1 inner join unionall r2 on r1.scode = r2.scode
-----------------------
If you know for sure that for each s_code there are 2 months (or at least a costant number) you could easily make a join on itself and select all the values with an alias, like so:
SELECT r1.scode, r1.amount as amount1, r2.amount as amount2 [...more fields...]
FROM result r1 inner join result r2 on r1.scode = r2.scode [...many joins as many months...]
If there can be multiple month that you don't know, i would probably do what on mysql is a group_concat. Basically, you group by scode and then, in the same field, there's a list separated values. Too bad you can't do a group_concat in SQLServer, but there are workaround guides around the web
How to make a query with group_concat in sql server
Related
I have 2 below tables called T1 and T2
T1 having data as follows
DateList
2021-11-06
2021-11-07
2021-11-08
2021-11-09
T2 having data as follows
EmpId ApplyDate
1 2021-11-07
1 2021-11-09
2 2021-11-09
Now i need t-sql statement that will give date which is not there in T2 for each EmpId.
Output should look as below
DateList EmpId
2021-11-06 1
2021-11-08 1
2021-11-06 2
2021-11-07 2
2021-11-08 2
We can use a cross join between the two tables to generate a reference table containing all date/employee pairs. Then, left anti-join this table to T2 to find all pairs which are not present.
SELECT d.DateList, e.EmpId
FROM T1 d
CROSS JOIN (SELECT DISTINCT EmpId FROM T2) e
LEFT JOIN T2
ON T2.DateList = d.DateList AND
T2.EmpId = e.EmpId
WHERE
T2.DateList IS NULL
ORDER BY
d.DateList,
e.EmpId;
How can I return values in a where clause for something like this:
Get me all the records that exist in table1.de1,table2.de2,table3.de3,table4.de3
select *
from table1
inner join table2
on table2.carID = table1.carID
inner join table3
on table3.carID = table1.carID
inner join table4
on table4.driverID = table1.driverID
where a recietrecord exists in table2 and its paydate has passed 20 days ago, comparing it to TODAYS date and show those days in a field called Days Passed From The Day Driver Was Suppose To Pay
At first, please, use table aliases. This solution is for SQL Server:
As was written in comments you can use DATEDIFF function to compare paydate to GETDATE.
select *,
DATEDIFF(day,t2.paydate,GETDATE()) as [Days Passed From The Day Driver Was Suppose To Pay]
from table1 t1
inner join table2 t2
on t2.carID = t1.carID
inner join table3 t3
on t3.carID = t1.carID
inner join table4 t4
on t4.driverID = t1.driverID
WHERE DATEDIFF(day,t2.paydate,GETDATE()) > 20
Or better use minutes:
DATEDIFF(minute,t2.paydate,GETDATE()) > 28800 --60 minutes * 24 hours * 20 days
I have two tables:
Teams
Id Name
1 Manchester
2 Arsenal
3 Inter
4 Milan
Games
GameId FirstTeamId GoalsFirstTeam GoalsSecondTeam SecondTeamId
1 1 0 0 2
2 3 2 3 4
3 1 1 1 3
I want to update into GameResult with a select and join from two tables Games and Teams like this:
GameId FirstTeam GoalsFT GoalsST SecondTeam
1 Manchester 0 0 Arsenal
2 Inter 2 3 Milan
3 Manchester 1 1 Inter
I tried this:
UPDATE GameResult
SET GameId = (SELECT GameId
FROM Games),
FirstTeam = (SELECT t1.Name AS FirstTeam
FROM Games AS g
INNER JOIN Teams t1
ON g.FirstTeamId = t1.Id),
GoalsFT = (SELECT GoalsFirstTeam
FROM Games),
GoalsST = (SELECT GoalsSecondTeam
FROM Games),
SecondTeam = (SELECT t2.Name AS SecondTeam
FROM Games AS g
INNER JOIN Teams t2
ON g.SecondTeamId = t2.Id)
...but it didn't work.
Can somebody help me with this ?
try this
UPDATE GameResult
SET GameId = G.GameId,
FirstTeam = T1.Name,
GoalsFT = G.GoalsFirstTeam,
GoalsST = G.GoalsSecondTeam,
SecondTeam = T2.Name
FROM Games G INNER JOIN Teams T1 ON G.FirstTeamID=T1.ID
INNER JOIN Teams T2 ON G.SecondTeamId=T2.ID
UPDATE:
if you want just to insert new records into GameResult from the 2 other tables, try this
INSERT GameResult (GameId, FirstTeam, GoalsFT, GoalsST, SecondTeam)
SELECT G.GameId, T1.Name, G.GoalsFirstTeam, G.GoalsSecondTeam, T2.Name
FROM Games G INNER JOIN Teams T1 ON G.FirstTeamID=T1.ID
INNER JOIN Teams T2 ON G.SecondTeamId=T2.ID
It seems that your table 'GameResult' hasn't got any records to update. Either fill it first and then use the abovementioned solution by Pupa Rebbe, or use a Merge statement to insert, update and (if needed) delete records.
For more information, see this MS library
Simple solution:
Delete From GameResult
Go
Insert GameResult (GameId,
FirstTeam,GoalsFT, GoalsST, SecondTeam)
SELECT g.GameId,
t1.Name AS FirstTeam,
g.GoalsFirstTeam, g.GoalsSecondTeam,
t2.Name AS SecondTeam
FROM Game g
INNER JOIN Team t1 ON g.FirstTeamId = t1.Id
INNER JOIN Team t2 ON g.SecondTeamId = t2.Id
I am trying to join 2 or more tables on MS SQL Server. All the tables have IsActive field which determines the active record. (IsActive = 1 means active record and IsActive = 0 means inactive record or record has been deleted from system)
So I have two conditions for joining the two or more tables.
On The first query,I filter the IsActive on the join clause
select * from table_A a
inner join table_B b
on a.ID = b.ID and b.IsActive = 1
inner join table_C c
on b.ID = c.ID and c.IsActive = 1
where a.IsActive = 1
On The second query, I also can filter IsActive on the where Clause
select * from table_A a
inner join table_B b
on a.ID = b.ID
inner join table_C c
on b.ID = c.ID
where a.IsActive = 1 and b.IsActive = 1
and c.IsActive = 1
notes: The relation from table A to B is one to one but from table A to C is one to many and also all the table has clustered index on primary key ID and the ID is auto increment.
So which one do you think is better? (assume each table has approximately 100.000 records (80% active records and 20% inactive records))
Thanks
The difference is simple but takes a careful eye to spot.
Consider the following example:
create table tbl_client as
select 1 as client_id, 'aaa' as client_name, 'Y' is_active from dual
union all
select 2, 'bbbbb', 'N' from dual
union all
select 3, 'cc', 'Y' from dual;
create table tbl_transaction as
select 1 transaction_id, 1 client_id, 123.34 amount from dual
union all
select 2, 1, 4353.45 from dual
union all
select 3, 2, 251.48 from dual;
Now, on these tables run the followoing queries:
Inner Join:
In an inner join, there is no difference in the results of the following two queries:
select c.client_name, t.amount, t.is_paid
from tbl_client c
inner join tbl_transaction t
on c.client_id = t.client_id
and t.is_paid = 'Y'; -- filter on join
select c.client_name, t.amount, t.is_paid
from tbl_client c
inner join tbl_transaction t
on c.client_id = t.client_id
where t.is_paid = 'Y'; -- filter in where
Both their result is the same as:
CLIENT_NAME AMOUNT IS_PAID
----------- ---------- -------
aaa 123.34 Y
aaa 4353.45 Y
Left Outer Join
This is where the difference kicks in.
Consider the following query:
select c.client_name, t.amount, t.is_paid
from tbl_client c
left outer join tbl_transaction t
on c.client_id = t.client_id
and t.is_paid = 'Y'; -- << filter in join
Result:
CLIENT_NAME AMOUNT IS_PAID
----------- ---------- -------
aaa 123.34 Y
aaa 4353.45 Y
cc -- << Note that client cc's transaction record is not there
bbbbb -- << and this client also shows up
And when you apply filter on where in a left outer join:
select c.client_name, t.amount, t.is_paid
from tbl_client c
left outer join tbl_transaction t
on c.client_id = t.client_id
where t.is_paid = 'Y'; -- << filter in where
Result:
CLIENT_NAME AMOUNT IS_PAID
----------- ---------- -------
aaa 123.34 Y
aaa 4353.45 Y -- No row for bbbbb or cc clients, just like the inner join
Summary
In short, when you put a filter on the joining condition, the filter is applied to the table being joined. For example, in the first case in the left outer join section, the row for tbl_transaction didn't show up for the client bbbbb.
But when you put a filter in the where clause, it filters the entire data set that is retrieved after joining all the tables (logically. Internal technical operations differ across RDBMSes). This is why the rows for bbbbb and cc didn't show up in the last query.
Fiddle
EDIT
As #DanGuzmanSqlServerMvp has mentioned in his comment, for the example you have posted in your question, the SQL Server query optimizer should execute the same plan. However, if there was an outer join in your query, the plans would be different.
I have 2 tables in SQL Server 2008 and I want to get the details from those 2 tables using join.
T-1 : vwHardwareConsolidate
|ID|||Qty|Type|Task_Id|
T-2 :
|MasterID|Task_Id|Act_Qty|
I want to get id, task_name, sum(qty), task_id from T1 and Masterid, Act_Qty from T2
I have tried this query
select
ID as MasterID, Task_id, Task_Name as Items,
SUM(Qty) as Req_Qty, 0 as Act_Qty
from
vwHardwareConsolidate
where
type = 'Reqrd' and ID = '21'
Group by
Task_Name,id,Task_id
union
(select
m.MasterID, m.Task_Id, vw.Task_Name as Items, 0 as Req_Qty, m.Act_Qty
from
vwHardwareConsolidate vw
Right join
(select
MasterID, m.Task_Id, 0 as Req_Qty, sum(Act_qty) as Act_Qty
from
tbl_MaterialDistribution_Detail m
where
MasterID = '21'
group by
m.Task_Id, MasterID) as m on m.Task_Id = vw.Task_id)
vwHardwareConsolidate
ID Site_name Qty Task_Name Type
1 CITY 1 A16Port_Switch Reqrd
1 CITY 1 Digital_Camera Reqrd
1 CITY 1 Electronic_Pen Reqrd
tbl_MaterialDistribution_Detail:
MasterID|TaskId|Act_qty
7 31 1
2 32 1
12 39 3
Please try this
select t1.ID, t1.Task_Name,Sum(t1.Qty) as Qty,t1.Task_Id,t2.MasterID,t2.Act_Qty
from vwHardwareConsolidate as t1
left outer join table2 as t2
on t2.Task_ID=t1.Task_ID
Group By t1.ID, t1.Site_name, t1.Task_Name,t1.Qty,t1.Type,t1.Task_Id,t2.MasterID,t2.Act_Qty
May this will help you.
SQL Fiddle Demo
You can use
SELECT T1.Id, T1.SiteName,T1.TaskName,T.Type,T2.Act_Qty,T2.MasterID,T2.Task_Id,SUM(Qty)AS
Qty FROM T1 INNER JOIN T2 ON T1.Task_Id=T2=Task_Id GROUP BY T1.Id, T1.SiteName,
T1.TaskName,T.Type,T2.Act_Qty,T2.MasterID,T2.Task_Id
something this way,
select a.id,a.Task_Name,b.qty,c.Act_Qty from vwHardwareConsolidate a inner join
tbl_MaterialDistribution_Detail c on a.id=c.task_id
inner join
(slect id,sum(qty)qty from vwHardwareConsolidate group by id)b
on a.id=b.id