Jointure et limitations des rélustats (LIMIT)

ViPHP
ViPHP | 3607 Messages

03 oct. 2008, 09:56

Bonjour à tous,
Je viens vers vous afin de débrouiller un petit problème que j'ai actuellement....
Je vais essayer de traiter le cas de manière abstraite, et si besoin on précisera avec mon cas à moi ;)
Alors prenons les tables suivantes:

Code : Tout sélectionner

tableA ------------- id_tableA auto_increment tableB ------------- id_tableB auto_increment id_tableA
Donc voilà nos deux tables, qui seront liées par une structure 1:n (plusieurs enregistrements de tableB peuvent avoir le même id_tableA)
Voilà ce que j'aimerais faire, limiter ma requête aux dix premiers enregistrements de tableA, sachant qu'une jointure avec un LIMIT 0,10, me donnera au mieux 10 enregistrements, mais peut-être un seul...
Voilà si y a des façon de faire ça, je suis preneur ;)
La seule manière à laquelle j'avais penser, c'était de faire une sous-requête jointe, dans laquelle je mettais une clause DISTINCT sur l'id_tableA, et le limit dans cette dernière...

EDIT: pour ma dernière idée... ça ne fonctionne pas...:
#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
Voilà comme ça c'est réglé, j'ai plus d'idée....



