Table des utilisateurs:
user_id product_id 1 2 1 4 1 5 2 4 2 5 2 7 3 1 3 5 3 4 3 2 4 1
5 Réponses :
Une option est d'utiliser une jointure auto: L'idée ici est d'essayer de faire correspondre à chacun des enregistrements d'un utilisateur donné à des enregistrements d'un utilisateur différent, mais d'avoir le même produit. L'étape d'agrégation puis vérifie si un utilisateur donné a toujours au moins deux produits après la jointure intérieure, ce qui implique qu'en fait, il a au moins deux produits en commun avec un autre utilisateur. P> Les utilisateurs correspondants ici sont: John, Mark et Scott P> P> Demo H2>
P>
Il faut trop de temps sur une grande table. J'ai des index sur tous les champs. Y a-t-il une autre façon de l'écrire?
J'ai des index sur tous les champs Code> ... mais cela ne signifie pas que les indices sont optimaux, voire que Postgres utilise l'un d'entre eux. Vous devriez éditer votre question et nous dire quels indices vous avez.
Un index sur (produit_id, user_id) code> sur le tableau user_products code> peut aider, en supposant que Postgres choisit de l'utiliser. Les requêtes d'agrégation ont tendance à prendre des ressources. Attendez-vous donc un peu de temps pour la conduire pour une très grande table.
J'ai dit ça tort. Aucun index sur tous les champs, mais index requis. J'ai une requête analysée avec expliquer. Il y a environ 100 milliers d'enregistrements dans la table des utilisateurs. Et 600 milliers de produits. J'ai abandonné la requête, parce que ça a pris trop de temps
mais index requis code> ... Quels index i>? Pouvez-vous nous montrer?
J'ai des utilisateurs.user_id comme clé primaire. Et index sur (product_id, user_id)
Ensuite, je n'ai aucune autre idée sur la manière d'améliorer la performance. Vous voudrez peut-être rechercher des magasins de données alternatifs, tels que GraphQL, conçu pour fonctionner avec les réseaux / relations telles que vos données.
Un auto rejoindre est la bonne approche, mais je pense que la bonne logique est la suivante: Si vous souhaitez la liste des produits, vous pouvez inclure array_agg (distinct1.product_id ) code>. p> p>
Vous pouvez également essayer aussi:
select distinct b.user_id from #UserProduct b join ( select count(1) cnt,product_id from #UserProduct group by product_id having count(1) = 3) c on b.product_id=c.product_id
Vous pouvez trouver paires i> d'utilisateurs qui partagent au moins 2 produits. Est-ce que c'est ce que tu veux?