PDA

Ver la versión completa : Ayuda con consulta SQL



Estopero
13/02/2009, 13:39
Hola chicos!!

Tengo un problemilla con una consulta SQL que no consigo abordar XDD, tengo experiencia con SQL pero tampoco soy un experto y cierto comportamientos no se porque se dan :S

La consulta coge los ultimos 20 hilos "actualizados" de un foro Simple Machines, lo ordeno descendentemente por orden de actualización, esto lo hace correctamente, y luego me gustaria que me los ordenase en segunda instancia por categoría PERO NO CONSIGO HACERLO, pasa de mi!! es decir, el segundo "requisito" de orden es como si no lo hiciera, si lo quito, la consulta me da el mismo resultado :(, a ver si me ayudais porque no veo el problema

Aquí va la consulta:


"SELECT smf_categories.name AS categorie_name, smf_categories.id_cat,
smf_boards.name AS board_name, smf_messages.subject, smf_topics.num_replies,
smf_members.member_name, smf_topics.id_topic, smf_topics.id_board, smf_topics.id_first_msg,
smf_topics.id_last_msg, smf_topics.id_member_updated, smf_boards.id_board

FROM smf_topics`, `smf_messages`, `smf_members`, `smf_boards`, `smf_categories`

WHERE smf_topics.id_first_msg = smf_messages.id_msg AND
smf_topics.id_member_updated = smf_members.id_member AND
smf_boards.id_board = smf_topics.id_board AND
smf_categories.id_cat = smf_boards.id_cat

ORDER BY smf_topics.id_last_msg DESC, smf_categories.id_cat ASC

LIMIT 20"

Alguna idea? :(, gracias tios!

Malenko
13/02/2009, 13:47
Has probado a cambiar el "order" a esto?


ORDER BY smf_topics.id_last_msg DESC, smf_categories.name ASC


Prueba y dime si es eso lo que quieres :)

Estopero
13/02/2009, 13:56
Has probado a cambiar el "order" a esto?


ORDER BY smf_topics.id_last_msg DESC, smf_categories.name ASC


Prueba y dime si es eso lo que quieres :)

Gracias por el intento! :D

En realidad una ordenación así también me valdría, he probado la consulta con ese ORDER pero me devuelve exactamente lo mismo, osea que ordena por id_last_msg pero el name o el id_cat se lo pasa por el forro!!

No lo entiendo :(

Malenko
13/02/2009, 13:59
Pregunta tonta xD

El resultado sale incorrectamente ordenado por esos campos o tu quieres ordenarlo y no sabes como?

Estopero
13/02/2009, 14:08
Pregunta tonta xD

El resultado sale incorrectamente ordenado por esos campos o tu quieres ordenarlo y no sabes como?

Quiero ordenador por categoria, para que los ultimos 20 post salgan "agrupados" por categorías, igual es que no entiendo el concepto de ORDER BY no se XDDD

El caso es que salen bien los últimos 20 post, pero luego no se ordenan por categoría, salen incorrectamente ordenados, ni por id, ni por name sale ordenado alfabéticamente ni nada :S, salen alternados, únicamente ordenados por la id_last_msg

Malenko
13/02/2009, 14:25
Quiero ordenador por categoria, para que los ultimos 20 post salgan "agrupados" por categorías, igual es que no entiendo el concepto de ORDER BY no se XDDD

El caso es que salen bien los últimos 20 post, pero luego no se ordenan por categoría, salen incorrectamente ordenados, ni por id, ni por name sale ordenado alfabéticamente ni nada :S, salen alternados, únicamente ordenados por la id_last_msg

Entonces esta correcto!

Si pones dos ORDER, el segundo solo lo hara cuando en el primero tengas valores repes.

Ejemplo. Imaginate que tienes los valores:
(letra - color)
C - VERDE
C- AZUL
B - ROJO
A - VERDE

La instruccion ORDER letra ASC, color DESC sacaría:
A - VERDE
B - ROJO
C- VERDE
C- AZUL

Ahora bien, si no hay ninguna "letra" repe, no se aplica el segundo caso de ordenación.

En tu caso, como el primer campo es un id de un mensaje, es imposible que salga repetido y por eso NUNCA se aplica el segundo criterio de ordenación.

Tendrias que hacerlo al revés ;)

Tendrias que poner este order:


ORDER BY smf_categories.id_cat ASC, smf_topics.id_last_msg DESC

< - >
La instrucción entera correcta, CREO que es esta:


"SELECT smf_categories.name AS categorie_name, smf_categories.id_cat,
smf_boards.name AS board_name, smf_messages.subject, smf_topics.num_replies,
smf_members.member_name, smf_topics.id_topic, smf_topics.id_board, smf_topics.id_first_msg,
smf_topics.id_last_msg, smf_topics.id_member_updated, smf_boards.id_board

FROM smf_topics`, `smf_messages`, `smf_members`, `smf_boards`, `smf_categories`

WHERE smf_topics.id_first_msg = smf_messages.id_msg AND
smf_topics.id_member_updated = smf_members.id_member AND
smf_boards.id_board = smf_topics.id_board AND
smf_categories.id_cat = smf_boards.id_cat

AND smf_categories.id_cat IN (SELECT smf_categories.id_cat FROM `smf_categories` ORDER BY smf_categories.id_cat LIMIT 20)

ORDER BY smf_categories.id_cat ASC, smf_topics.id_last_msg DESC
"


No se si será muy optima pero tendria que darte lo que pides :)

