2012-05-22 13 views
5

estoy usando SQL Server 2008. Tengo 2 variables de tabla como¿Cómo combinar las columnas de las tablas 2 en 1 sin usar JOIN

FirstName 
========== 
Little 
John 
Baby 

LastName 
========== 
Timmy 
Doe 
Jessica 

Y quiero ser la tabla de resultados:

First  Last 
===================== 
Little  Timmy  
John  Doe  
Baby  Jessica 

Tenga en cuenta que no hay PK puede unir las 2 tablas. Estoy tratando de usar un cursor pero no estoy seguro de cómo comenzar.

---- ----- Actualizado

Sé que es un caso raro, pero estoy escribiendo un guión para limpiar los datos heredados. La única forma en que sabemos que "Little" va con "Timmy" es que ambos son el primer registro de la mesa. ¿Ayudaría si tuviéramos PK para las tablas pero no hay relación?

ID FirstName 
========== 
1 Little 
2 John 
3 Baby 
---------- 

ID LastName 
========== 
4 Timmy 
5 Doe 
6 Jessica 
---------- 

No estoy familiarizado con TSQL así que pensé que puede recorrer las 2 tablas como bucle a través de matrices en la memoria.

+2

@Xi .... sin PK, ¿cómo estás seguro de que poco va a Timmy, etc. Es importante el orden de los registros el factor determinante? – MikeTWebb

+0

¿Por qué querrías hacer esto? –

+1

hombre, sin ninguna clave principal no se puede 'UNIR', 'Cursor' etc. – Sajmon

Respuesta

6

Usted podría intentar algo como esto, para que coincida con base en números de fila:

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 

pero no tome esto como una señal de que no necesita llaves.

+0

+1 especialmente para el comentario de "no necesitar claves". –

+0

Lo estoy bajando porque la pregunta es bastante clara: no hay identificaciones en las dos tablas. Su orden por es sintácticamente incorrecta. –

+0

@GordonLinoff: Estoy viendo la versión actualizada del OP de las tablas, que contiene columnas ID que podemos usar para ordenar por –

1

No existe el "primer registro". El orden de lectura es totalmente indefinido. ¡Esto también es verdad en la práctica! Usted va a ver el orden de filas al azar en la práctica.

Usted necesidad de definir un orden de clasificación. Después de hacer eso se puede consultar la siguiente manera:

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 

Aviso el marcador de posición "SORT ORDER HERE". Necesito completarlo. Ejemplo: "ID" o "FirstName".

Editar: Después de ver su edición agregué orden de clasificación en ID. Esto funcionará ahora.

+0

Cogí el código que él borró (razón desconocida para mí, fue un buen comienzo). No pasó nada malo al hacerlo. Sin embargo, arreglé el código y agregué muchos comentarios. – usr

+0

@usr: cuando publiqué por primera vez no había columnas de ID en la pregunta del OP. Sin ellas (o piratear las tablas para agregar algo) no había forma de hacer un pedido, así que lo borré y agregué un comentario. al OP necesitaron una forma de ordenar. –

+0

Edité el código para ordenar por ID. Esta solución funcionará. @AdamV, tomar su código no fue un acto malicioso. Yo mismo habría producido un código similar. Retyping habría sido una pérdida de tiempo. – usr

0

Aquí es un truco, que podrían funcionar en su caso:

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 

En mi experiencia, el row_number() con la sub consulta para el pedido por medio de que ningún tipo que realmente se hace, pero las filas están traído secuencialmente. Es más probable que esto funcione si está utilizando una única instancia con subprocesos.

¡Y no garantizo que funcione! ¡Definitivamente verifica los resultados! Si esto no funciona, puede obtener el mismo efecto utilizando tablas temporales.

¿Estos datos provienen del exterior del mundo de la base de datos? Si tiene que realizar este proceso más de una vez, debe manejar el problema externamente o al ingresar a la base de datos.

2

No puede unir de forma fiable estas dos variables de tabla sin identidades.Asumiendo que se están pobladas de forma ordinal, en primer lugar, cada tabla se puede crear con las identidades de la siguiente manera:

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 
+4

Tenga cuidado, sin 'MAXDOP' su cláusula' VALUES' podría insertarse en cualquier orden, lo que significa que puede que no obtenga los mismos resultados todas las veces (es por eso que preguntamos cómo se estaban determinando los valores de ID). Por supuesto, es poco probable que alguna vez sea diferente, pero no se garantiza que se comporte igual siempre. –

+1

@ Aaronofertrand El objetivo aquí es ordenar la identificación, por lo que dividirla en declaraciones separadas debería resolver esa posibilidad, como se ha editado anteriormente. –

+0

Sí, mucho mejor :-) - ahora, simplemente no tenemos idea si el OP tiene la capacidad de definir el orden de inserción de esta manera. Si es INSERTAR ...SELECCIONADO DE some_other_table, y esa tabla tampoco tiene una clave, todavía no hay forma de definir confiablemente "primero" ... –

0

Basándose en @JohnDewey solución presentada, puede ordenar los registros en las variables de la tabla. En la práctica, se creará una relación entre los valores basados ​​en el orden de los registros:

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 
+0

Sigue el mismo problema: la asignación de valores de identidad no está garantizada a menos que use 'MAXDOP 1' ... –

+0

@AaronBertrand es correcto, aunque en mi experiencia SQL Server devuelve filas en el mismo orden en que se insertaron cuando la tabla no lo hace t tiene un índice agrupado, no ofrece ninguna garantía de este comportamiento; este podría ser un efecto secundario de la ID de surogate que crea el motor. Estrictamente hablando, no hay solución usando el álgebra relacional o la teoría de conjuntos (ya que ignoran el orden), pero esta sugerencia ** podría ser un enfoque lo suficientemente bueno como para intentarlo. –

Cuestiones relacionadas