Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[Pg] Fonction ARRAY -> SETOF

3 réponses
Avatar
Jogo
Salut,

Mon titre est tout sauf clair...

Bon, en simplifiant j'ai deux tables :

Groupes (
nom VARCHAR UNIQUE,
et d'autres champs qui ne m'intéressent pas dans ce cas
)
Selection (
regex VARCHAR,
inclus REGEX,
feed_id FK
)

Mais la première table ne me sert pas à grand chose dans ce cas, car
je fais :

SELECT DISTINCT s.feed_id
FROM Selection s
JOIN Groupes g
ON g.nom LIKE s.regex
WHERE g.nom = ANY (?)
GROUP BY g.nom,s.feed_id
HAVING bool_and(s.inclus)

Le «?», c'est parce que je prépare cette requête et l'execute avec
par exemple '{fr.comp.applications.sgbd,fr.comp.lang.perl}'.

EXPLAIN a l'air de me dire que que cette recherche dans Groupes prend
du temps, trop pour cette requête stratégique. J'aimerais donc beaucoup
faire plutôt quelquechose comme :

SELECT DISTINCT s.feed_id
FROM Selection s
JOIN (
VALUES ('fr.comp.applications.sgbd'),('fr.comp.lang.perl')
) g (nom)
ON g.nom LIKE s.regex
GROUP BY g.nom,s.feed_id
HAVING bool_and(s.inclus)

Sur cet exemple précis, EXPLAIN prétend que ça va 6 fois plus vite.
Le problème c'est que je ne peux plus préparer ma requête et lui passer
une liste.

Je cherche donc une solution miracle, rapide et "préparable". Dans
l'idéal une fonction qui reçoit un tableau de VARCHAR, et renvoie un
SETOF VARCHAR. J'utilise postgreSQL 8.2.6.

--
Le seul problème quand on garde l'esprit ouvert, c'est quon trouve toujours
quelqu'un qui tient absolument à y fourrer tout un tas de choses.
-- T. Pratchett

3 réponses

Avatar
Patrick Mevzek
Le Tue, 22 Jan 2008 22:46:31 +0100, Jogo a écrit:
Mais la première table ne me sert pas à grand chose dans ce cas, car
je fais :

SELECT DISTINCT s.feed_id
FROM Selection s
JOIN Groupes g
ON g.nom LIKE s.regex
WHERE g.nom = ANY (?)
GROUP BY g.nom,s.feed_id
HAVING bool_and(s.inclus)

Le «?», c'est parce que je prépare cette requête et l'execute avec
par exemple '{fr.comp.applications.sgbd,fr.comp.lang.perl}'.



Peut-être une solution low-tech :
WHERE ? LIKE s.regex OR ? LIKE s.regex

A moduler en fonction du nombre d'éléments dans la liste,
du genre en Perl :
$dbh->prepare('SELECT .... WHERE '.join(' OR ',(('? LIKE s.regex') x @v)));
$dbh->execute(@v);


--
Patrick Mevzek . . . . . . . . . . . . . . Dot and Co
<http://www.dotandco.net/> <http://www.dotandco.com/>
Avatar
Jogo
> SELECT DISTINCT s.feed_id
> FROM Selection s
> JOIN Groupes g
> ON g.nom LIKE s.regex
> WHERE g.nom = ANY (?)
> GROUP BY g.nom,s.feed_id
> HAVING bool_and(s.inclus)

Peut-être une solution low-tech :
WHERE ? LIKE s.regex OR ? LIKE s.regex



Non, car je perdrais le GROUP BY g.nom.

Merci quand même, je cherche toujours...

--
On n'éprouve jamais l'amour pour la première fois, on se le rappelle
toujours, prévient Danilo Martuccelli, pour qui le véritable organe de
l'amour n'est ni le coeur, ni le sexe, mais l'imagination.
- Serge Chaumier - La déliaison amoureuse -
Avatar
Jogo
Sur fr.comp.applications.sgbd, Fred Brouard - SQLpro disait :

>>> SELECT DISTINCT s.feed_id
>>> FROM Selection s
>>> JOIN Groupes g
>>> ON g.nom LIKE s.regex
>>> WHERE g.nom = ANY (?)
>>> GROUP BY g.nom,s.feed_id
>>> HAVING bool_and(s.inclus)

"= ANY" n'a aucun intérêt. Faites un IN par exemple. ANY ALL et SOME
n'ont d'intérêt qu'avec une inégalité.



L'intérêt d'ANY est de fonctionner sur des tableaux. Avec IN, je ne
sais pas quoi passer à execute pour qu'une liste de valeurs soit
générée. Si quelqu'un sait comment le faire, ça m'intéresse beaucoup.

D'autre part essayez :
SELECT DISTINCT s.feed_id
FROM Selection s
JOIN Groupes g
ON g.nom LIKE s.regex
WHERE g.nom IN (?)
GROUP BY g.nom,s.feed_id
HAVING COUNT(*) = n

n étant le nombre d'item dans ?



Cette requête ne fait pas ce que je veux. Par exemple si SELECT *
FROM Selection donne :

feed_id regex inclus
27 fr.% t
27 %.test t
72 comp.% t
72 %.test f

Et si je lance une recherche sur 'fr.test', votre requête renverra 72,
et la mienne 27.

Merci beaucoup quand même.

--
Cela nous arrangerait si tu voulais bien pousser jusqu'à un AAD4 : Il y
a actuellement une promo d'enfer si tu commandes tes AAD par 4 et cela
arrangerait tes deux gestionnaires de votes préférés qui sont un peu
charette en ce moment.
-- Christophe Raverdy dans fufe --