MySQL: Problemas con JOINs entre versión 4 y 5
11 de Abril de 2008 en Programación, SQL
Lecturas: 2,945
alprazolam pills buy alprazolam without prescription acomplia cheap generic synthroid cheap generic lasix xanax cheap viagra lorazepam generic lowest price synthroid cialis online discount alprazolam prozac pills soma without a prescription order diazepam cheapest doxycycline prices buy tramadol cheap online viagra price of cialis accutane online zithromax purchase lorazepam xanax prices discount clomid prozac online cheapest prozac prices discount prozac buy tramadol online synthroid no prescription levitra sale cialis discount cheap generic alprazolam xanax generic cheapest flagyl prices buy lasix bactrim online stores cheap acomplia tablets zoloft online stores cheapest phentermine acomplia online cheap buy cheap bactrim online viagra cheap zoloft discount flagyl sale generic zithromax cheap doxycycline online generic alprazolam buy cheap diazepam online buy cheap synthroid online propecia online cheap purchase flagyl propecia generic cialis sale cheap lasix tablets levitra for sale discount valium price of accutane cheap phentermine valium pills lorazepam online clomid sale phentermine generic levitra no prescription nexium prices buy generic clomid soma online stores order clomid online pharmacy diazepam plavix generic tramadol online zoloft for sale cheapest lasix order zoloft buy lorazepam cheap buy doxycycline zithromax prescription cheap nexium tablets pharmacy accutane cheapest zithromax buy cheap prozac online lowest price propecia lasix online stores cheapest viagra clomid pharmacy buy flagyl diazepam without a prescription zithromax online cheapest prozac order viagra online alprazolam online stores tramadol cheap alprazolam online prozac generic cheap lorazepam cheap prozac tablets buy alprazolam cheap order cialis online order propecia online cheapest cialis prices diazepam online cheapest phentermine prices pharmacy levitra buy flagyl online cheap generic levitra buy diazepam cheap order plavix soma price of diazepam cheapest bactrim diazepam pharmacy bactrim sale propecia discount pharmacy nexium cheap lasix online xanax where to buy phentermine purchase viagra online lowest price tramadol buy zoloft lowest price zoloft alprazolam pharmacy price of levitra propecia prices cialis without prescription accutane online cheap buy plavix diazepam prescription purchase tramadol online clomid without a prescription zithromax cheap levitra phentermine prices doxycycline generic valium generic xanax discount viagra generic purchase phentermine order viagra cheapest flagyl soma prescription buy acomplia cheap online nexium buy diazepam online prozac online cheap bactrim no prescription clomid generic cheap valium online accutane pharmacy generic lasix buy cheap doxycycline online buy propecia cheapest plavix prices order alprazolam online purchase soma prozac lasix online cheap purchase acomplia cheap viagra online plavix pills valium pharmacy alprazolam for sale where to buy acomplia cheap lorazepam tablets lowest price valium purchase zithromax buy zithromax without prescription order soma doxycycline online cheap plavix discount cheap clomid tablets price of bactrim buy clomid without prescription purchase viagra bactrim pharmacy order zithromax online order synthroid valium sale soma online cheapest zithromax prices buy soma cheap cheapest lorazepam cialis no prescription online diazepam cheapest nexium order bactrim online cheapest clomid buy cheap acomplia buy cialis purchase zithromax online pharmacy lasix order tramadol online buy accutane buy clomid price of zoloft buy prozac without prescription online phentermine cheap doxycycline buy valium without prescription lorazepam discount flagyl purchase zoloft cheap prozac online cheap synthroid online price of prozac zoloft without prescription buy cheap nexium propecia online buy generic phentermine buy generic cialis online synthroid cheap valium tablets cheapest synthroid prices nexium prescription lasix pills alprazolam without prescription online tramadol lowest price cialis buy levitra zithromax online stores acomplia for sale accutane prices price of alprazolam cheap soma online levitra generic discount soma purchase nexium tramadol discount phentermine without prescription purchase bactrim buy cheap accutane online acomplia without a prescription buy generic lasix doxycycline prescription doxycycline prices cheap zoloft tablets online plavix where to buy alprazolam diazepam online stores price of nexium cheap flagyl tablets propecia pills buy generic valium order nexium online generic phentermine cheap valium buy cheap flagyl prozac pharmacy purchase lasix online levitra online buy prozac alprazolam no prescription lasix prescription buy cheap bactrim pharmacy soma lowest price phentermine pharmacy valium where to buy lasix lowest price zithromax viagra sale purchase levitra cheap soma valium for sale purchase doxycycline online price of zithromax discount zoloft accutane without prescription buy cheap valium soma cheap purchase valium cheapest alprazolam levitra prescription buy tramadol without prescription buy generic acomplia purchase flagyl online order lasix valium without prescription flagyl online cheap zoloft online buy generic zoloft buy bactrim without prescription generic clomid cheap synthroid tablets purchase alprazolam bactrim discount cheap generic doxycycline buy zoloft without prescription lowest price soma cheap bactrim online buy viagra online cialis online cheap online zoloft purchase lasix buy acomplia online cheap viagra tablets cheap levitra tablets cheapest clomid prices buy flagyl cheap buy xanax cheapest acomplia buy cheap levitra online synthroid generic propecia without a prescription cheap generic soma xanax online cheap cheap propecia cheapest nexium prices cheapest soma price of doxycycline where to buy levitra lorazepam prescription online acomplia zithromax for sale price of clomid pharmacy doxycycline purchase cialis online order zithromax cheap levitra lorazepam pills tramadol generic buy acomplia cheapest tramadol cheap generic cialis pharmacy propecia acomplia prescription lowest price accutane zoloft cheap plavix tablets zoloft pills cheap flagyl buy plavix without prescription where to buy viagra buy generic prozac cheap diazepam cheapest lorazepam prices discount levitra price of lorazepam clomid online stores phentermine online pharmacy viagra order bactrim viagra without a prescription cheapest synthroid cheap zithromax online purchase cialis propecia prescription online soma buy cheap lasix online accutane cheap price of tramadol diazepam cheap cheap clomid online where to buy prozac buy phentermine online cheapest diazepam purchase phentermine online clomid for sale soma sale generic acomplia levitra online stores cheapest acomplia prices viagra no prescription nexium pills generic plavix buy cheap lorazepam online nexium without prescription propecia for sale cheap generic zoloft doxycycline online buy plavix online doxycycline sale order phentermine lasix online buy cheap cialis online cheap generic diazepam where to buy diazepam price of propecia online cialis flagyl prices buy generic synthroid acomplia online purchase bactrim online cheap xanax pharmacy phentermine discount propecia nexium online phentermine without a prescription cheapest zoloft purchase propecia online buy zoloft online acomplia prices buy generic soma price of plavix buy lasix online buy doxycycline online bactrim cheap pharmacy zoloft price of phentermine prozac without prescription generic nexium buy cheap nexium online tramadol cheap cheap acomplia online cheap xanax tablets phentermine for sale discount lorazepam nexium no prescription alprazolam purchase plavix online flagyl no prescription generic viagra buy cheap diazepam prozac without a prescription discount diazepam buy accutane without prescription buy soma online buy zithromax cheap buy lasix cheap cheapest alprazolam prices clomid without prescription flagyl prescription order prozac cheap nexium cialis cheap generic bactrim buy cheap viagra valium without a prescription valium online cheap order acomplia online levitra zoloft generic lasix without a prescription purchase doxycycline buy viagra bactrim without prescription levitra prices plavix for sale cheap plavix buy cialis online buy prozac online nexium sale where to buy soma nexium without a prescription lasix for sale order tramadol buy plavix cheap buy bactrim online order soma online price of acomplia buy alprazolam prozac prescription lasix without prescription purchase synthroid online buy generic doxycycline lorazepam without a prescription price of flagyl cheap levitra online prozac prices order flagyl online generic zoloft buy nexium online alprazolam prices buy cheap levitra nexium order alprazolam plavix cheap diazepam without prescription buy cheap flagyl online buy generic zithromax online alprazolam price of lasix buy cheap soma xanax prescription zoloft online alprazolam without a prescription order clomid purchase prozac online buy accutane cheap phentermine online cheap doxycycline no prescription plavix without prescription phentermine cheap diazepam for sale zithromax discount buy phentermine cheap synthroid without a prescription valium xanax without prescription discount synthroid phentermine prescription online clomid accutane online online prozac generic diazepam valium no prescription cheapest accutane cheap alprazolam buy cheap zoloft online prozac cheap levitra discount pharmacy flagyl clomid cialis cheap doxycycline without a prescription discount cialis discount viagra soma generic xanax nexium online stores buy soma cheap doxycycline tablets xanax sale nexium pharmacy cheap cialis online cheapest viagra prices bactrim without a prescription lowest price plavix cheap generic tramadol flagyl pills synthroid online cheap tramadol for sale zoloft online cheap cheap diazepam online buy levitra cheap buy generic flagyl buy acomplia without prescription purchase xanax online buy clomid cheap cheapest xanax prices bactrim generic cheap prozac doxycycline without prescription purchase synthroid lowest price flagyl nexium generic buy cheap clomid cialis prescription buy cheap soma online online lasix lorazepam cheap acomplia where to buy nexium where to buy xanax propecia without prescription xanax for sale order valium lowest price xanax order synthroid online buy alprazolam online where to buy synthroid zoloft pharmacy order lorazepam online propecia online stores cheap zithromax doxycycline for sale xanax pharmacy generic flagyl clomid prescription acomplia without prescription buy cheap propecia synthroid sale cheap phentermine tablets buy diazepam plavix pharmacy generic xanax order acomplia online doxycycline cheap buy clomid online soma for sale bactrim discount nexium prozac discount soma without prescription doxycycline pills purchase alprazolam online purchase diazepam bactrim online cheap alprazolam online cheap where to buy plavix plavix online prozac sale bactrim online buy diazepam without prescription zithromax without a prescription price of viagra xanax online soma no prescription cheapest bactrim prices order levitra online buy doxycycline cheap lasix discount prozac no prescription buy lasix without prescription alprazolam prescription flagyl for sale alprazolam sale discount tramadol buy generic alprazolam buy propecia online prozac online stores cheap generic accutane where to buy zoloft purchase diazepam online lowest price bactrim acomplia pharmacy buy cheap zithromax buy synthroid bactrim for sale tramadol no prescription lorazepam without prescription where to buy propecia synthroid for sale cheap cialis tablets cheapest tramadol prices diazepam generic clomid no prescription generic prozac generic tramadol alprazolam discount pharmacy synthroid valium online stores phentermine sale phentermine pharmacy acomplia discount zoloft cheap alprazolam online buy cialis without prescription buy lorazepam online cheapest zoloft prices order xanax lasix sale cheapest xanax buy zithromax order accutane lowest price lorazepam buy cheap prozac where to buy tramadol generic lorazepam plavix online cheap clomid discount online doxycycline online flagyl cheap lorazepam online buy cheap lasix order lorazepam cheap generic clomid cheap lasix online zithromax no prescription buy generic nexium buy generic levitra buy phentermine buy prozac cheap synthroid prescription pharmacy bactrim valium discount pharmacy alprazolam synthroid discount buy levitra online discount plavix cheap generic xanax viagra online online bactrim propecia cheap cheap generic flagyl soma pills accutane generic online lorazepam discount zithromax discount accutane soma prices pharmacy cialis lowest price diazepam cheap generic zithromax synthroid cheap where to buy zithromax buy lorazepam without prescription plavix prescription levitra pills propecia no prescription buy viagra cheap flagyl online stores bactrim prescription pharmacy tramadol acomplia sale order doxycycline cheap propecia online cialis for sale alprazolam generic levitra without prescription diazepam prices synthroid prices cheap zithromax tablets zithromax online cheap xanax no prescription cheap accutane online generic levitra clomid pills diazepam pills order accutane online buy cheap tramadol buy cheap plavix online buy valium buy cheap viagra online buy tramadol discount acomplia buy cheap xanax order levitra synthroid online stores zithromax without prescription acomplia generic plavix lowest price viagra cheap viagra cheap generic valium where to buy cialis levitra cheap diazepam no prescription buy valium cheap tramadol pills buy generic bactrim buy nexium without prescription buy synthroid cheap cheapest levitra buy levitra without prescription zoloft sale order valium online doxycycline pharmacy cheap diazepam tablets buy generic accutane cheapest doxycycline buy viagra without prescription price of soma purchase valium online tramadol pharmacy viagra pharmacy accutane sale buy propecia cheap cheap cialis accutane without a prescription diazepam discount soma discount where to buy accutane cheapest lasix prices lowest price doxycycline online propecia cheap phentermine online zithromax generic soma pharmacy cheapest accutane prices viagra online cheap bactrim prices order propecia propecia sale valium online buy accutane online flagyl pharmacy tramadol prices buy cheap zithromax online cheap zoloft buy cheap zoloft purchase xanax buy generic xanax valium prices purchase propecia viagra without prescription soma online cheap cheap generic phentermine tramadol without a prescription pharmacy zithromax discount doxycycline flagyl generic flagyl without a prescription cheap synthroid buy cheap plavix cheap generic prozac online valium xanax online stores buy generic tramadol buy bactrim cheap plavix sale purchase clomid online lowest price prozac zithromax lasix cheap doxycycline online stores price of synthroid lowest price lasix order plavix online accutane pills purchase plavix purchase lorazepam online buy generic diazepam purchase clomid viagra online stores zithromax pharmacy cheap generic propecia cheapest valium buy nexium cheap lorazepam no prescription levitra pharmacy buy cheap acomplia online cialis prices cheap alprazolam tablets purchase tramadol buy cheap accutane order diazepam online where to buy flagyl zithromax pills nexium cheap order cialis clomid online cheap diazepam discount phentermine buy soma without prescription buy lorazepam levitra without a prescription prozac for sale viagra pills zoloft without a prescription lorazepam for sale cheap accutane tablets generic bactrim lasix prices accutane discount lowest price clomid nexium online cheap accutane online stores flagyl discount clomid cheap cheapest levitra prices diazepam online cheap generic valium propecia pharmacy acomplia online stores cheap xanax online doxycycline lasix no prescription nexium for sale cheap bactrim flagyl without prescription cialis pharmacy zithromax prices cheap clomid accutane for sale buy xanax cheap cheap soma tablets cheap plavix online purchase levitra online where to buy clomid propecia cheap tramadol cheapest diazepam prices price of valium where to buy bactrim generic cialis where to buy lorazepam zoloft prices synthroid pharmacy order nexium buy cheap tramadol online zoloft prescription levitra online cheap pharmacy plavix buy flagyl without prescription cheap generic nexium lorazepam pharmacy synthroid online generic doxycycline cheap generic plavix purchase prozac buy cheap lorazepam accutane prescription cheap propecia tablets clomid prices viagra prescription order prozac online buy generic plavix where to buy valium tramadol online cheap cheapest plavix cheapest soma prices generic propecia plavix prices buy propecia without prescription nexium discount buy cheap propecia online flagyl online cheap order lasix online buy generic viagra lowest price nexium generic accutane alprazolam cheap plavix without a prescription diazepam sale cheap accutane cheap generic viagra buy synthroid online discount bactrim phentermine phentermine online stores pharmacy prozac valium cheap tramadol without prescription cheapest propecia prices synthroid where to buy doxycycline order flagyl flagyl cheap cheap tramadol tablets discount xanax pharmacy acomplia xanax pills synthroid pills cheap generic acomplia pharmacy clomid order doxycycline online buy cheap doxycycline purchase soma online cialis online stores discount flagyl cialis without a prescription buy synthroid without prescription buy cheap alprazolam online buy cheap valium online purchase acomplia online lowest price acomplia viagra discount buy cheap synthroid plavix online stores buy cheap phentermine online cheap tramadol online generic soma purchase nexium online buy phentermine without prescription order xanax online doxycycline discount buy cialis cheap cheap acomplia buy generic propecia lorazepam online cheap purchase accutane buy xanax online zithromax sale cialis generic cheapest cialis tramadol prescription accutane no prescription acomplia pills lowest price levitra buy generic lorazepam purchase accutane online viagra prices cheapest valium prices lorazepam phentermine pills buy cheap xanax online lasix pharmacy online accutane tramadol sale buy xanax without prescription buy cheap alprazolam price of xanax viagra for sale pharmacy xanax order zoloft online buy cheap cialis buy cheap clomid online phentermine discount zoloft no prescription cheap bactrim tablets discount lasix lorazepam sale valium prescription tramadol online stores lorazepam prices cheap nexium online purchase zoloft online lasix generic phentermine no prescription lasix cialis pills plavix no prescription acomplia no prescription lorazepam online stores buy bactrim buy nexium cheap flagyl online buy doxycycline without prescription cheap generic synthroid buy zoloft cheap clomid online pharmacy lorazepam lowest price alprazolam xanax without a prescription buy valium online synthroid without prescription bactrim pills buy cheap phentermine order phentermine online buy zithromax online cheapest propecia cheap generic lorazepam