Estopero
13/02/2009, 14:28
Entonces esta correcto!

Si pones dos ORDER, el segundo solo lo hara cuando en el primero tengas valores repes.

Ejemplo. Imaginate que tienes los valores:
(letra - color)
C - VERDE
C- AZUL
B - ROJO
A - VERDE

La instruccion ORDER letra ASC, color DESC sacaría:
A - VERDE
B - ROJO
C- VERDE
C- AZUL

Ahora bien, si no hay ninguna "letra" repe, no se aplica el segundo caso de ordenación.

En tu caso, como el primer campo es un id de un mensaje, es imposible que salga repetido y por eso NUNCA se aplica el segundo criterio de ordenación.

Tendrias que hacerlo al revés ;)

Tendrias que poner este order:


ORDER BY smf_categories.id_cat ASC, smf_topics.id_last_msg DESC

Vale lo entendí!!! tienes razón XDDD muchas gracias!! al menos ahora tiene sentido XD

Lo que pasa que lo que me propones al final no me vale, porque entonces no me saca los 20 últimos post actualizados, me saca los 20 primeros resultados de ordenar todos los registros por categoria, y luego el resultado ya si me lo ordena por smf_topics.id_last_msg.

Ahora me acuerdo que una vez para solucionar esto, hacia una consulta por cada categoría y luego las unía con UNION por orden, pero claro, esto era en una página con 3 categorías fijas, no un foro con muchas categorías y que puede cambiar en el tiempo, me gustaría encontrar una manera "definitiva" si existe!! XDD

Muchas gracias por tu tiempo eh Malenko! :D

Malenko
13/02/2009, 14:31
Vale lo entendí!!! tienes razón XDDD muchas gracias!! al menos ahora tiene sentido XD

Lo que pasa que lo que me propones al final no me vale, porque entonces no me saca los 20 últimos post actualizados, me saca los 20 primeros resultados de ordenar todos los registros por categoria, y luego el resultado ya si me lo ordena por smf_topics.id_last_msg.

Ahora me acuerdo que una vez para solucionar esto, hacia una consulta por cada categoría y luego las unía con UNION por orden, pero claro, esto era en una página con 3 categorías fijas, no un foro con muchas categorías y que puede cambiar en el tiempo, me gustaría encontrar una manera "definitiva" si existe!! XDD


Te la he puesto, vuelve a mirarlo xD

Ya se que no te daba los 20 últimos, pero era para que vieses lo del orden ;) Para sacar los 20 últimos has de hacer una subconsulta ya que un LIMIT solo te filtra el primer campo, y tu quieres "contar" los del segundo (el numero de post).


Muchas gracias por tu tiempo eh Malenko! :D
De nada, me estan pagando por estar delante del monitor y pensar, asi que mientras te puedo echar una mano. Visto de esta manera, se podria decir que me están pagando por ayudarte xD

Estopero
13/02/2009, 14:37
Te la he puesto, vuelve a mirarlo xD

Ya se que no te daba los 20 últimos, pero era para que vieses lo del orden ;) Para sacar los 20 últimos has de hacer una subconsulta ya que un LIMIT solo te filtra el primer campo, y tu quieres "contar" los del segundo (el numero de post).


De nada, me estan pagando por estar delante del monitor y pensar, asi que mientras te puedo echar una mano. Visto de esta manera, se podria decir que me están pagando por ayudarte xD

Al terminar de postear vi que habías puesto otra consulta :D

Pues con la nueva consulta me da este error:
#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

