I am trying to display all records that table 1 contains, each record with all the records from table 2 :
Table 1
company adress
------------------
A AdressX
B AdressY
C AdressZ
Table 2
Product Price
----------------
P1 50
P2 60
Result :
company Product
----------------
A P1
A P2
B P1
B P2
C P1
C P2
That would be a cross join.
SELECT t1.company,
t2.product
FROM [table 1] t1
CROSS JOIN [table 2] t2
ORDER BY t1.company,
t2.product;
Using CROSS APPLY this exected output is possible:
SELECT T1.company, T2.Product
FROM Table1 T1
CROSS APPLY Table2 T2
ORDER BY T1.company, T2.Product
Demo on db<>fiddle
Demo with sample data:
DECLARE #Table1 TABLE (company VARCHAR (1), adress VARCHAR (10));
INSERT INTO #Table1 (company, adress) VALUES
('A', 'AdressX'),
('B', 'AdressY'),
('C', 'AdressZ');
DECLARE #Table2 TABLE (Product VARCHAR (2), Price INT);
INSERT INTO #Table2 (Product, Price) VALUES
('P1', 50),
('P2', 60);
SELECT T1.company, T2.Product
FROM #Table1 T1
CROSS APPLY #Table2 T2
ORDER BY T1.company, T2.Product
Output:
company Product
---------------
A P1
A P2
B P1
B P2
C P1
C P2
The following query will select all data from both tables (not linked or related).
SELECT *
FROM TABLE 1
OUTER APPLY
(
SELECT *
FROM Table 2
) AS Table 2
If there is a foreign key, you can use a LEFT JOIN (SELECT)
This is the Scenario : I have a duplicate rows in my table with the same Id , Name and so on .
1) I have to find the duplicate row matching all the criteria ( this is done)
2) Delete them only if the criteria match
3) Use the id of the deleted record and update the existing row in the table
For this i have created a 2 temp table. Temp1 is the table with all the record. Temp2 consist of duplicated row.
IF OBJECT_ID('tempdb..#Temp1') IS NOT NULL
DROP TABLE #Temp1
IF OBJECT_ID('tempdb..#Temp2') IS NOT NULL
DROP TABLE #Temp2
IF OBJECT_ID('tempdb..#Temp3') IS NOT NULL
DROP TABLE #Temp3
CREATE Table #Temp1 (
Id int,
Name NVARCHAR(64),
StudentNo INT NULL,
ClassCode NVARCHAR(8) NULL,
Section NVARCHAR(8) NULL,
)
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(1,'Joe',123,'A1', 'I')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(1,'Joe',123,'A1', 'I')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(2,'Harry',113,'X2', 'H')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(2,'Harry',113,'X2', 'H')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(3,'Elle',121,'J1', 'E1')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(3,'Elle',121,'J1', 'E')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(8,'Jane',191,'A1', 'E')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(5,'Silva',811,'S1', 'SE')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(6,'Juan',411,'S2', 'SE')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(7,'Carla',431,'S2', 'SE')
;WITH CTE AS (
select
ROW_NUMBER() over (partition by Id
, StudentNo
order by Id, StudentNo)as Duplicate_RowNumber
, * from #Temp1 )
select t1.Id,t1.Name,t1.StudentNo,t1.Section,t1.ClassCode
INTO #Temp2
from CTE as c INNER JOIN #Temp1 as t1 ON t1.Id = c.Id
and t1.StudentNo = t1.StudentNo
and c.Duplicate_RowNumber >1
-- this will have 6 rows all the duplicates are included
--select * from #Temp2
-- this is for output clause
DECLARE #inserted Table (Id int,
Name NVARCHAR(64),
StudentNo INT NULL,
ClassCode NVARCHAR(8) NULL,
Section NVARCHAR(8) NULL)
DELETE FROM #temp1
OUTPUT deleted.Id , deleted.Name ,deleted.StudentNo ,deleted.ClassCode ,deleted.Section into #inserted
WHERE EXISTS ( SELECT * FROM #Temp2 as t2
where #temp1.Id = t2.Id
and #temp1.Name = t2.Name
and #temp1.StudentNo = t2.StudentNo
and #temp1.ClassCode = t2.ClassCode
and #temp1.Section = t2.Section)
-- this is to check what is delete so that i can join it and update the table temp1
select * from #inserted
You can see below the query should not delete the last two highlighted column because the Section does not match. It should only delete matching criteria from Temp1 and Temp2.
Scenario 2 : Delete the duplicate record in Temp1 and use the key in order to update the data to NULL for Section and Classcode . This is what i expect with the highlighted to be NULLs .
You can run this query yourself - just copy and paste.
Yes, for scenario #1 it is going to delete the rows because the problem is in this section.
I added this table for references.
Added this #temp2 table to clarify for later use.
CREATE Table #Temp2 (
Id int,
Name Varchar(64),
StudentNo INT NULL,
ClassCode Varchar(8) NULL,
Section Varchar(8) NULL,
)
IF OBJECT_ID('tempdb..#tmp4') IS NOT NULL
DROP TABLE #tmp4
select t1.Id,t1.Name,t1.StudentNo,t1.Section,t1.ClassCode,
Duplicate_RowNumber
INTO #Duplicatedata
from CTE as c INNER JOIN #Temp1 as t1 ON t1.Id = c.Id
and t1.StudentNo = t1.StudentNo
and c.Duplicate_RowNumber >1
select * from #Duplicatedata
This is going to satisfy both condition as #temp 1 will have both rows for Elle as your join condition is only on ID and Student No.
I added row number column for clarity.
Id Name StudentNo Section ClassCode Duplicate_RowNumber
1 Joe 123 I A1 2
1 Joe 123 I A1 2
2 Harry 113 H X2 2
2 Harry 113 H X2 2
3 Elle 121 E1 J1 2
3 Elle 121 E J1 2
As your Partition is based by Student No and ID, every duplicate row will have 2 or more row numbers.
You can use this approach to delete.
select
ROW_NUMBER() over (partition by Id
, StudentNo
order by Id, StudentNo, section)as Duplicate_RowNumber
, * into #tmp4 from #Temp1
--You can add section in your order as well for consistency purpose.
delete
from #tmp4
output deleted.id, deleted.Name, deleted.StudentNo, deleted.ClassCode,
deleted.Section into #Temp2
where Duplicate_RowNumber > 1
After that it seems like you want to keep one row in your final table and put the other one in you deleted table. For Elle it will delete one of the rows from Final table and keep only one since your partition is not based on section.
To make sure that you delete 1 row from your final table you can use this.
DELETE t
OUTPUT deleted.Id , deleted.Name ,deleted.StudentNo ,deleted.ClassCode
,deleted.Section into #inserted FROM
(select *, row_number() over (Partition by tm.name, tm.studentNo Order by ID,
StudentNo, section ) rownum from #temp1 tm) t
join #Temp2 t2 on t.Id = t2.Id
and t.Name = t2.Name
and t.StudentNo = t2.StudentNo
and t.ClassCode = t2.ClassCode
and t.Section = t2.Section
where t.rownum > 1
If you notice I added this row number, so that it will not two delete the rows from final table, since Joe and Harry has all the matching attributes, and it will delete two rows.
select * from #inserted
Output you get:
Id Name StudentNo ClassCode Section
3 Elle 121 J1 E1
2 Harry 113 X2 H
1 Joe 123 A1 I
Finally you can update final table in this way. #Scenario 2
update TMP
SET ClassCode = NULL, SECTION = NULL
FROM
#Temp1 TMP
JOIN #INSERTED I ON TMP.Id = I.Id
AND TMP.StudentNo = I.StudentNo
SELECT * FROM #Temp1
Final Output:
Id Name StudentNo ClassCode Section
1 Joe 123 NULL NULL
2 Harry 113 NULL NULL
3 Elle 121 NULL NULL
8 Jane 191 A1 E
5 Silva 811 S1 SE
6 Juan 411 S2 SE
7 Carla 431 S2 SE
Please note that I have added scripts and output only for the parts where it required change, and rest part is same script provided by you.
I have a query that I can't understand. Can someone explain to me what is going on with all these commas ?
SELECT * FROM TABLE1
LEFT OUTER JOIN TABLE2 ON TABLE1.Column1 = TABLE2.Column1,
TABLE3, TABLE4, TABLE5, TABLE6
WHERE [...]
I don't get the part where a bunch or tables are listed. I figured out by the WHERE part that it was bound or at least used like in a "FROM" use. Can someone explain to me what is it and the name or at least have a link to the documentation of this form of link ?
Thanks a lot.
This means you Are Joining TABLE1 and TABLE2 using LEFT JOIN
So If there is a Matching value in TABLE2.Column1 for TABLE1.Column1 that Value will be displayed and if there is no Match, then the Column Will be there but Value will be NULL
For all other Tables, you are using a CROSS JOIN. So It will create a Cartesian Product with the Records obtained from the First Join
DECLARE #TABLEA TABLE
(
ColA INT
)
DECLARE #TABLEB TABLE
(
ColB INT
)
DECLARE #TABLEC TABLE
(
ColC INT
)
DECLARE #TABLED TABLE
(
ColD INT
)
INSERT INTO #TABLEA
VALUES(1),(2),(3)
INSERT INTO #TABLEB
VALUES(4),(5),(6)
INSERT INTO #TABLEC
VALUES(7),(8),(9)
INSERT INTO #TABLED
VALUES(10)
SELECT
*
FROM #TABLEA A
LEFT JOIN #TABLEB B
ON A.ColA = B.ColB
,#TABLEC,#TABLED
In the above Example, TableA and TableB are LEFT JOINed and then TABLEC AND TABLED are Cross Joined with the Result. So my Final Output will be
ColA ColB ColC ColD
----------- ----------- ----------- -----------
1 NULL 7 10
1 NULL 8 10
1 NULL 9 10
2 NULL 7 10
2 NULL 8 10
2 NULL 9 10
3 NULL 7 10
3 NULL 8 10
3 NULL 9 10
You Can Filter the Records from any of the tables using the WHERE Clause
I have following tow tables
create table #temp(id int,rid int)
insert into #temp
select 1,1
union all
select 2,1
union all
select 3,1
select * from #temp
drop table #temp1
create table #temp1(id int, nid int,PRIMARY KEY CLUSTERED
(
id asc,nid asc
))
insert into #temp1
select 1,10
union all
select 2,10
union all
select 2,11
union all
select 3,10
Following are the both result sets:
id rid
1 1
2 1
3 1
id nid
1 10
2 10
2 11
3 10
I want to update #temp1 table with value from rid field of #temp table by matching id field from both tables. See following query:
select a.*
from #temp1 a inner join #temp b
on a.id = b.id
where a.id <> b.rid
It returns:
id nid
2 10
2 11
3 10
I want to update id with following query:
update a
set a.id = b.rid
-- select a.*
from #temp1 a inner join #temp b
on a.id = b.id
where a.id <> b.rid
But it returns
primary key violation error because of primary key in table #temp1.
I would like to delete the value if it is already exist if not then I would like to update
for example
id nid
1 10
2 10-- want to update but not able to this bcoz it violates primary key so delete this row.
2 11-- able to update this row but other 2 rows causing an issue.
3 10-- want to update but not able to this bcoz it violates primary key so delete this row.
Please suggest other ways to do this.
Because You are Violating the Primary Key Constraints
Check Below Tables
select B.*
from #temp1 a inner join #temp b
on a.id = b.id
where a.id <> b.rid
id rid
2 1
2 1
3 1
select * from #temp1
id nid
1 10
2 10
2 11
3 10
You are setting ID of above first table using join from #temp which already in #temp1
You Are attempt to Update Values which are already in #temp1 where id=2,2,3
select *
from #temp1 a inner join #temp b
on a.id = b.id
where a.id <> b.rid
You would be updating two id 2 records to the same value. You cannot do this, period. There is no other method to fix this except to drop the PK which I would suggest would be bad idea.
It is possible you need some further definition in your pdate to specify which of multiple records you want to update or you may need to delete the record which might end up as a duplicate before you do the update. Not knowing the business rules for what you are actually trying to accomplish or what your data means, it is impossiblet say what you can do to solve your problem. This ia case where the solution is dependant on the meaning and of course we have no meaning here.
I have a database with two tables (Table1 and Table2). Table1 has one column ColumnA and Table2 has one column ColumnB i want to select both the columns,
looking for something like:
ColumnA in Table1:
a
b
c
ColumnA in Table2:
d
e
f
Result set should be:
a d
b e
c f
Thanks in advance..
I am pretty sure sql server 2000 supports table vars so you can try this
DECLARE #TableA TABLE(
ID INT IDENTITY(1,1),
Val VARCHAR(50)
)
INSERT INTO #TableA (Val) SELECT ColumnA FROM Table1
DECLARE #TableB TABLE(
ID INT IDENTITY(1,1),
Val VARCHAR(50)
)
INSERT INTO #TableB (Val) SELECT ColumnB FROM Table2
SELECT a.Val,
b.Val
FROM #TableA a INNER JOIN
#TableB b ON a.ID = b.ID
Since you have no relation between the two tables, this operation is not really defined. What row in table1 goes with what row in table2?
You should set up a relation.
What is it you want to achieve anyway?
I don't know the big picture but from what you've said, here's an example. There has to be some way to define which record in table 1 should match up with a record in table 2. I'm assuming they match up on the ordering when ordered by the column in each table (e.g. record 1 from Table 1 ordered by column A, matches with record 1 from Table 2 ordered by column B). This example requires SQL 2005 or higher.
DECLARE #T1 TABLE (A varchar(10))
DECLARE #T2 TABLE (B varchar(10))
INSERT #T1 VALUES ('a')
INSERT #T1 VALUES ('b')
INSERT #T1 VALUES ('c')
INSERT #T2 VALUES ('d')
INSERT #T2 VALUES ('e')
INSERT #T2 VALUES ('f')
SELECT A, B
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY A ASC) AS RowNo, A
FROM #T1
) t1
JOIN
(
SELECT ROW_NUMBER() OVER (ORDER BY B ASC) AS RowNo, B
FROM #T2
) t2 ON t1.RowNo = t2.RowNo
How will the system know to associate the 'a' value from table1 with the 'd' value from table 2? If someone adds another row to table2 with value 'c' should your query now output
null- c
a - d
b - e
c - f
or
a - c
b - d
c - e
or
a - c
b - d
c - e
null- f
??? --- You have to specify in some way what rules to use to associate the rows from table1 with the rows from table2.
If you just want the rows associated based on alphabetical sorting,
then if the values are unique in each of the tables, (using standard SQL only), try this
Select Z1.ColumnA, z2.ColumnB
From (Select ColumnA,
(Select Count(*)
From Table1
Where ColumnA < t1.ColumnA) RowNo,
From Table1 T1) z1
Join (Select ColumnB,
(Select Count(*)
From Table2
Where ColumnB < t2.ColumnB) RowNo,
From Table2 T2) z2
On z1.RowNo = z2.RowNo
Order By z1.RowNo