MySQLEste artículo puede sonar más bién a una llamada desesperada. Llevo unas semanas (por no decir un par de meses) liado con un proyecto que me consume más de lo que quisiera pero por respeto a la empresa no puedo desvelar casi nada. Y para colofón me aparece este problema que me está llevando de cabeza.

Resulta que tengo una query... sencilla en concepto, un par de joins cruzados... La construyo en local contra MySQL 4 y funciona perfectamente... y al subirla al servidor de producción con MySQL 5 simplemente me devuelve 0 rows. Estoy literalmente alucinando.

Explicación del escenario

Se trata de tres tablas con relación N:M, es decir, dos tablas principales y una que las une:

variables
---------
id (pk)
name

var_questions
-------------
id (pk)
id_variable (fk)
id_language (fk)
question

languages
----------
id (pk)
name
enabled

La tabla de variables contiene todas las variables registradas en el programa. La tabla languages contiene todos los idiomas disponibles en el programa. La tabla var_questions relaciona variables con languages y presenta el campo question que viene a ser el texto de la variable en el idioma determinado, es decir, para cada variable e idioma debe haber un texto.

Entonces yo necesito una query que me saque las inconsistencias (no las coincidencias), porque se trata de tablas MyISAM y en el proceso de desarrollo se puede haber creado un idioma sin haber generado ningún texto para él y para todas las variables. Mi query debe encontrar "lo que queda suelto".

