How to use cross join twice SQL - sql

Table1:
ID
Name
Class
1
Paul
1st
Table2:
ID
Name
Class
Date
Intime
INAM
1
Paul
1st
06-12-2022
8:30AM
P
Table3:
ID
Name
Class
Date
Outtime
OUTPM
1
Paul
1st
06-12-2022
4:30PM
P
Table4:
ID
Name
Class
Date
Intime
Outtime
INAM
OUTPM
ID
Paul
1st
06-12-2022
8:30AM
4:30PM
P
P
I have two tables('Table2','Table3') I'm trying to join these two tables and insert into Table4 using Table1.
I have tried:
INSERT INTO table4
SELECT DISTINCT
COALESCE(tt.ID, t1.ID) AS ID,
COALESCE(tt.Name, t1.Name) AS Name,
COALESCE(tt.Class, t1.Class) AS Class,
tt.Date, tt.Intime, tt.Outtime, tt.INAM, tt.OUTPM
FROM
table1 AS t1
CROSS JOIN
(SELECT * FROM Table4
UNION ALL
SELECT ID, Name, Class, Indate AS Date, Intime, NULL, INAM, NULL
FROM Table2) AS tt
CROSS JOIN
(SELECT * FROM Table4
UNION ALL
SELECT ID, Name, Class, Outdate AS Date, NULL, Outtime, NULL, OUTPM
FROM Table3) AS tt
SELECT * FROM Table4
Please someone help me two join Table2 and Table3 and insert into Table4 using Table1. Thank you...

Try this code
I start by create tables for your testdata
USE [tempdb]
IF OBJECT_ID('table1') IS NOT NULL DROP TABLE table1
CREATE TABLE table1 (ID int, Name varchar(50), Class varchar(20))
INSERT INTO table1 VALUES (1, 'Paul', '1st')
IF OBJECT_ID('table2') IS NOT NULL DROP TABLE table2
CREATE TABLE table2 (ID int, Name varchar(50), Class varchar(20), Date date, Intime time, INAM varchar(20))
INSERT INTO table2 VALUES (1, 'Paul', '1st', '2022-12-06', '8:30AM', 'P')
IF OBJECT_ID('table3') IS NOT NULL DROP TABLE table3
CREATE TABLE table3 (ID int, Name varchar(50), Class varchar(20), Date date, Outtime time, OUTPM varchar(20))
INSERT INTO table3 VALUES (1, 'Paul', '1st', '2022-12-06', '4:30PM', 'P')
IF OBJECT_ID('table4') IS NOT NULL DROP TABLE table4
CREATE TABLE Table4 (ID int, Name varchar(50), Class varchar(20), Date date, Intime time, Outtime time, INAM varchar(20), OUTPM varchar(20))
SELECT * FROM table1
SELECT * FROM table2
SELECT * FROM table3
INSERT INTO table4
SELECT t1.[ID], t1.[Name], t1.[Class], t2.[Date], t2.[Intime], NULL, t2.[INAM], NULL FROM table2 AS t2 JOIN table1 AS t1 ON t1.[ID] = t2.[ID]
UNION ALL
SELECT t1.[ID], t1.[Name], t1.[Class], t2.[Date], NULL, t2.[Outtime] , NULL, t2.[OUTPM] FROM table3 AS t2 JOIN table1 AS t1 ON t1.[ID] = t2.[ID]
SELECT * FROM table4

You almost certainly do not want a CROSS JOIN, you want an INNER JOIN. A CROSS JOIN gives you the Cartesian product, which is every possible combination of the rows. An INNER JOIN gives you the matching records.
Assuming that ID is a primary key in Table2 and Table3, then something like this:
INSERT INTO Table4 ([ID], [Name], [Class], [Date], [Intime], [Outtime], [INAM], [OUTPM])
SELECT t2.[ID], y2.[Name], t2.[Class], t2.[Date], t2.[Intime], t3.[Outtime], t2.[INAM], t3.[OUTPM]
FROM Table2 AS t2
INNER JOIN Table3 AS t3 ON t2.ID = t3.ID;
Your sample data is very limited, but what is shown is an INNER JOIN.

Related

