Comunidad de diseño web y desarrollo en internet online

consulta avanzada sql (join?)

Citar            
MensajeEscrito el 11 Abr 2006 03:03 am
alo

bien, tengo un proyecto en el cual se sucitó un problema que no había previsto. la cosa es simple; hay dos tablas (más abajo están), una tiene el identificador de un dato y el dato en sí; la otra es la de los votos y tiene el identificador hacia el dato de la primera tabla y el voto de la persona que lo hizo (también tiene la fecha, pero esto no importa)
la estructura es así:

Código :

  Tabla Facts
id_fact | dato
--------|------------
  001   | bla bla bla
  002   | dla dla dla
  003   | lorem ipsum

  Tabla Votos
voto_de | voto_idfact
--------|-----------
 user1  | 001
 user1  | 002

lo que necesito es una consulta que me devuelva los registros que aún NO han sido votados por la persona (en este caso, el 003), ya que lo tenía en forma aleatoria pero cuando ya son muchos registros (digamos, 50) y la persona ha votado una buena parte (digamos, 48), los que aún no han sido votados tardarán mucho en aparecer si sólo se le dejara a la suerte.

más o menos necesito algo así: (esto es un subquery pero por alguna extraña razón siempre me da error de sintaxis)

Código :

SELECT * FROM tabl_facts WHERE id_fact NOT IN (SELECT voto_idfact FROM tabl_votos WHERE voto_de = 'user1')


un poco de luz?

gracias

Por fael

BOFH

2443 de clabLevel

3 tutoriales
2 articulos

 

firefox
Citar            
MensajeEscrito el 11 Abr 2006 03:55 am
Prueba con esto

Código :

SELECT * FROM Facts INNER JOIN Votos ON id_fact<> voto_idfact


saludos

Por Maikel

BOFH

5575 de clabLevel

22 tutoriales
5 articulos

Genero:Masculino   Team Cristalab

Claber de baja indefinida

firefox
Citar            
MensajeEscrito el 11 Abr 2006 04:19 am
Maikel eso regresaría todos los registros diferentes, sería una union del tipo.

001 - 002
001 - 003
002 - 001
002 - 003


fael cuando requieres saber los registros que no estan en otra tabla puedes hacer esto:

Código :

SELECT * FROM Facts INNER JOIN Votos ON id_fact= voto_idfact WHERE voto_idfact is null


Saludos :wink:

Por Dano

BOFH

4273 de clabLevel

14 tutoriales
4 articulos
10 ejemplos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Lugar estratégico para vigilarte

clabbrowser
Citar            
MensajeEscrito el 11 Abr 2006 04:49 am
bueno aqui vuelvo yo, probe la dos consultas la mia y la de Dano y ninguna funciono :lol: . esta si la probe :P

Código :

$sql = "SELECT * FROM facts WHERE NOT id_fact IN ( SELECT voto_idfact FROM votes)";


saludos

Por Maikel

BOFH

5575 de clabLevel

22 tutoriales
5 articulos

Genero:Masculino   Team Cristalab

Claber de baja indefinida

firefox
Citar            
MensajeEscrito el 11 Abr 2006 05:05 am
Maikel me da gusto tu interés en el tema. :wink: En estos casos la lógica recomendada es como yo la planteo, la segunda opción que haces, hace una búsqueda anidada, sabes lo que es eso en una base de datos de verdad?

Pero gracias por el tip, el único detalle que se me fué(y es que no tenía mysql abierto, y me hiciste abrirlo ¬¬) es el LEFT, es una intersección lo que nos interesa.


Código :

SELECT *
FROM Facts
LEFT JOIN Votos ON id_fact = voto_idfact
WHERE voto_idfact IS NULL
LIMIT 0 , 30



Saludos :wink:

Por Dano

BOFH

4273 de clabLevel

14 tutoriales
4 articulos
10 ejemplos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Lugar estratégico para vigilarte

clabbrowser
Citar            
MensajeEscrito el 11 Abr 2006 05:44 am