La query

Usando la lógica (la mía, claro...) pensé: teniendo la lista de variables y la lista de idiomas, lo que debe presentar inconsistencias es la tabla intermedia. Entonces, podría hacer una query enlazando las variables con var_questions con un left join i la última con languages con un right join, para encontrar los nulls en la tabla intermedia var_questions. Luego le digo en el where que sólo quiero los nulls et violà.

SQL:
SELECT
  VARIABLES.name            AS var_name,
  VARIABLES.id        AS var_id,
  var_questions.question    AS question,
  languages.name            AS lang
FROM
  VARIABLES
    LEFT JOIN var_questions ON VARIABLES.id = var_questions.id_variable
      RIGHT JOIN languages ON var_questions.id_language = languages.id
WHERE
    var_questions.question IS NULL
AND languages.enabled = 1

La ejecuto en MySQL 4 y perfecto. Me saca justamente la información que necesito. Subo la query a producción, con un servidor MySQL 5 y me devuelve (con los mismos datos) 0 rows. Y justo ahí empieza mi odisea.

Investigando

La verdad es que poco más puedo investigar a parte de lo que haríamos todos: Googlear mucho, buscar problemas de compatibilidad, buscar documentación de JOINs, preguntar a cracks en el tema, dejar mensajes en foros, ...

