How to replace TOP 1000 rows of select columns indiscriminately - sql

Basically I have a table that contains 1000 rows with three columns. (TABLE A)
I have ANOTHER table with 200 columns with 1million+ records. (TABLE B)
I am trying to replace the THREE COLUMNS OF 1000 rows of TABLE B with those of TABLE A. I've read a lot of solutions where you can INSERT into table B from TABLE A.. but that's useless because I'll get NULLs in the remaining 197 columns that I need data for.
So the task is to replace rows of certain columns from one table to select columns of another table. There is NO conditions, just the top rows or whatever order you can think of is fine. If you can give an answer that takes ORDER BY something into account, that'd be bonus! Thank you so much!

If I understood your requirements
WITH TA
AS (SELECT *,
ROW_NUMBER()
OVER (
ORDER BY col1) AS RN
FROM TableA),
TB
AS (SELECT *,
ROW_NUMBER()
OVER (
ORDER BY col1) AS RN
FROM TableB)
UPDATE TB
SET TB.col1 = TA.col1,
TB.col2 = TA.col2,
TB.col3 = TA.col3
FROM TB
JOIN TA
ON TB.RN = TA.RN

Try something like this:
WITH topB AS (
SELECT TOP 1000 row_number() OVER(ORDER BY field_n) rn, b.* FROM table_b b
ORDER BY field_x),
topA AS (
SELECT row_number() OVER(ORDER BY field_m) rn, a.*
FROM table_a a)
UPDATE b
SET
b.Field_1 = a.Field_1,
b.Field_2 = a.Field_2,
b.Field_3 = a.Field_3
FROM
TopB b JOIN TopA a ON b.rn = a.rn
Idea here is to assign row numbers in both tables, join them by these numbers, and update the B part of the join with values from A.

Related

How do I join two tables together (one to many relationship), but only select the 3rd match from the second table?

I have two tables, table A and table B. There are multiple entries in table B for each entry in table A when joining them together, but I only want to match the 3rd value from table B, which is neither the maximum nor the minimum of the values. The values can be ordered, and it will always be the 3rd value after ordering. Is there a way to do this? Thank you!
WITH
ranked_b AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY key ORDER BY val) AS key_rank
FROM
table_b
)
SELECT
*
FROM
table_a
INNER JOIN
ranked_b
ON ranked_b.key = table_a.key
AND ranked_b.key_rank = 3
Consider below approach
select key,
array_agg(value order by value limit 3)[safe_ordinal(3)] as value
from tableA
left join tableB
on key = foreignkey
group by key
You can use a correlated subquery:
select a.*,
(select b.value
from b
where b.key = a.key
limit 1 offset 2
)
from a;

Get one record per ID

I'm trying to retrieve data from 2 tables A&B.
(select * from tableA a LEFT JOIN tableB b on a.idA = b.idA)
, there are multiple data rows in B for each PrimaryKey from A. But I want to get only the first record for every ID from tableA. How can I achieve this?
SQL tables represent unordered sets so there is no first row. But you can get an arbitrary row or specific row based on an ordering column using window functions:
select *
from tableA a LEFT JOIN
(select b.*,
row_number() over (partition by idA order by <ordering col>) as seqnum
from tableB b
) b
on a.idA = b.idA and seqnum = 1

How can I display two columns together in SQL?

I have 2 queries that return data in the form:
query 1:
column 1
a
b
c
query 2:
column 2
d
e
How can I combine the 2 queries to get output as:
column 1 column 2
a d
b e
c
The order of data in the columns does not matter.
Possibly anything with joins ?
Thanks
use row_number()
select t1.col1,t2.col2 from
(
select *,row_number() over(order by col1) rn from query1
) t1 full outer join
(
select *,row_number() over(order by col2) rn from query2
) t2 on t1.rn=t2.rn
For n,m rows use full outer join
A possible solution is selecting both columns with row_number() and join them by the row_number. One must be aware to select first from the table with the higher number of rows. Example:
select
col_1,
col_2
from (
select
a.col_1,
row_number() over () rn
from a
) s1
FULL OUTER JOIN (
select
b.col_2,
row_number() over () rn
from b
) s2 on s1.rn = s2.rn

How do I insert values from one table into another without a value to inner join them?

Table A has a single field.
Table B has many fields.
I want to copy each value from Table A to a row on Table B but I have no values with which to join the two tables.
It doesn't matter which row in B each value in A goes into as long as each value in Table A only appears once in Table B.
I do not want to use loops.
You could assign a row number to each of the two tables, and then do an update join:
WITH cte1 AS (
SELECT col, ROW_NUMBER() OVER (ORDER BY col) rn
FROM TableA
),
WITH cte2 AS (
SELECT *,
ROW_NUMBER() OVER (ORDER BY some_col) rn
FROM TableB
)
UPDATE t2
SET col = t1.col
FROM cte2 t2
INNER JOIN cte1 t1
ON t1.rn = t2.rn
This solution makes several assumptions, including that TableB already has a destination column col for the data coming from the first TableA table's single column, and that the types match in both tables. It also assumes that TableB has more rows than TableA to fit the data from TableB. If not, data would be lost.

SQL join two tables matching only 1 row to 1 row

I'm looking for ... lack of a better word, an "exclusive join". I want only 1 row from the right to match a row on the left and cannot be joined to another preceding row. Solution should be for MS SQL 2012.
Example: I have two tables A and B each with 10 rows. Row A1 matches B3 and B5, and Row A3 matches B3 and B5. Result set should include 2 rows: A1 joined to B3 (because it's the first match on the right), and A3 joined to B5 (because it's the first match on the right that hasn't already been used).
Obviously, I'm trying to avoid cursors. Perhaps a recursive CTE is the only other way to go about this?
One way to do this is to apply a row_number call to the join column, and then add a condition on it when you join:
SELECT a.*, b.*
FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY join_col ORDER BY 1) rn
FROM table_a) a
JOIN (SELECT *, ROW_NUMBER() OVER (PARTITION BY join_col ORDER BY 1) rn
FROM table_b) b ON a.join_col = b.join_col AND a.rn = b.rn
See the script beneath. CTE and cursor are not knockout demands I understand... Anyway, I hope it leads to your answer.
Without a identifier to join on (as not provided in your question, I think a cross join is needed, and partition by will do the trick.
Something like this:
create table #t (a nvarchar(2),rna int, b nvarchar(2), rnb int)
insert into #t select * from
(select a
,row_number() over (partition by a order by a) rna
,b
,row_number() over (partition by b order by b) rnb
from table_a
cross join
table_b
) as x
where rnb=1
select a, b from #t
drop table #t
And here a script to create the tables:
create table table_a (a nvarchar(2))
insert into table_a values ('A1'),('A3');
create table table_b (b nvarchar(2))
insert into table_b values ('B3'),('B5');