3 votes

Sélectionner à partir des tableaux d'intersections/jonctions

Souvent, le fait de trouver le bon article et de le lire sur StackOverflow m'a aidé. beaucoup de choses dont je ne savais pas quoi faire, mais pour la première fois, je pense que je dois en écrire un. J'ai cherché la bonne réponse à cette question mais je n'ai pas réussi à en trouver une.

Le problème est que j'ai créé deux tables et une table d'intersection pour les relier.

L'idée sous-jacente est si simple (je suis presque gêné de ne pas pouvoir la résoudre).

Un article du BBS PEUT avoir QUELQUES fichiers attachés. Cela signifie qu'un article peut avoir une pièce jointe ou non. Un article peut avoir plusieurs pièces jointes.

Ce que j'ai essayé de faire, c'est

obtenir la liste des articles avec toutes les informations sur ses pièces jointes mais sans les lignes en double.

Ok... J'ai essayé de mettre en place la DDL mais je n'ai pas pu la formater correctement...

create table article(
id PK
some other stuff...
)

create table attachment(
id PK
physical_file_name 
etc...
)

et voici l'intersection

create table article_attachment(
id PK(synthetic)
article_id FK
attachment_ID FK
)

Je veux sélectionner tous les articles, qu'ils aient ou non des pièces jointes. mais si un article a plusieurs pièces jointes, je n'ai besoin que d'une seule d'entre elles. (peu importe laquelle).

Oui, cela semble stupide, mais il n'y a pas de DBA ou de développeur SQL ici, alors je dois faire tout ce qui est nécessaire. choses... C'est un peu le bordel, mais je fais de mon mieux.

Des idées judicieuses ?

Merci d'avance

-p.s. - J'ai essayé quelque chose comme...

with refined_table as(

  select file_id, row_number() over(partition by id order by id desc) as seq
  from consumer_file

)
select * 
from consumer_info ci 
left outer join consumer_file cf on cf.consumer_id = ci.id
left outer join refined_table rt on rt.file_id = cf.file_id
where rt.seq =1

mais je ne comprends pas vraiment comment cela fonctionne.

UPDATE

Voici ce que j'ai essayé au début. Cela me donne toujours ORA-00979:pas d'expression GROUP BY J'ai cherché la solution pendant longtemps. Quelques personnes ont suggéré d'utiliser fonction d'agrégation ou "Hint" (si c'est ce que c'est...)

  with refined_table as(

      select file_id, row_number() over(partition by id order by id desc) as seq
      from consumer_file

    )

Je veux dire ceci

Hmm, des idées ?

Merci beaucoup à vous tous : )

SELECT 
    CI.id as article_id, 
    DF.id as attachment_id,  
    DF.PHYSICAL_NAME as file_name 
FROM 
    CONSUMER_INFO CI
LEFT OUTER JOIN 
    CONSUMER_FILE CF ON CF.CONSUMER_ID = CI.ID
LEFT OUTER JOIN 
    DEFAULT_FILE DF ON CF.FILE_ID = DF.id
GROUP BY 
   CI.ID

5voto

Ozair Kafray Points 7445

S'il s'agit uniquement d'une relation 1->N entre l'article et la pièce jointe, vous pouvez modifier l'interface de l'article. pièce jointe comme suit :

create table attachment(
   id PK
   article_id FK 
   physical_file_name 
   etc...
)

Vous n'avez besoin d'une table d'intersection distincte que s'il existe une relation N->N entre les articles et les pièces jointes.

MISE À JOUR : Cependant, si vous devez conserver la relation N<->N (comme mentionné dans votre commentaire), vous pouvez utiliser la clause GROUP BY pour GROUPER les résultats par article_id, par exemple :

SELECT 
    article.id as article_id, 
    attachment.id as attachment_id,  
    attachment.physical_file_name as file_name 
FROM 
    article 
LEFT OUTER JOIN 
    article_attachment ON article_id = article.id 
LEFT OUTER JOIN 
    attachment ON attachment_id = attachment.id
GROUP BY 
    article_id

0voto

Bob Jarvis Points 14906

Je pense que les définitions de vos tables sont bonnes. L'obligation de ne sélectionner qu'une seule des pièces jointes rend les choses un peu plus complexes, mais puisque vous ne vous souciez pas de savoir laquelle vous obtenez, je pense que ce qui suit devrait fonctionner :

SELECT *
  FROM ARTICLE a
  LEFT OUTER JOIN (SELECT ARTICLE_ID, MIN(ATTACHMENT_ID) AS ATTACHMENT_ID
                     FROM ARTICLE_ATTACHMENT
                     GROUP BY ARTICLE_ID) aa
    ON (aa.ARTICLE_ID = a.ID)
  LEFT OUTER JOIN ATTACHMENT t
    ON (t.ID = aa.ATTACHMENT_ID)

Partagez et appréciez.

0voto

Iľja Points 483

Si vous ne vous souciez pas de savoir quelles pièces jointes vous chargez, alors c'est ce que vous recherchez :

select
  art.article_id, art.article_stuff,
  att.attachment_id, att.attachment_stuff
from
  article art,
  article_attachment aat,
  attachment att
where
  art.article_id = &article_id
  and aat.article_id = art.article_id
  and att.attachment_id = aat.attachment_id
  and rownum < 2;

Le site rownum < 2 s'assurera que vous ne sélectionnez que la première ligne de toutes les article-article_attachment-attachment combinaisons.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X