6
votes

Un meilleur moyen de subquierer

J'ai un dB où l'article code> code> a une relation de plusieurs à plusieurs (via article_rel code>) et articles code> ont Types Code>. Les parents ont un type de 1234, tandis que les enfants peuvent être l'un des types de plusieurs types.

J'essaie de trouver ces parents qui ne sont pas des enfants; Ou, s'ils ont des enfants, l'article de l'enfant le plus récent n'est pas d'un certain ensemble de types. P>

Ce qui suit fonctionne raisonnablement pour la deuxième partie, mais ne répond pas à la première partie. Chaque tentative que j'ai faite pour retirer la sous-requête afin que je puisse faire référence à la valeur qu'il renvoie (à ajouter "ou est null") a échoué. Je me demande également en général s'il y a une meilleure façon d'écrire quelque chose comme celui-ci. P>

SELECT 
 CONCAT('http://www.sitename.com/', n.id, '.html') as URL,
 n.added,
 u.email,
 n.body
 #c.body
 FROM
     warehouse.article n 
 inner join site.user u on n.user_id = u.id
 inner join warehouse.article_param np on np.id = n.id and np.param_name = 'ready' and np.param_value = 'true'
 where
     n.type_id = 1234 
 and
     (select 
           c.type_id 
      from 
           warehouse.article c, 
           warehouse.article_rel r
      where
           r.child_nid = c.id
           and r.parent_nid = n.id
      order by 
           c.added desc 
      limit 1)
      not in (2245,5443)
 order by 
      n.updated desc


0 commentaires

3 Réponses :


0
votes
SELECT 
n.added,
CONCAT('http://www.sitename.com/', n.id, '.html') as URL,
u.email,
n.body
#c.body
FROM
    warehouse.article n 
inner join site.user u on n.user_id = u.id
inner join warehouse.article_param np on np.id = n.id and np.param_name = 'ready' and np.param_value = 'true'
left join 
     (
           select r.parent_nid, c.type_id 
           from warehouse.article c
           left join warehouse.article_rel r on r.child_nid = c.id and r.parent_nid = n.id     
           order by c.added desc 
           limit 1
      ) child_type
      on child_parent_nid = n.id
where
    n.type_id = 1234 and (child_type.type_id not in (2245,5443) or child_type.type_id is null)
order by 
    n.updated desc
Only test in my mind, not sure it's 100% correct or not. Any correction is very welcome. :)

0 commentaires

0
votes

Première requête obtiendra les parents qui n'ont pas d'enfants alors que la deuxième requête obtiendra le parent dont l'article de l'enfant le plus récent n'est pas un certain ensemble de types. L'Union vous fournira elle-même le jeu de résultats distincts.

Il y a tellement de sélection imbriquées, mais ne vous inquiétez pas, tous appliquent des filtres sur votre ensemble de résultats principaux déjà chargés afin qu'il ne effectue pas de performance, vous pouvez le tester lors de l'exécution de l'exécution. Query sur la console DB. P>

SELECT
 CONCAT('http://www.sitename.com/', n.id, '.html') AS URL,
 n.added,
 u.email,
 n.body
 FROM
 warehouse.article n
 JOIN site.user u ON n.user_id = u.id
 JOIN warehouse.article_param np ON np.id = n.id AND np.param_name = 'ready' AND <br/> np.param_value = 'true'
 LEFT JOIN warehouse.article_rel r ON r.parent_nid = n.id
 WHERE
 n.type_id = 1234  AND r.id IS NULL

 UNION

 SELECT URL,added,email,body FROM
 (SELECT * FROM
(SELECT

 CONCAT('http://www.sitename.com/', n.id, '.html') AS URL,
 n.added,
 u.email,
 n.body,
 nr.type_id
 FROM
 warehouse.article n
 JOIN site.user u ON n.user_id = u.id
 JOIN warehouse.article_param np ON np.id = n.id AND np.param_name = 'ready' AND <br/> np.param_value = 'true'
 JOIN warehouse.article_rel r ON r.parent_nid = n.id
 JOIN warehouse.article nr ON r.child_nid=nr.id
 WHERE
 n.type_id = 1234
 ORDER BY n.id DESC
 ) AS tbl1
GROUP BY id
Where  type_id NOT IN (2245,5443)


0 commentaires

1
votes

Vous devriez pouvoir utiliser Max (ajouté) pour trouver uniquement les enfants les plus nouveaux. La table dérivée x trouve la dernière date de votre enfant pour le parent n.Id (voir Ceci si cette partie n'a pas de sens pour vous). Ensuite, t trouve les données sur ce dernier enfant ajouté. J'ai utilisé la jointure gauche pour obtenir le dernier enfant de N.Id, car s'il n'ya pas d'enfant, il laissera une null dans la place de l'enfant, vous donnant tous des articles qui n'ont pas d'enfants.

left join (SELECT c.type_id, c.id, c.added, r.parent_nid
           FROM warehouse.article c
           INNER JOIN warehouse.article_rel r on c.id = r.child_nid)
           as t on t.parent_nid = n.id and t.added = x.latest


0 commentaires