Example:
Table 1:
Column1 Column2
----------- -------------
A 1
B 2
D 3
E 4
Table 2:
Column3 Column4
----------- -------------
A 7
E 9
Z 5
Expected output:
Column1 Column2 Column3 Column4
----------- ------------- ------------- -------------
A 1 A 7
B 2 E 9
D 3 Z 5
E 4 NULL NULL
I want the output as shown in the picture.
If there are two tables with the columns Column1, Coumn2 and Column3, Column4,
then the expected output should be Column1, Column2, Column3, Column4, without any joins. It should have Table2's columns to the right hand side of the Table1's columns. NULL values will consume the empty rows if the number of rows in each table don't match.
You can use ROW_NUMBER window function to create a calculated field that can be used to join the two tables together:
SELECT t1.Column1, t1.Column2, t2.Column3, t2.Column4
FROM (
SELECT Column1, Column2,
ROW_NUMBER() OVER (ORDER BY Column1) AS rn
FROM Table1) AS t1
FULL OUTER JOIN (
SELECT Column3, Column4,
ROW_NUMBER() OVER (ORDER BY Column3) AS rn
FROM Table2) AS t2
ON t1.rn = t2.rn
A FULL OUTER JOIN is necessary in case either Table1 or Table2 has more rows.
This would work:-
SELECT Column1, Column2, Column3, Column4 FROM
(SELECT ROW_NUMBER() OVER(ORDER BY Column1) row, Table1.*
FROM Table1) t1
FULL OUTER JOIN (SELECT ROW_NUMBER() OVER(ORDER BY Column3) row, Table2.*
FROM Table2) t2
ON t1.row = t2.row
SQLFIDDLE
Alternatively, you could also do a left join instead of full outer join:
SELECT Column1
,Column2
,t.Column3
,t.Column4
FROM (
SELECT ROW_NUMBER() OVER (
ORDER BY Column1
) rn
,Table1.*
FROM Table1
) t1
LEFT JOIN (
SELECT ROW_NUMBER() OVER (
ORDER BY Column3
) AS rn
,t2.*
FROM Table2 t2
) t ON t1.rn = t.rn;
SQL Fiddle Demo
Note: Ofcourse, this is only going to work if you have more records in TableA.
The simplest way is using CROSS JOIN
SELECT t1.FIELD_A, t2.FIELD_B, t1.FIELD_C, t2.FIELD_D, t2.FIELD_E
FROM tbl01 t1
CROSS JOIN
tbl02 t2
Related
My subqueries produce a result like this:
coulmn1 column2
a d
b z1000
c c
d
1
2
z1000 k
I want to know the different elements in both sets. column1 ={ a,b,c, 1,2,d, z1000,.....} column 2 ={ d,c,z1000,k......} The result I want is ={ a,k,1,2,....} hope I made it clear ..please let me know how could I do that..?
One method is full outer join:
select coalesce(t1.col1, t2.col2)
from t t1 full join
t t2
on t1.col1 = t2.col2
where t1.col1 is null or t2.col2 is null;
Another method doesn't require running the subquery twice;
select v.col
from t cross apply
(values (t.col1, 1), (t.col2, 2)) v(col, which)
group by v.col
having min(v.which) = max(v.which);
--Test Data
with temp_table as (
select 'a' coulmn1,'b' column2 union all
select 'b' coulmn1,'z1000' column2 union all
select 'c' coulmn1,'c' column2 union all
select 'd' coulmn1,'' column2 union all
select 'z1000' coulmn1,'k' column2
)
--use cross join and union to distinct data
--you have to change temp_table to your own table
select * into #temp_table from (
select T.coulmn1,T2.column2 as column2
from temp_table T,temp_table T2
where T.coulmn1 <> T2.column2
) T;
select coulmn1 from #temp_table
union
select column2 from #temp_table;
Test Link
Use EXCEPT for this.
SELECT column1
FROM your_subquery
EXCEPT
SELECT column2
FROM your_subquery
UNION
SELECT column2
FROM your_subquery
EXCEPT
SELECT column1
FROM your_subquery
how can I update a column of my table1 with this query?
update table1
set table1.column5 = (
select count(*)
from table2, table1
where table1.column1 = table2.column4
group by table1.column1)
table1 has these columns (column1, column2, column3, column4, column5)
table2 has these columns (column1, column2, column3, column4)
and table2.column4 is foreign key of table1.column1
Use This
UPDATE T1
SET
column5 = COUNT(1)
FROM table2 T2
INNER JOIN table1 T1
ON T1.column1 = T2.column4
GROUP BY T2.column4
Or This
;WITH CNT
AS
(
SELECT
column4,
Cnt = COUNT(1)
FROM table2 T2
GROUP BY T2.column4
)
update t1
SET
column5 = CNT.Cnt
FROM CNT
INNER JOIN table1 T1
ON CNT.column4 = T1.column1
Try this query
with cte as (
select column4, cnt = count(*)
from table2
group by column4
)
update a
a.column5 = b.cnt
from
table1 a
join cte b on a.column1 = b.column4
I am trying to Left join Table 1 to table 2
Table1 Table2
ID Data ID Data2
1 r 1 q
2 t 1 a
3 z 2 x
1 u 3 c
After i have left joined this two Tables i would like get something like this
Table1+2
ID Data Data2
1 r a
2 t x
3 z c
1 u q
and NOT
Table1+2
ID Data Data2
1 r q
2 t x
3 z c
1 u q
and my question is: is there any possibility to tell table 2 that if u have used something for table 1, dont use it and give me next value. do i have to make it im T-SQL or to and new column where i can list if this id exists then write 2 if not 1(Number data). How can i solve this problem?
Ty u in advance.
Since there's no uniqueness in the ID on both tables, lets add some uniqueness to it.
So it can be used to join on.
The window function ROW_NUMBER can be used for that.
An example solution that gives the expected result:
DECLARE #TestTable1 TABLE (ID INT, Data VARCHAR(1));
DECLARE #TestTable2 TABLE (ID INT, Data VARCHAR(1));
INSERT INTO #TestTable1 VALUES (1,'r'),(2,'t'),(3,'z'),(1,'u');
INSERT INTO #TestTable2 VALUES (1,'q'),(1,'a'),(2,'x'),(3,'c');
select
t1.ID, t1.Data,
t2.Data as Data2
from (
select ID, Data,
row_number() over (partition by ID order by Data) as rn
from #TestTable1
) t1
left join (
select ID, Data,
row_number() over (partition by ID order by Data) as rn
from #TestTable2
) t2 on t1.ID = t2.ID and t1.rn = t2.rn;
Note: Because of the LEFT JOIN, this does assume the amount of same ID's in table2 are equal or lower can those on table1. But you can change that to a FULL JOIN if that's not the case.
Returns :
ID Data Data2
1 r a
1 u q
2 t x
3 z c
To get the other result could have been achieved in different ways.
This is actually a more common situation.
Where one wants all from Table 1, but only get one value from Table 2 for each record of Table 1.
1) A top 1 with ties in combination with a order by rownumber()
select top 1 with ties
t1.ID, t1.Data,
t2.Data as Data2
from #TestTable1 t1
left join #TestTable2 t2 on t1.ID = t2.ID
order by row_number() over (partition by t1.ID, t1.Data order by t2.Data desc);
The top 1 with ties will only show those where the row_number() = 1
2) Using the row_number in a subquery:
select ID, Data, Data2
from (
select
t1.ID, t1.Data,
t2.Data as Data2,
row_number() over (partition by t1.ID, t1.Data order by t2.Data desc) as rn
from #TestTable1 t1
left join #TestTable2 t2 on t1.ID = t2.ID
) q
where rn = 1;
3) just a simple group by and a max :
select t1.ID, t1.Data, max(t2.Data) as Data2
from #TestTable1 t1
left join #TestTable2 t2 on t1.ID = t2.ID
group by t1.ID, t1.Data
order by 1,2;
All 3 give the same result:
ID Data Data2
1 r q
1 u q
2 t x
3 z c
Use ROW_NUMBER
DECLARE #Table1 TABLE (ID INT, DATA VARCHAR(10))
DECLARE #Table2 TABLE (ID INT, DATA VARCHAR(10))
INSERT INTO #Table1
VALUES
(1, 'r'),
(2, 't'),
(3, 'z'),
(1, 'u')
INSERT INTO #Table2
VALUES
(1, 'q'),
(1, 'a'),
(2, 'x'),
(3, 'c')
SELECT
A.*,
B.DATA
FROM
(SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY(SELECT NULL)) RowId FROM #Table1) A INNER JOIN
(SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY(SELECT NULL)) RowId FROM #Table2) B ON A.ID = B.ID AND
A.RowId = B.RowId
I want two columns in the output of the join. I only get one, the storeID. The StoreComponentID is not there.
if you want two column you need to declare two columns
SELECT column1, NULL as column2 -- even when Table1 doesnt have column2
FROM Table1
UNION
SELECT NULL as column1, column2 -- even when Table2 doesnt have column1
FROM Table2
Now if you want some kind of merge side by side.
WITH idA as (
SELECT StoreComponentID,
ROW_NUMBER() OVER (ORDER BY StoreComponentID) as rn
FROM StoreComponent
), idB as (
SELECT StoreID
ROW_NUMBER() OVER (ORDER BY StoreID) as rn
FROM Store
)
SELECT idA.StoreComponentID,
idB.StoreID
FROM idA
FULL JOIN idB
ON idA.rn = idB.rn
I figured out a simple solution:
select S.storeid as sID, SC.storecomponentid as SCID from tstore as S, tstorecomponent as SC
I got following table and want to calculate value of Column2 on each row using the value of the same column (Column2) from the previous row in a sql without using cursor or while loop.
Id Date Column1 Column2
1 01/01/2011 5 5 => Same as Column1
2 02/01/2011 2 18 => (1 + (value of Column2 from the previous row)) * (1 + (Value of Column1 from the current row)) i.e. (1+5)*(1+2)
3 03/01/2011 3 76 => (1+18)*(1+3) = 19*4
and so on
Any thoughts?
Assuming at least SQL Server 2005 for the recursive CTE:
;with cteCalculation as (
select t.Id, t.Date, t.Column1, t.Column1 as Column2
from YourTable t
where t.Id = 1
union all
select t.Id, t.Date, t.Column1, (1+t.Column1)*(1+c.Column2) as Column2
from YourTable t
inner join cteCalculation c
on t.Id-1 = c.id
)
select c.Id, c.Date, c.Column1, c.Column2
from cteCalculation c
I solved the problem, just mentioned.
This is my code:
;with cteCalculation as (
select t.Id, t.Column1, t.Column1 as Column2
from table_1 t
where t.Id = 1
union all
select t.Id, t.Column1, (1+t.Column1)*(1+c.Column2) as Column2
from table_1 t
inner join cteCalculation c
on t.Id-1 = c.id
),
cte2 as(
select t.Id, t.Column1 as Column3
from table_1 t
where t.Id = 1
union all
select t.Id, (select column2+1 from cteCalculation c where c.id = t.id) as Column3
from table_1 t
inner join cte2 c2
on t.Id-1 = c2.id
)
select c.Id, c.Column1, c.Column2, c2.column3
from cteCalculation c
inner join cte2 c2 on c.id = c2.id
The result is as I was expected:
1 5 5 5
2 2 18 19
3 3 76 77
Here is an example using ROW_NUMBER() if the Id's aren't necessarily in order:
;with DataRaw as (
select 1 as Id, '01/01/11' as Date, 5 as Column1 union
select 2 as Id, '02/01/11' as Date, 2 as Column1 union
select 4 as Id, '03/01/11' as Date, 3 as Column1
),
Data as (
select RowId = ROW_NUMBER() over (order by Id), Id, Date, Column1 from DataRaw
),
Data2 as (
select
RowId, id, Date, Column1, Column1 as Column2
from
Data d
where
RowId = 1
union all
select
d1.RowId, d1.id, d1.Date, d1.Column1, (1+d1.column1)*(1+d2.column2) as column2
from
Data d1
cross join
Data2 d2
where
d2.RowId + 1 = d1.RowId
)
select
Id, Date, Column1, Column2
from
Data2
edit: shoudld have read the question better...
Another go woudl be this:
;with DataRaw as (
select 1 as Id, '01/01/11' as Date, 5 as Column1 union
select 2 as Id, '02/01/11' as Date, 2 as Column1 union
select 4 as Id, '03/01/11' as Date, 3 as Column1
),
Data as (
select Ord = ROW_NUMBER() over (order by Id), Id, Date, Column1 from DataRaw
),
select -- formula goes here, using current and prev as datasources.
from data current
left join data prev on current.Ord = prev.Ord + 1 -- pick the previous row by adding 1 to the ordinal
I think a normal join to get to the previous row would be faster than a CTE. You;d have to check for yourself though.
Looks easier to me.
Good luck, GJ