How to 1st table distinct and sum and join 2nd table, which if not match between T1 and T2 then add new row

How to join 1st table distinct and sum and join 2nd table, which if not match between T1 and T2 then add new row
Result i need
Period in result table is Getdate()
Select distinct(y.Emp_ID),x.MealAllowance_OT from [dbo].[SPCM_TX_MonthlyAllowance] y left join
(Select x.Emp_Id,x.MealAllowance_OT from [dbo].[SPCM_Cal_OTLog] x
group by x.Emp_Id,x.MealAllowance_OT) x
on x.Emp_Id = y.Emp_ID
order by x.MealAllowance_OT desc
You have to use a subquery on T2 to get sums by group. Then you outer join with T1 to include non-matching rows.
I guessed at the math and the defaults. Like why is Pay/MealAllowance presumed to be 400 when there isn't an entry in T1.
declare #T1 table (Emp_Id int, TRA varchar(3), Pay int)
declare #T2 table (Emp_Id int, DayTy varchar(3), MealAllowance int)
insert into #T1
values (1,'DL',400),(2,'IDL',400),(5,'IDL',400)
insert into #T2
values (1,'DL',18),(2,'IDL',136),(2,'IDL',136),(4,'IDL',136)
select isnull(T1.Emp_Id,T2.Emp_Id) Emp_Id,isnull(T1.TRA,T2.DayTy) DayTY
,isnull(Pay,400) MealAllowance_Mont, isnull(MealAllowance,0) MealAllowance
,isnull(Pay,400) + isnull(MealAllowance,0) Tot, getdate() period
from #T1 T1
full outer join
(
select Emp_Id, DayTy,sum(MealAllowance) MealAllowance
from #T2
group by Emp_Id, DayTy
) T2
on T1.Emp_Id = T2.Emp_Id
and T1.TRA = T2.DayTy

sql for breaking one record into 2 records

I have 2 tables with data as below-
table 1-
id name id_start_date
---------------------
345 Fiamma 1/01/1900
Table 2-
Change_Date Old_id New_id Users
-------------------------------
15/06/2017 123 345 abc#xyz.com
I'm looking for data as below-
id product_name start_date end_date
-----------------------------------
123 Fiamma 1/01/1900 15/06/2017
345 Fiamma 15/06/2017 31/12/2099
Basically I want to break the table 2 data into 2 records one with old id and the start and end dates for that id and the other with the new id with start and end dates.
Cheers
select t2.old_id as id, t1.name as product_name, t1.start_date, t2.change_date as end_date
from table1 t1
INNER JOIN table2 t2 ON t1.id = t2.new_id
UNION
select t1.id as id, t1.name as product_name, t2.change_date, "" as end_date
from table1 t1
INNER JOIN table2 t2 ON t1.id = t2.new_id
here is a test that you can run :
create table #table1
(
id int,
name varchar(50),
start_date datetime
)
GO
create table #table2
(
change_date datetime,
Old_id int,
New_id int,
users varchar(50)
)
GO
insert into #table1
values (345,'Fiamma','01/01/1900')
insert into #table2
values ('15/06/2017',123,345,'abc#xyz.com')
select * from #table1
select * from #table2
select t2.old_id as id, t1.name as product_name, t1.start_date as start_date, t2.change_date as end_date
from #table1 t1
INNER JOIN #table2 t2 ON t1.id = t2.new_id
UNION
select t1.id as id, t1.name as product_name, t2.change_date as start_date , DATEADD(YEAR,+10,GETDATE()) as end_date
from #table1 t1
INNER JOIN #table2 t2 ON t1.id = t2.new_id
drop table #table1
drop table #table2

SQL. Joining records from 3 or more tables based on dates

