Cómo combinar columnas de 2 tablas en 1 sin usar JOIN
Frecuentes
Visto 3,854 veces
5
I am using SQL Server 2008. I have 2 table variables like
FirstName
==========
Little
John
Baby
LastName
==========
Timmy
Doe
Jessica
And I want the result table be:
First Last
=====================
Little Timmy
John Doe
Baby Jessica
Note that there is no PK can join the 2 tables. I am trying to use a cursor but not sure how to start.
---- Updated -----
I know it's a rare case, but I am writing a script to clean up legacy data. The only way we know "Little" goes with "Timmy" is that they are both the first record of the table. Would it help if we had PK for the tables but there is no relation?
ID FirstName
==========
1 Little
2 John
3 Baby
----------
ID LastName
==========
4 Timmy
5 Doe
6 Jessica
----------
I am not familiar with TSQL so I thought I can loop through the 2 tables like looping through Arrays in memory.
5 Respuestas
7
You could try something like this, to match up based on row numbers:
SELECT FirstName AS First, LastName AS Last
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY ID) AS RowNum, FirstName
FROM FirstName
) t1
INNER JOIN
(
SELECT ROW_NUMBER() OVER (ORDER BY ID) AS RowNum, LastName
FROM LastName
) t2
ON t1.RowNum = t2.RowNum
But don't take this as a signal that you don't need keys.
contestado el 22 de mayo de 12 a las 18:05
I"m downvoting it because the question is pretty clear that there are no id's in the two tables. Your order by is syntactically incorrect. - gordon linoff
@GordonLinoff: I'm looking at the OP's updated version of the tables, which contains ID columns that we can use to order by. - Adam V
@GordonLinoff I think you should reverse your downvote. Given the updated data this is a correct answer. - Aarón Bertrand
You are right. I do need keys after all. You example is a good start. Thanks! - Xi 张 熹
2
You can't reliably join these two table variables without identities. Assuming they are being populated in an ordinal manner in the first place, each table could be created with identities as follows:
DECLARE @first TABLE(ID INT IDENTITY(1,1), NameFirst VARCHAR(30));
DECLARE @last TABLE(ID INT IDENTITY(1,1), NameLast VARCHAR(30));
-- Note that we don't need to list column names here
INSERT INTO @first VALUES('Little');
INSERT INTO @first VALUES('John');
INSERT INTO @first VALUES('Baby');
INSERT INTO @last VALUES('Timmy');
INSERT INTO @last VALUES('Doe');
INSERT INTO @last VALUES('Jessica');
SELECT n1.NameFirst
, n2.NameLast
FROM @first n1
INNER JOIN @last n2 ON n1.ID=n2.ID;
Resultado:
NameFirst NameLast
------------------------------ ------------------------------
Little Timmy
John Doe
Baby Jessica
contestado el 22 de mayo de 12 a las 18:05
Be careful, without MAXDOP
tu VALUES
clause could be inserted in any order, meaning you may not get the same results every time (this is why we asked on the question how the ID values were being determined). Granted, it is unlikely that it would ever be different, but it is not guaranteed to behave the same every time. - Aarón Bertrand
@AaronBertrand The objective here is the ordering of ID, so breaking into separate statements should resolve that possibility, as edited above. - John Dewey
Yes, much better :-) - now, we just have no idea if the OP has the ability to define the insert order this way. If it is INSERT ... SELECT FROM some_other_table, and that table also doesn't have a key, there is still no way to reliably define "first"... - Aarón Bertrand
Agreed, and if the OP not currently controlling the order, he'll need to revisit the process by which the tables are being populated. - John Dewey
1
There is no such thing as a "first record". Reading order is totally undefined. This holds true in practice as well! You sí see random row order in practice.
Usted necesitas to define a sorting order. After doing that you can query like this:
SELECT FirstName AS First, LastName AS Last
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY ID) AS r, FirstName
FROM FirstName
) t1
INNER JOIN
(
SELECT ROW_NUMBER() OVER (ORDER BY ID) AS r, LastName
FROM LastName
) t2
ON t1.r = t2.r
Notice the placeholder "SORT ORDER HERE
". Need to fill that in. Example: "ID" or "FirstName".
Edit: Having seen your edit I added sort order on ID. This will work now.
contestado el 22 de mayo de 12 a las 18:05
I took the code from his which he deleted (reason unknown to me - it was a good start). Nothing wrong with doing that. I fixed the code, though, and added lots of commentary. - usr
@usr: when I first posted it, there were no ID columns in the OP's question. Without those (or hacking the tables to add something in) there was no way to do an order, so I deleted and added a comment telling the OP they needed a way to sort. - Adam V
I edited the code to order by ID. This solution will work.; @AdamV, taking your code was not a malicious act. I'd have produced similar code myself. Retyping it would have been a waste of time. - usr
@usr: I completely understand, I'm not upset! :) - Adam V
@usr nobody is upset or claiming it is malicious. Just seems weird you would copy code from another answer but not check its validity, that's all. - Aarón Bertrand
0
Here is a hack, that might work in your case:
select t1.id, t1.name, t2.name
from (select name, row_number() over (partition by null order by (select NULL)) as id
from t1
) t1 join
(select name, row_number() over (partition by null order by (select NULL)) as id
from t2
) t2
on t1.id = t2.id
In my experience, the row_number() with the subquery for the order by means that no sort is actually done, but the rows are brought in sequentially. This is more likely to work if you are using a single threaded instance.
And, I don't guarantee that it will work! Definitely check the results! If this doesn't work, you might be able to get the same effect by using temporary tables.
Is this data coming from outside the database world? If you have to perform this process more than once, then you should handle the problem either externally or on input into the database.
contestado el 22 de mayo de 12 a las 18:05
0
Building on solution @JohnDewey presented, you can sort the records into the table variables. In practice, it will create a relation between the values based on the order of the records:
DECLARE @first TABLE(sequence INT IDENTITY(1,1), FirstName VARCHAR(30));
DECLARE @last TABLE(sequence INT IDENTITY(1,1), LastName VARCHAR(30));
INSERT INTO @first(FirstName)
SELECT FirstName FROM TableFisrt ORDER BY id;
-- sequence FirstName
-- ======== =========
-- 1 Little
-- 2 John
-- 3 Baby
INSERT INTO @last(LastName)
SELECT FirstName FROM TableLast ORDER BY id;
-- sequence LastName
-- ======== =========
-- 1 Timmy
-- 2 Doe
-- 3 Jessica
SELECT frs.FirstName, lst.LastName
FROM @first frs
INNER JOIN @last lst ON frs.sequence = lst.sequence;
-- sequence FirstName
-- ======== =========
-- Little Timmy
-- John Doe
-- Baby Jessica
contestado el 22 de mayo de 12 a las 19:05
Still the same problem - the assignment of identity values is not guaranteed unless you use MAXDOP 1
... - Aarón Bertrand
@AaronBertrand is right, although in my experience SQL Server returns rows at the same order they were inserted when the table doesn't have a clustered index, it does not make any guarantee of this behaviour -- this might be a side effect of the surogate ID the engine creates. Strictly speaking, there's no solution using relational algebra or set theory (since they ignore order), but this suggestion podría be a good enough approach to worth a try. - Gerardo Lima
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas sql sql-server tsql or haz tu propia pregunta.
@Xi....with no PK, how are you assured that Little goes with Timmy, etc. Is the order of the records the determining factor? - MikeTWebb
Por qué querrías hacer esto? - Lynn Crumbling
man, without any primary key you cannot
JOIN
,Cursor
Etc.- Simon Dorociak@Xi, are there any Id columns that could help establish an ordering or matching? - Web User
I had added a ROW_NUMBER() answer, but like @Web User says, without a way of establishing an ordering, this won't work either. - Adam V