Las versiones con las que juego son, en local, un MySQL 4.1.22-community-nt sobre Windows Vista, y en producción un MySQL 5.0.24a sobre Linux 2.6.9-023stab046.2-enterprise (Red Hat 3.4.5-2).

Durante las pruebas he encontrado una query que parece devolver los mismos resultados, pero no me gusta por el simple hecho que usa una CROSS JOIN que no podría explicar exactamente qué hace, pero parece hacer una producto cartesiano de las tablas enlazadas y no acepta un ON:

SQL:
SELECT
  VARIABLES.name            AS var_name,
  var_questions.question    AS question,
  languages.name            AS lang
FROM
  languages
    CROSS JOIN VARIABLES
      LEFT JOIN var_questions ON var_questions.id_language = languages.id
WHERE
    var_questions.question IS NULL
AND languages.enabled = 1

Cómo probar?

Tengo unos datos preparados por si alguien quiere hacer algunas pruebas (que serán agradecidas profundamente):

SQL:
CREATE TABLE `variables` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(100) collate latin1_spanish_ci NOT NULL DEFAULT '',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci;

CREATE TABLE `languages` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(10) collate latin1_spanish_ci NOT NULL DEFAULT '',
  `enabled` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci;

CREATE TABLE `var_questions` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `id_variable` int(11) UNSIGNED NOT NULL DEFAULT '0',
  `id_language` int(11) UNSIGNED NOT NULL DEFAULT '0',
  `question` text collate latin1_spanish_ci,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=163 DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci;