My tables look like this(just an example):
table1:
TIME |data1
1.01.2018|aaa
2.01.2018|bbb
table2:
TIME |data2
1.01.2018|abcd
2.01.2018|cd
table3:
TIME |data3
1.01.2018|
2.01.2018|d
Now what i would like to do is take the data from table2 and put it in the table1 where there are missing records. If there is no record in all tables for that date, then the data in data column is NULL. The data copied to table1 needs to be the same date as in the table2. and if there is no same date in table1 as it is in table2, that date is created.
So far i have tried with this code, but the data copied is not valid. If there is a missing day in some of the tables, that missing day is created in time column, but the data in data column is incorect.
SELECT DISTINCT table1.time,table1.data,table2.time,table2.data,table3.time,table3.data
FROM table1
LEFT JOIN table2 ON table1.time=table2.time
LEFT JOIN table3 ON table1.time=table3.time
EDIT
This is how the output should look like:
For example, there was no data in table3 for data3 for that specific date, so the cell is empty.
TIME |data1|data2|data3|
1.01.2018|aaa |abcd | |
2.01.2018|bbb | cd | d |
You need a full join instead of a left join. (you didn't specify the backend. Here the sample is with MS SQL) ie:
SELECT
coalesce(table1."time",table2."time", table3."time") as "time",
table1.data1,table2.data2,table3.data3
FROM table1
full JOIN table2 ON table1."time"=table2."time"
full JOIN table3 ON table1."time"=table3."time" ;
Output:
Time data1 data2 data3
1.01.2018 aaa abcd (null)
2.01.2018 bbb cd d
EDIT: The distinct in your code suggests you want only one row per day. Then it is not clear which column value should be used. Assuming any would do, you can do aggregation like this:
SELECT
coalesce(table1."time",table2."time", table3."time") as "time",
max(table1.data1) as data1,
max(table2.data2) as data2,
max(table3.data3) as data3
FROM table1
full JOIN table2 ON table1."time"=table2."time"
full JOIN table3 ON table1."time"=table3."time"
group by coalesce(table1."time",table2."time", table3."time");
Start the process with
SELECT [DISTINCT] TIME FROM TABLE1
UNION [DISTINCT]
SELECT [DISTINCT] TIME FROM TABLE2
UNION [DISTINCT]
SELECT [DISTINCT] TIME FROM TABLE3
And then LEFT JOIN the three tables to that.
Try this:
with cte as (Select time from table1 union Select time from table2 union Select time from table3)
SELECT cte.time,table1.data as data1,table2.data as data2,table3.data as data3
FROM cte
LEFT JOIN table1 ON table1.time=cte.time
LEFT JOIN table2 ON cte.time=table2.time
LEFT JOIN table3 ON cte.time=table3.time
Apply simple left join after union on.
DECLARE #t1 table
(
TIMEDate1 DATE
,Data1 VARCHAR(50)
)
DECLARE #t2 table
(
TIMEDate2 DATE
,Data2 VARCHAR(50)
)
DECLARE #t3 table
(
TIMEDate3 DATE
,Data3 VARCHAR(50)
)
insert #t1 (TIMEDate1,Data1 ) select getdate(),'aaa'
insert #t1 (TIMEDate1,Data1 ) select getdate()+1,'bbb'
insert #t2 (TIMEDate2,Data2 ) select getdate(),'abcd'
insert #t2 (TIMEDate2,Data2 ) select getdate()+1,'cd'
insert #t3 (TIMEDate3,Data3 ) select getdate(),''
insert #t3 (TIMEDate3,Data3 ) select getdate()+1,'d'
SELECT t.TIMEDate,t1.Data1,t2.Data2,t3.Data3
FROM (
SELECT distinct TIMEDate1 as TIMEDate FROM #t1
UNION
SELECT distinct TIMEDate2 as TIMEDate FROM #t2
UNION
SELECT distinct TIMEDate3 as TIMEDate FROM #t3
) t
left JOIN #t1 t1 ON t1.TIMEDate1 = t.TIMEDate
left JOIN #t2 t2 ON t2.TIMEDate2 = t.TIMEDate
left JOIN #t3 t3 ON t3.TIMEDate3 = t.TIMEDate
--order by t1.TIMEDate1 asc
The SQL below is just an alternative for inserting the missing dates into Table1.
--
-- insert those into Table1 that are in Table2 but not in Table1
--
insert into Table1 ("time", data1)
select "time", data2
from Table2 as t2
where not exists
(
select 1
from Table1 as t1
where t1."time" = t2."time"
);
--
-- insert those into Table1 that are in Table3 but not in Table1
--
insert into Table1 ("time", data1)
select "time", data3
from Table3 as t3
where not exists
(
select 1
from Table1 as t1
where t1."time" = t3."time"
);
Then add the dates that are still missing in Table1 after all that.
Below is an example for MS SQL Server :
;with RCTE_DATERANGE as
(
select min([time]) as dt, max([time]) as max_dt
from Table1
union all
select dateadd(day, 1, dt), max_dt
from RCTE_DATERANGE where dt < max_dt
)
insert into Table1 ([time])
select dt
from RCTE_DATERANGE AS rcte
where not exists
(
select 1
from Table1 as t1
where t1.[time] = rcte.dt
);
-- Just checking
;with RCTE_DATERANGE as
(
select min([time]) as dt, max([time]) as max_dt
from Table1
union all
select dateadd(day, 1, dt), max_dt
from RCTE_DATERANGE where dt < max_dt
)
select rcte.dt, t1.[time] as time1, t2.[time] as time2, t3.[time] as [time3], t1.data1, t2.data2, t3.data3
from RCTE_DATERANGE AS rcte
full join Table1 t1 on t1.[time] = rcte.dt
full join Table2 t2 on t2.[time] = rcte.dt
full join Table3 t3 on t3.[time] = rcte.dt;

T-SQL Group Check

I have three tables - Table_1, Table_2 and Table_3. Here's what each looks like:
Table_1
ID | TicketID | Rule
---------------------------
1 | 101 | NULL
Table_2
TicketID | Location
---------------------------
101 | A
101 | B
Table_3
Location | Rule
--------------------
A | R1
B | R1
A | R2
B | R2
C | R2
My goal is to populate the Rule column in Table_1 (which should be a select distinct of the Rule column in Table_3). The process should be:
Take the TicketID from Table_1. Join Table_1 to Table_2 on TicketID and get the Locations associated with that ticket.
Look up Table_3 and check what Rule needs to be applied. The check needs to be at the group level. For instance, in this example, Ticket 101 has locations A,B. Table_3 has A,B against Rule R1 but also has A,B,C against Rule R2. The correct rule should be R1 as Ticket 101 has no allocation for location C. Hope this make sense. What would be the easiest way of achieving this? Thanks in advance!
Please try the below code. Its working fine in SQL server 2012.
DECLARE #table_1 TABLE
(ID int, TicketID int, [Rule] Varchar(10))
DECLARE #table_2 TABLE
(TicketID int, Location Varchar(10))
DECLARE #table_3 TABLE
(Location Varchar(10),[Rule] Varchar(10))
INSERT #table_1
(ID,TicketID,[Rule])
VALUES
(1,101,NULL)
INSERT #table_2
(TicketID,Location)
VALUES
(101,'A'),
(101,'B')
INSERT #table_3
(Location,[Rule])
VALUES
('A','R1'),
('B','R1'),
('A','R2'),
('B','R2'),
('C','R2')
SELECT DISTINCT [RULE] FROM #table_3 t3 WHERE t3.Location IN
(SELECT t2.Location FROM #table_2 t2 INNER JOIN #table_1 t1 ON t1.TicketID = t2.TicketID)
AND [RULE] NOT IN
(SELECT t.[RULE] FROM #table_3 t WHERE t.Location NOT IN
(SELECT t2.Location FROM #table_2 t2 INNER JOIN #table_1 t1 ON t1.TicketID = t2.TicketID))
TRY THIS..
SELECT t1.TicketID
,t2.[Rule]
FROM (SELECT DISTINCT t2.TicketID,[Rule]
FROM #table_3 t3 INNER JOIN
#table_2 t2 ON t2.Location = t3.Location) t2
INNER JOIN #table_1 t1 ON t2.TicketID = t1.TicketID
Use this select statement with the above declared table variable
--http://stackoverflow.com/questions/37344006/t-sql-group-check
set nocount on
drop table #temp
DECLARE #table_1 TABLE
(ID int, TicketID int, [Rule] Varchar(10))
DECLARE #table_2 TABLE
(TicketID int, Location Varchar(10),obs int)
DECLARE #table_3 TABLE
(Location Varchar(10),[Rule] Varchar(10), obs int)
INSERT #table_1
(ID,TicketID,[Rule])
VALUES
(1,101,NULL)
INSERT #table_2
(TicketID,Location)
VALUES
(101,'A'),
(101,'B'),
--(101,'C')
(102,'A'),
(102,'B'),
(102,'C'),
(102,'S')
INSERT #table_3
(Location,[Rule])
VALUES
('A','R1'),
('B','R1'),
('A','R2'),
('B','R2'),
('C','R2'),
('S','R2')
declare #table_4 table (src varchar(2), id varchar(3), obs int)
insert into #table_4
select 't2', [ticketid], count(*) from #table_2 group by [ticketid]
Insert into #table_4
select 't3',[rule], count(*) from #table_3 group by [rule]
update #table_2
set obs = t4.obs
from #table_2 t2
join #table_4 t4 on t4.id = t2.ticketid
where t4.src = 't2'
update #table_3
set obs = t4.obs
from #table_3 t3
join #table_4 t4 on rtrim(t4.id) = rtrim(t3.[rule])
where t4.src = 't3'
select t2.ticketid,t2.location as t2location,t2.obs as t2obs,t3.location as t3location,t3.[Rule],t3.obs as t3obs
into #temp
from #table_2 t2
full join #table_3 t3 on t3.location = t2.location
delete #temp
where [rule] in (select [rule] from #temp where ticketid is null)
--select t.*
--from #temp t
select distinct ticketid,[rule]
from #temp
where t2location = t3location and t2obs = t3obs
Try this code :
SELECT DISTINCT [RULE] FROM Table_3 t3 WHERE t3.Location IN
(SELECT t2.Location FROM Table_2 t2 INNER JOIN Table_1 t1 ON t1.TicketID = t2.TicketID)
AND [RULE] NOT IN
(SELECT t.[RULE] FROM Table_3 t WHERE t.Location NOT IN
(SELECT t2.Location FROM Table_2 t2 INNER JOIN Table_1 t1 ON t1.TicketID = t2.TicketID))

Join 3 tables based on Partition by or Self join

I have following tables
tbl1 (empID, Name, ctNo)
tbl2 (salID, empID, salry)
tbl3 (histryID, salDate, empID, salID)
Expect Output (empID,Name,salary,Salary_Date)
For Salary date, I only want the last salary_date to be displayed.
(maybe By using Partitiion by or Selfjoin methods.)
Thank You.
Below query can answer your question
Create table #tbl1 (empID int , Name varchar(11), ctNo int)
Create table #tbl2 (salID int, empID int, salry int)
Create table #tbl3 (histryID int, salDate DATE, empID int, salID int)
INSERT INTO #tbl1
values(1,'Dinesh',23),(2,'Raj',11)
INSERT INTO #tbl2
values(1,1,1000),(2,1,2000),(3,2,100),(4,2,500)
INSERT INTO #tbl3
values(1,'20020101',1,1),(2,'20020201',1,2),(3,'20020101',2,3),(4,'20020201',2,4)
SELECT M1.* FROM(
SELECT T1.empID,T1.Name,T2.salry,T3.salDate FROM
#tbl1 AS T1
INNER join #tbl2 AS T2
ON T1.empID=T2.empID
INNER join #tbl3 AS T3
ON T1.empID=T3.empID AND T2.salID =T3.salID
) AS M1
INNER JOIN
(
SELECT empID,MAX(salDate) AS SALDATE FROM #tbl3 GROUP BY empID) AS M2
ON M1.SALDATE=M2.salDate AND M1.empID=M2.empID
You could try something like this:
select t1.empID, t1.Name, t2.salry as salary, top (t3.salDate) as Salary_Date from tbl1 t1, tbl2 t2, tbl3 t3 on t1.empID=t2.empID and t1.empID=t3.empID
Note: Pointing in correct direction. Not tested.
You can do this with row_number window function:
select t1.empid, t1.name, t3.saldate, t2.salary
from tbl1 t1
join(select *, row_number() over(partition by empid order by saldate desc) rn
from tbl3)t3 on t1.empid = t3.empid and t3.rn = 1
join tbl2 t2 on t3.empid = t2.empid AND t3.salid = t2.salid