Dano escribió:

Maikel me da gusto tu interés en el tema.


no te creas, no me iba a quedar con los brazos cruzados ^^

Dano escribió:

y es que no tenía mysql abierto, y me hiciste abrirlo mmmm


jaaaa :lol:


bueno lo que decia era esto:
esta con INNER JOIN NO funciona

Código :

SELECT * FROM facts INNER JOIN votes ON facts.id = votes.idfacts WHERE votes.idfacts IS NULL


con LEFT JOIN SI funciona:

Código :

 SELECT * FROM facts LEFT JOIN votes ON facts.id = votes.idfacts WHERE votes.idfacts IS NULL


solo cambia eso, mas nada :P

saludos

Por Maikel

BOFH

5575 de clabLevel

22 tutoriales
5 articulos

Genero:Masculino   Team Cristalab

Claber de baja indefinida

firefox
Citar            
MensajeEscrito el 11 Abr 2006 05:51 am
por alguna extraña razón, Maikel, no puedo hacer subqueries, pero seguro por ahí iba la solución jeje

Dano, whoa.. maestrazo, muchas gracias, el query funciona de maravilla, sólo que hay un pequeño detalle (y, bueno... no me gustaría colgarme tanto de esto).
hay varios usuarios, es decir, el query va directamente a donde no hay registros, pero esto debe estar en función del usuario. estos últimos minutos me he roto la cabeza y nada; lo que he intentado es lo siguiente:

Código :

SELECT * FROM Facts LEFT JOIN Votos ON id_fact = voto_idfact WHERE voto_idfact IS NULL AND Votos.voto_de = 'user1'

pero no devuelve ningún registro

y lo otro es para hacerlo más l33t, al query pasado si no encuentra resultados, hago otro query

Código :

$q = query("SELECT * FROM Facts LEFT JOIN Votos ON id_fact = voto_idfact WHERE voto_idfact IS NULL AND Votos.voto_de = 'user1'");
if(!mysql_num_rows($q)){
   $q = query("SELECT * FROM Facts WHERE 1 ORDER BY RAND() LIMIT 1");   
}

sólo por curiosidad —y si no es muy jodido—, cómo se haría esto en un solo query?

bien, gracias bro, y sorry por colgarme tanto

Por fael

BOFH

2443 de clabLevel

3 tutoriales
2 articulos

 

firefox
Citar            
MensajeEscrito el 11 Abr 2006 05:52 am
bueno lo que decia era esto:
esta con INNER JOIN NO funciona


con LEFT JOIN SI funciona:

Maikel tu no dijiste eso, yo dije eso, tu sugeriste la consulta anidada. :wink:

Por Dano

BOFH

4273 de clabLevel

14 tutoriales
4 articulos
10 ejemplos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Lugar estratégico para vigilarte

clabbrowser
Citar            
MensajeEscrito el 11 Abr 2006 06:01 am
*sigh* (qué feo es cuando no sabes de qué hablan)

Por fael

BOFH

2443 de clabLevel

3 tutoriales
2 articulos

 

firefox
Citar            
MensajeEscrito el 11 Abr 2006 06:09 am

Código :

SELECT *
FROM Facts
LEFT JOIN Votos ON ( id_fact = voto_idfact
AND Votos.voto_de = 'user1' )
WHERE voto_idfact IS NULL
LIMIT 0 , 30

Básicamente la unión la haces diciendo que usuario quieres.

Saludos :wink:

Por Dano

BOFH

4273 de clabLevel

14 tutoriales
4 articulos
10 ejemplos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Lugar estratégico para vigilarte

clabbrowser
Citar            
MensajeEscrito el 11 Abr 2006 06:45 am
esa no la había visto, pensé que el problema estaba después del WHERE
muchas gracias Dano! ya quedó como debería
http://www.therror.com/losalmada/top.php
un saludo

Por fael

BOFH

2443 de clabLevel

3 tutoriales
2 articulos

 

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.