INSERT INTO `languages` (`id`, `name`, `enabled`) VALUES (2, 'es', 1);
INSERT INTO `languages` (`id`, `name`, `enabled`) VALUES (4, 'ca', 1);
INSERT INTO `languages` (`id`, `name`, `enabled`) VALUES (5, 'en', 0);

INSERT INTO `variables` (`id`, `name`) VALUES (56, 'var_1');
INSERT INTO `variables` (`id`, `name`) VALUES (60, 'var_2');
INSERT INTO `variables` (`id`, `name`) VALUES (61, 'var_3');

INSERT INTO `var_questions` (`id`, `id_variable`, `id_language`, `question`) VALUES (157, 56, 2, 'Variable 1');
INSERT INTO `var_questions` (`id`, `id_variable`, `id_language`, `question`) VALUES (158, 60, 2, 'Variable 2');
INSERT INTO `var_questions` (`id`, `id_variable`, `id_language`, `question`) VALUES (159, 61, 2, 'Variable 3');

El resultado correcto debería ser el siguiente:

var_name var_id question lang
var_1 56 null ca
var_2 60 null ca
var_3 61 null ca

Colofón

Vale. No soy capaz de encontrar el problema. Será un problema de algún bug en la versión que uso para producción? Está mal planteada la query? A alguien se le ocurre algo?