:(

No entiendo muy bien el uso de ese IN, me lo tendré que estudiar un poco me parece XDD

Malenko
13/02/2009, 14:48
Prueba esto, pero creo que Mysql no soporta TOP (yo uso mas SQL Server :P)


"SELECT smf_categories.name AS categorie_name, smf_categories.id_cat,
smf_boards.name AS board_name, smf_messages.subject, smf_topics.num_replies,
smf_members.member_name, smf_topics.id_topic, smf_topics.id_board, smf_topics.id_first_msg,
smf_topics.id_last_msg, smf_topics.id_member_updated, smf_boards.id_board

FROM smf_topics`, `smf_messages`, `smf_members`, `smf_boards`, `smf_categories`

WHERE smf_topics.id_first_msg = smf_messages.id_msg AND
smf_topics.id_member_updated = smf_members.id_member AND
smf_boards.id_board = smf_topics.id_board AND
smf_categories.id_cat = smf_boards.id_cat

AND smf_categories.id_cat IN (SELECT TOP 20 smf_categories.id_cat FROM `smf_categories` ORDER BY smf_categories.id_cat)

ORDER BY smf_categories.id_cat ASC, smf_topics.id_last_msg DESC
"

Estopero
13/02/2009, 14:54
Prueba esto, pero creo que Mysql no soporta TOP (yo uso mas SQL Server :P)


"SELECT smf_categories.name AS categorie_name, smf_categories.id_cat,
smf_boards.name AS board_name, smf_messages.subject, smf_topics.num_replies,
smf_members.member_name, smf_topics.id_topic, smf_topics.id_board, smf_topics.id_first_msg,
smf_topics.id_last_msg, smf_topics.id_member_updated, smf_boards.id_board

FROM smf_topics`, `smf_messages`, `smf_members`, `smf_boards`, `smf_categories`

WHERE smf_topics.id_first_msg = smf_messages.id_msg AND
smf_topics.id_member_updated = smf_members.id_member AND
smf_boards.id_board = smf_topics.id_board AND
smf_categories.id_cat = smf_boards.id_cat

AND smf_categories.id_cat IN (SELECT TOP 20 smf_categories.id_cat FROM `smf_categories` ORDER BY smf_categories.id_cat)

ORDER BY smf_categories.id_cat ASC, smf_topics.id_last_msg DESC
"

No acepta TOP no :(

No te preocupes, que estás trabajando y ya me da apuro que sigas perdiendo el tiempo en esto XDD, ya sabiendo que es lo que pasa intentaré investigar un poco :D

Muchísimas gracias tio =)))

civantoz
13/02/2009, 15:46
Si no acepta top será por que estas con MySQL y otro SGBD (El TOP creo que solo chuta en MSSQL Server), prueba a quitar los TOP N de los select y en la consulta que lo necesites poner al final un LIMIT N

Estopero
13/02/2009, 16:06
Si no acepta top será por que estas con MySQL y otro SGBD (El TOP creo que solo chuta en MSSQL Server), prueba a quitar los TOP N de los select y en la consulta que lo necesites poner al final un LIMIT N

Quitando el top/limit de la subconsulta y poniendolo al final me saca una lista de 20 post bien ordenados por orden de posteo y categoria, pero no los últimos 20 post y solo llegan a aparecer 3 de las 5 categorias, porque el LIMIT lo hace sobre la lista entera. No se si me explico XD

Nose que hacer XDD

Juk
13/02/2009, 16:17
De nada, me estan pagando por estar delante del monitor y pensar, asi que mientras te puedo echar una mano. Visto de esta manera, se podria decir que me están pagando por ayudarte xD

Te tienen como a mi, vaya **** mierda de curro estar asi, llevo 2 semanas y estoy asqueado total.

Yo el SQL lo tengo abandonado desde hace 2 años :S. Y eso que sacaba todo con 10 en la asignatura, jejejeje, pero ahora me quedaría casi en blanco.

Suerte con el problemilla

Malenko
13/02/2009, 16:50
Te tienen como a mi, vaya **** mierda de curro estar asi, llevo 2 semanas y estoy asqueado total.

Yo el SQL lo tengo abandonado desde hace 2 años :S. Y eso que sacaba todo con 10 en la asignatura, jejejeje, pero ahora me quedaría casi en blanco.

Suerte con el problemilla

No no, yo es que ahora estoy diseñando como iran las tablas para un nuevo sistema que queremos meter y tengo que hacer un diseño bastante optimo (es un sistema para dar servicio a terceros). Asi que estoy ahora mismo tambien liado con esto de las tablas y demás mandangas.

civantoz, lo del TOP estaba casi seguro que solo era sql server, ya lo hemos dicho antes arriba. Leamonos los hilos Fan Club! xD

Yo lo que haría a unas malas, es pillar los registros y leer solo los 20. Supongo que eso es para implementarlo en un portal con php. Pues haces la query y solo lees 20 registros. De esta manera aunque mysql calcula todo, solo pasa por red 20 registros, con lo que almenos no es tan tan tan ineficiente.