2012-09-16 10 views
6

Estoy aprendiendo SQL/dbms y usando Postgres. Quiero devolver las filas que tienen un cierto valor en una determinada columna. Por ejemplo, en las tablas Carpets y Curtains, quiero obtener el id s de filas donde el color es 'light yellow'. Creo que necesito UNIRME para esto, pero no estoy seguro de qué tipo.Creando una consulta que devuelve el id. Si la condición coincide en las filas de dos tablas

Esto es lo que tengo:

SELECT id 
    FROM Carpets 
    WHERE colour = 'light yellow' 
     INNER JOIN Curtains ON Carpets.colour = Curtains.colour; 

Ambas tablas tienen el atributo id.

Acerca de aprender JOIN, ¿cuál debo aprender primero? Me estoy disparando en el pie si trato de aprenderlos todos a la vez (ya que los diferentes recursos incluyen diferentes 'variantes').

IMPORTANTE Estaba buscando una respuesta donde el id sería devuelto solo si ambas cortinas y la alfombra eran de color "amarillo claro".

Respuesta

13

Leídos your question en Meta acerca de esta cuestión en particular, permítanme explicar por qué las tres respuestas correctas son de hecho - como es la forma en que WOR lo eliminó.

he incluido ejemplos de las tres respuestas y el esquema que están trabajando en:

Database changed 
mysql> create table carpet(id int(3), material varchar(10), color varchar(15)); 
Query OK, 0 rows affected (0.02 sec) 

mysql> create table curtain(id int(3), material varchar(10), color varchar(15)); 
Query OK, 0 rows affected (0.00 sec) 

(grupo de instrucciones de inserción)

mysql> select * from carpet; 
+------+-----------+--------------+ 
| id | material | color  | 
+------+-----------+--------------+ 
| 1 | wool  | Light Yellow | 
| 2 | wool  | Beige  | 
| 3 | polyester | Light Yellow | 
| 4 | polyester | Light Red | 
+------+-----------+--------------+ 
4 rows in set (0.00 sec) 

mysql> select * from curtain; 
+------+----------+--------------+ 
| id | material | color  | 
+------+----------+--------------+ 
| 1 | Velvet | Purple  | 
| 2 | cotton | White  | 
| 3 | cotton | Light Yellow | 
| 4 | cotton | Light Blue | 
+------+----------+--------------+ 
4 rows in set (0.00 sec) 

una intersección utiliza dos sentencias de selección y trae de vuelta resultados coincidentes. En este caso, está buscando todas las filas que tienen un color coincidente de 'Amarillo claro'.

No puedo darle un ejemplo en MySQL ya que no lo admite (Como puede ver a continuación, no es necesario dar los mismos resultados).

Una consulta de unión de dos sentencias de selección cada una con una cláusula where que solo permita el color de 'Amarillo claro' devolverá los mismos datos. Aunque una unión se puede usar para devolver datos que no coinciden, la cláusula where de cada instrucción select significa que solo se devolverá las filas que desee.

mysql> select id, material, color from carpet 
    -> union 
    -> select id, material, color from curtain; 
+------+-----------+--------------+ 
| id | material | color  | 
+------+-----------+--------------+ 
| 1 | wool  | Light Yellow | 
| 2 | wool  | Beige  | 
| 3 | polyester | Light Yellow | 
| 4 | polyester | Light Red | 
| 1 | Velvet | Purple  | 
| 2 | cotton | White  | 
| 3 | cotton | Light Yellow | 
| 4 | cotton | Light Blue | 
+------+-----------+--------------+ 
8 rows in set (0.00 sec) 

Aww, eso es malo ¿no?Por supuesto, no especificamos la cláusula where:

mysql> select id, material, color from carpet where color='Light Yellow' 
    -> union 
    -> select id, material, color from curtain where color='Light Yellow'; 
+------+-----------+--------------+ 
| id | material | color  | 
+------+-----------+--------------+ 
| 1 | wool  | Light Yellow | 
| 3 | polyester | Light Yellow | 
| 3 | cotton | Light Yellow | 
+------+-----------+--------------+ 
3 rows in set (0.00 sec) 

una combinación entre dos tablas en el color le permitirá devolver las filas de ambas tablas en una sola fila de datos. Puede especificar la unión en las dos tablas para el color del elemento y usar una cláusula where para devolver solo las filas que está buscando.

mysql> select a.id, a.material, a.color, b.id, b.material 
    -> from curtain a join carpet b on a.color=b.color; 
+------+----------+--------------+------+-----------+ 
| id | material | color  | id | material | 
+------+----------+--------------+------+-----------+ 
| 3 | cotton | Light Yellow | 1 | wool  | 
| 3 | cotton | Light Yellow | 3 | polyester | 
+------+----------+--------------+------+-----------+ 
2 rows in set (0.00 sec) 

Como se puede ver, esto ha regresado sólo las filas con un color a juego y te permitía tener columnas de ambas tablas en una sola fila de su conjunto de resultados.

Ahora, claramente no pensaba muy bien como no tengo otros resultados que coinciden aparte de la 'luz amarilla' en ambas tablas, por lo que si añado unas cuantas más entradas en que conseguir esto:

mysql> select * from curtain; 
+------+----------+--------------+ 
| id | material | color  | 
+------+----------+--------------+ 
| 1 | Velvet | Purple  | 
| 2 | cotton | White  | 
| 3 | cotton | Light Yellow | 
| 4 | cotton | Light Blue | 
| 5 | Wool  | White  | 
| 6 | Fluff | Beige  | 
+------+----------+--------------+ 
6 rows in set (0.00 sec) 