Una cervecita para quien dé con la solución ;)

Salu10

Tags: , ,
 Enviar a Fresqui

Leer los Comentarios

[ # 19625 ] Comment desde franci [11 de Abril de 2008, 04:08]

Usar un valor null provocado por la inexistencia de tuplas en un left join o right join no creo que sea muy aconsejable (excepto si se utiliza desde otra sentencia que usa el resultado como tabla. Desconozco como sería en MySQL pero en derby, SQLServer y varios más podría ser así:

SELECT
V.name var_name,
V.id var_id,
‘null’ question,
L.name lang
FROM
VARIABLES V, languages L
WHERE
L.enabled = 1 and
not exists
(
select *
from
var_questions VQ
where
VQ.id_variable = V.id and
VQ.id_language = L.id and
VQ.question IS not NULL
)

al menos en derby (es lo que tengo en casa) me da el resultado que pides.

Por cierto ¿Me cambias la cervecita por un café o una horchata? :-)

[ # 19626 ] Comment desde Jurguen [11 de Abril de 2008, 04:38]

No es problema de Mysql o del Join, es solo que no vas a poder obtener ese tipo de resultado, realizando left o right join a menos que utilizes cross joins ¿y no veo el problema en usarlo?

Te envio una consulta que retorna el resultado que deseas:

select variables.name, variables.id, NULL as question, languages.name from variables,languages
where languages.id not in (select id_language from var_questions)
and languages.enabled=1

Es obvio que el campo question este en null, pero no se porque deseas mostrarlo.

Espero te sirva, nos leemos.

[ # 19627 ] Comment desde Chema [11 de Abril de 2008, 04:56]

En una mysql 5.0.54 (en linux gentoo con 2.6.23), el resultado que tu comentas resulta igual. A ver si te sirve de algo.

Un saludo,

[ # 19628 ] Comment desde Chema [11 de Abril de 2008, 04:59]

Pero ojo, no me devuelve 0 rows, sino mas bien esto:

var_name var_id question lang
NULL NULL NULL ca

[ # 19629 ] Comment desde Bellz [11 de Abril de 2008, 05:20]

He probado con un MySQL 5.051a y me retorna una fila con las columnas con valor nulo, exceptuando languages.name.

El resultado que esperas

var_name var_id question lang
var_1 56 null ca
var_2 60 null ca
var_3 61 null ca

no se puede dar nunca, al menos en esa forma.

El left join de var_questions retorna las filas coincidentes por identificador de variable y te devolverá las columnas de la selección correctamente. En cuanto aplicas el right join con languages te devolverá el lenguaje para las variables resultado del left join anterior y una fila (solo una) por lenguaje no coincidente y exceptuando los valores de languages el resto de columnas de esa fila tendrán valor nulo, por ejemplo

SELECT *
FROM variables
left JOIN var_questions ON (variables.id = var_questions.id_variable)
right JOIN languages ON (languages.id=var_questions.id_language)

retornará

id|name|id|id_variable|id_language|question|id|name|enabled
56|var_1|157|56|2|Variable 1|2|es|1
60|var_2|158|60|2|Variable 2|2|es|1
61|var_3|159|61|2|Variable 3|2|es|1
\N|\N|\N|\N|\N|\N|4|ca|1
\N|\N|\N|\N|\N|\N|5|en|0

Creo que el problema no es MySQL 5 sino MySQL 4, que no optimiza los resultados de los JOIN y aplica el último join a cada fila de resultado del join anterior, por ejemplo, la misma query anterior en un MySQL 4 produce éste resultado

id|name|id|id_variable|id_language|question|id|name|enabled
56|var_1|157|56|2|Variable 1|2|es|1
60|var_2|158|60|2|Variable 2|2|es|1
61|var_3|159|61|2|Variable 3|2|es|1
56|var_1|\N|\N|\N|\N|4|ca|1
60|var_2|\N|\N|\N|\N|4|ca|1
61|var_3|\N|\N|\N|\N|4|ca|1
56|var_1|\N|\N|\N|\N|5|en|0
60|var_2|\N|\N|\N|\N|5|en|0
61|var_3|\N|\N|\N|\N|5|en|0

Puede que esta query te sirva

SELECT variables.id, variables.name, languages.name FROM variables, var_questions, languages
where not languages.id = var_questions.id_language
and languages.enabled = 1
group by variables.id, languages.id order by variables.id

Un saludo.

[ # 19632 ] Comment desde Patxi Echarte [11 de Abril de 2008, 08:03]

Una forma sencilla de hacerlo es con consultas anidadas:

SELECT v.*, l.name
FROM variables AS v, languages AS l
WHERE l.enabled=1 AND v.id NOT
IN (
SELECT id_variable
FROM var_questions
WHERE id_language = l.id
)

[ # 19633 ] Comment desde Patxi Echarte [11 de Abril de 2008, 08:18]

Otra opción es tal como dices utilizando un join normal:

SELECT v.*, l.name
FROM
variables AS v CROSS JOIN languages AS l
LEFT JOIN var_questions AS vq ON v.id = vq.id_variable
AND vq.id_language=l.id
WHERE l.enabled=1 AND vq.id IS NULL

El cross join tal como dices se corresponde con el producto cartesiano de las tablas, (el join básico) en este caso de languages y variables. Esto produce que se obtengan todas las combinaciones de variables y lenguajes existentes. A partir de esto es suficiente con utilizar un left join para buscar los elementos que falten.

[ # 19636 ] Comment desde Biel Frontera [11 de Abril de 2008, 09:16]

Hola!
A mi me funciona la select en la versión 5.0.30-Debian (después de cambiar VARIABLES por variables).

De todas maneras, podrías plantear la select de otra manera (no sé si es más pesada o no… pero también tiene que funcionar). Puedes hacer una lectura de todas las parejas lenguaje-variable que no encuentre ningún registro en la tabla var_questions (con un count).

Sería:
SELECT
variables.name AS var_name,
languages.name AS lang
FROM languages, variables
WHERE
languages.enabled =1
AND (
SELECT count( 1 )
FROM var_questions
WHERE
var_questions.id_language = languages.id
AND var_questions.id_variable = variables.id
) = 0

[ # 19763 ] Comment desde Xavi [14 de Abril de 2008, 08:43]

@Franci, Jurguen, Patxi y Biel: Se me olvidó de decir que quería no utilizar subquerys… Hace tiempo hicimos unas pruebas con un amigo y descubrimos que la subconsulta se re-ejecuta a cada iteración de la consulta principal, con lo que se vuelve mucho mucho más pesada. De todas formas, gracias ;) Y no es que desee mostrar el campo NULL, es simplemente para ver que realmente es null (mientras desarrollo la query).

@Chema: No entiendo ése resultado… De acuerdo que faltan todas las variables con el lenguage “ca”, pero deberían salir con su nombre… juer

@Bellz: Tienes mi cerveza. ;) Por un lado te diré que mi query si que me funciona en MySQL 4. Entiendo tu explicación y entiendo también que el fallo realmente es de MySQL 4 en aplicar el right join a todos los resultados del left join (aunque podría pensarse en otros casos que éso pudiera ser correcto). He probado tu query en MySQL y no ha funcionado. En cambio, en MySQL 5 ha funcionado de forma esperada y me da los resultados correctos. Hasta me da vergüenza ver lo simple que és, y yo liándome con cross joins… Gracias majo!

@Patxi: gracias por la explicación del CROSS JOIN

A todos, gracias por responder. Da gusto ver que aún hay gente dispuesta a echar una mano.

Salu10!

[ # 19781 ] Comment desde Bellz [14 de Abril de 2008, 02:09]

De nada Xavi ;)

Gracias por la cerve :)

Escribe un Comentario





Estadísticas