EDIT2:
J'ai beau cherché partout, je vois rien qui m'aille (comme lamoutarde...)
La seule solution qui serait à envisager, se serait de faire une table ou je stockerais l'ordre de mes identifiants évènement, et je rajouterais une jointure sur cette table avec une clause WHERE et un BETWEEN
(je m'explique mal, alros regardez là: http://www.nexen.net/index2.php?option= ... 1&id=17611)
Bref c'est une solution envisageable, mais assez difficile à mettre en place, il faut faire une reactualisation régulière de la table (donc un cron, vu la longueur du traitement...)

D'autres idées?

ViPHP
ViPHP | 3607 Messages

05 oct. 2008, 15:55

Bon alors me revoilà avec des nouvelles du front!!
J'ai implémenté la solution de la table intermédiaire, afin de limiter les résultats grace à un BETWEEN...
voici ce que donne mes tables, si ça interesse quequ'un:
--
-- Structure de la table `dates`
--

CREATE TABLE IF NOT EXISTS `dates` (
`id_date` int(10) unsigned NOT NULL auto_increment,
`id_evenement` int(10) unsigned NOT NULL,
`date_debut` datetime NOT NULL,
`date_fin` datetime NOT NULL,
PRIMARY KEY (`id_date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=41 ;

--
-- Contenu de la table `dates`
--

INSERT INTO `dates` (`id_date`, `id_evenement`, `date_debut`, `date_fin`) VALUES
(32, 38, '2000-11-13 20:30:00', '0000-00-00 00:00:00'),
(31, 37, '2005-12-23 00:00:00', '2006-01-10 00:00:00'),
(30, 36, '2006-12-12 00:00:00', '2006-12-14 00:00:00'),
(27, 33, '2008-09-23 08:30:00', '0000-00-00 00:00:00'),
(21, 29, '2008-12-29 00:00:00', '0000-00-00 00:00:00'),
(26, 32, '2008-11-11 08:30:00', '0000-00-00 00:00:00'),
(28, 34, '2008-12-23 20:30:00', '0000-00-00 00:00:00'),
(33, 39, '2005-10-12 20:30:00', '0000-00-00 00:00:00'),
(29, 35, '2007-12-23 20:30:00', '0000-00-00 00:00:00'),
(10, 22, '2008-12-20 20:30:00', '0000-00-00 00:00:00'),
(11, 24, '2008-11-12 00:00:00', '2008-12-19 00:00:00'),
(25, 31, '1988-06-11 00:00:00', '0000-00-00 00:00:00'),
(24, 31, '1987-06-11 00:00:00', '0000-00-00 00:00:00'),
(20, 29, '2008-12-27 00:00:00', '0000-00-00 00:00:00'),
(34, 40, '2007-12-23 20:30:00', '0000-00-00 00:00:00'),
(35, 41, '2007-12-23 20:30:00', '0000-00-00 00:00:00'),
(36, 42, '2000-02-11 00:00:00', '0000-00-00 00:00:00'),
(37, 42, '2000-02-13 00:00:00', '0000-00-00 00:00:00'),
(38, 42, '2000-02-14 00:00:00', '0000-00-00 00:00:00'),
(39, 42, '2000-02-17 00:00:00', '0000-00-00 00:00:00'),
(40, 42, '2000-02-19 00:00:00', '0000-00-00 00:00:00');

-- --------------------------------------------------------

--
-- Structure de la table `evenements`
--

CREATE TABLE IF NOT EXISTS `evenements` (
`id_evenement` int(11) NOT NULL auto_increment,
`description` varchar(200) collate utf8_bin NOT NULL,
`codepostal` char(5) collate utf8_bin NOT NULL,
`ville` varchar(70) collate utf8_bin NOT NULL,
PRIMARY KEY (`id_evenement`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=43 ;

--
-- Contenu de la table `evenements`
--

INSERT INTO `evenements` (`id_evenement`, `description`, `codepostal`, `ville`) VALUES
(33, 'essai avec accents heiné? c''est cool les accents hôhô encore ë', '38', 'gre'),
(29, 'ça marche?\r\n', '38', 'grenoble'),
(31, 'naissance et 1 an', '26', 'romans'),
(36, 'iuog', '12', 'oh'),
(22, 'test2', '38000', 'grenoble'),
(35, 'test', '38', 'gre'),
(24, 'essai plage2', '38000', 'grenoble'),
(32, 'test2\r\n', '38', 'beaurepaire'),
(34, 'hioihazidohazidoazhf azfoihza fia', '38', 'içi'),
(37, 'iugezf', '13', 'iug'),
(38, 'oiuhaz', '14', 'oih'),
(39, 'oihjuzef', '15', 'oih'),
(40, 'oiufhez', '34', 'oih'),
(41, 'oiufhez', '34', 'oih'),
(42, 'zegfoiuh', '14', 'oihj');

-- --------------------------------------------------------

--
-- Structure de la table `limit_events`
--

CREATE TABLE IF NOT EXISTS `limit_events` (
`row` int(10) unsigned NOT NULL auto_increment,
`id` int(10) unsigned NOT NULL,
PRIMARY KEY (`row`),
UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=11 ;

--
-- Contenu de la table `limit_events`
--

INSERT INTO `limit_events` (`row`, `id`) VALUES
(1, 33),
(2, 35),
(3, 40),
(4, 41),
(5, 36),
(6, 37),
(7, 39),
(8, 38),
(9, 42),
(10, 31);
Et voici ma requête repoussante ;) :

Code : Tout sélectionner

SELECT e.id_evenement AS id, e.description AS descri, e.ville AS ville, e.codepostal AS cp, d.date_debut AS dated, d.date_fin AS datef FROM evenements AS e JOIN dates AS d ON d.id_evenement = e.id_evenement JOIN limit_events AS l ON l.id = e.id_evenement AND l.row BETWEEN 1 AND 10 WHERE d.id_evenement NOT IN ( SELECT e.id_evenement FROM evenements AS e JOIN dates AS d ON d.id_evenement = e.id_evenement WHERE d.date_fin >= Now( ) OR d.date_debut >= Now( ) ) ORDER BY d.date_debut ASC
Pour finir voici la requête de mise à jour de la table de navigation:

Code : Tout sélectionner

INSERT INTO limit_events( SELECT DISTINCT 0 , e.id_evenement AS id FROM evenements AS e JOIN dates AS d ON d.id_evenement = e.id_evenement WHERE d.id_evenement NOT IN ( SELECT e.id_evenement FROM evenements AS e JOIN dates AS d ON d.id_evenement = e.id_evenement WHERE d.date_fin >= Now( ) OR d.date_debut >= Now( ) ) ORDER BY d.date_debut DESC )
Je sais pas si ça servira à quelqu'un...?


La seule question que je me pose encore, c'est la requête de mise à jour, qui risque de mettre de plus en plus de temps au fur et à mesure que la base se remplie...
Je vous tiendrais au courant :p

Je suis toujorus preneur pour d'autres solutions hein? si jamais ;)
Merci encore!