mysql> select * from carpet; 
+------+-----------+--------------+ 
| id | material | color  | 
+------+-----------+--------------+ 
| 1 | wool  | Light Yellow | 
| 2 | wool  | Beige  | 
| 3 | polyester | Light Yellow | 
| 4 | polyester | Light Red | 
| 5 | Fluff  | Light Blue | 
+------+-----------+--------------+ 
5 rows in set (0.00 sec) 

Ahora podemos ejecutar de nuevo, y esta vez llegar:

mysql> select a.id, a.material, a.color, b.id, b.material 
    -> from curtain a join carpet b on a.color=b.color; 
+------+----------+--------------+------+-----------+ 
| id | material | color  | id | material | 
+------+----------+--------------+------+-----------+ 
| 3 | cotton | Light Yellow | 1 | wool  | 
| 3 | cotton | Light Yellow | 3 | polyester | 
| 4 | cotton | Light Blue | 5 | Fluff  | 
| 6 | Fluff | Beige  | 2 | wool  | 
+------+----------+--------------+------+-----------+ 
4 rows in set (0.00 sec) 

¡Oh no!

esto es ahora donde utilizamos la unión y la cláusula donde juntos:

mysql> select a.id, a.material, a.color, b.id, b.material 
    -> from curtain a join carpet b on a.color=b.color 
    -> where a.color='Light Yellow'; 
+------+----------+--------------+------+-----------+ 
| id | material | color  | id | material | 
+------+----------+--------------+------+-----------+ 
| 3 | cotton | Light Yellow | 1 | wool  | 
| 3 | cotton | Light Yellow | 3 | polyester | 
+------+----------+--------------+------+-----------+ 
2 rows in set (0.00 sec) 

que ves, en SQL a menudo hay más formas de conseguir el mismo resultado a través de diferentes medios que los que hay variaciones de la misma datos en sus tablas.

EDIT: Bueno, por lo que si solo deseas filas donde todo los datos coinciden, justo incluirlo en la sintaxis de la combinación:

mysql> select a.id, a.material, a.color, b.id, b.material 
    -> from curtain a 
    -> join carpet b on a.color=b.color 
    -> and a.id=b.id 
    -> where a.color='Light Yellow'; 
+------+----------+--------------+------+-----------+ 
| id | material | color  | id | material | 
+------+----------+--------------+------+-----------+ 
| 3 | cotton | Light Yellow | 3 | polyester | 
+------+----------+--------------+------+-----------+ 
1 row in set (0.00 sec) 

Como se puede ver, ahora nos dicen la unión que tanto el Los campos id y color deben coincidir entre las dos tablas, y los resultados hablan por sí mismos. Ahora, en este caso, técnicamente todavía no coincidía con TODAS las columnas ya que el material es diferente. Si quería hacer coincidir más, la consulta no volvería ningún resultado como no tengo registros coincidentes en el ello, el material y hacer coincidir el color, pero la sintaxis sería la siguiente:

mysql> select a.id, a.material, a.color, b.id, b.material 
    -> from curtain a 
    -> join carpet b on a.color=b.color 
    -> and a.id=b.id 
    -> and a.material=b.material 
    -> where a.color='Light Yellow'; 
Empty set (0.00 sec) 

En esa nota, sin embargo, se en la mayoría de los casos, no desea que coincidan las columnas. Muy a menudo las tablas tienen una ID que solo se usa para esa tabla y es un valor que se incrementa automáticamente. Desea usarlo para identificar una fila única en esa tabla, pero no para usarla para hacer coincidir tablas no relacionadas. En todo caso, le habría sugerido que haga coincidir el material y el color, pero deje la identificación fuera de este.

+0

Lo que hubiera deseado de sus datos de muestra es solo id = 3. No id = 1 porque a pesar de que en color de alfombra = "amarillo claro" en color de cortina = "violeta" para id = 1. – Celeritas

+1

@Celeritas Próximamente :) – Fluffeh

+0

@Celeritas Y listo, vea la edición :) – Fluffeh

2

Dado que los resultados son para dos mesas disjuntos, que realmente quieren un sindicato en su lugar:

select id, 'curtains' as source from curtains where color = 'lightyellow' 
    union 
select id, 'carpets' as source from carpets where color = 'lightyellow' 

En cuanto a combinaciones, aprender todos juntos. Son solo pequeñas variaciones el uno del otro.

+0

Es posible que desee incluir una columna de cadena literal en la consulta para mostrar si cada fila de salida está describiendo una identificación de cortina o una identificación de alfombra. –

+0

@FredSobotka buen punto, actualizando la respuesta. –

+0

@TanzeebKhalili ¿qué significa la palabra "disjoint" como en tablas disjuntas? – Celeritas

2

Si desea que el resultado de la casación en dos tipos de tabla, a continuación, intente esto:

select id 
    from curtains 
     ,carpets 
    where curtain.color = carpets.color; 

Esto devolverá id donde curtain.color = carpets.color

+0

pero no solo coincidencia entre dos tablas, el color tiene que ser 'amarillo claro' – Celeritas

+0

@Celeritas que simplemente añada 'AND color = 'amarillo claro'' antes del punto y coma. – bfavaretto

2

Estos tanto de la consulta se dará resultado que desea ....

SELECT Carperts.id 
    FROM Carpets INNER JOIN Curtains ON Carpets.colour = Curtains.colour 
    and colour = 'light yellow'; 


SELECT Carperts.id 
    FROM Carpets INNER JOIN Curtains ON Carpets.colour = Curtains.colour 
    WHERE colour = 'light yellow'; 
Cuestiones relacionadas