2010-05-02 3 views
1

J'ai une base de données sql. Dans cette base de données il y a 3 tables que j'ai besoin d'interroger. La première table a toutes les informations de l'élément appelé item et les deux autres tables a données pour les votes et les commentaires disant userComment et le troisième pour les votes appelé userItemsql question de déclaration. Besoin d'interroger 3 tables en une seule fois!

J'ai actuellement une fonction qui utilise cette requête SQL pour obtenir la dernière plus populaire (en termes de votes et commentaires):

$sql = "SELECT itemID, COUNT(*) AS cnt 
FROM (
     SELECT `itemID` 
     FROM `userItem` 
     WHERE FROM_UNIXTIME(`time`) >= NOW() - INTERVAL 1 DAY 
     UNION ALL 
     SELECT `itemID` 
     FROM `userComment` 
     WHERE FROM_UNIXTIME(`time`) >= NOW() - INTERVAL 1 DAY AND `itemID` > 0 
     ) q 
GROUP BY 
     `itemID` 
ORDER BY 
     cnt DESC"; 

Je sais comment changer cela pour soit par votes seul ou commentaires ....

CEPENDANT - Je dois interroger la base de données pour retourner uniquement la itemID de ceux qui ont des conditions spécifiques dans seulement le item ce tableau sont WHERE categoryID = 'xx' AND typeID = 'xx'

Si le ninja sql pourrait m'aider s'il vous plaît sur celui-ci? Dois-je d'abord retourner les résultats de la requête ci-dessus et le pour chaque dans le tableau récupéré puis vérifier chaque contre la table item et voir si elle correspond aux conditions pour construire un nouveau tableau - ou est-ce exagéré?

Merci, Stefan

Répondre

0

Ce n'est pas clair pour moi exactement comment votre DB est configuré ou si certains de ces attributs sont, mais il pourrait être quelque chose comme:

$sql = "SELECT q.itemID, COUNT(*) AS cnt 
FROM (
     SELECT `itemID` 
     FROM `userItem` 
     WHERE FROM_UNIXTIME(`time`) >= NOW() - INTERVAL 1 DAY 
     UNION ALL 
     SELECT `itemID` 
     FROM `userComment` 
     WHERE FROM_UNIXTIME(`time`) >= NOW() - INTERVAL 1 DAY AND `itemID` > 0 
     ) q inner join item i on q.itemID = i.itemID 
WHERE i.categoryID = 'xx' AND i.typeID = 'xx' 
GROUP BY 
     q.`itemID` 
ORDER BY 
     cnt DESC"; 
+0

Doesnt semblent travailler? De quelles informations supplémentaires avez-vous besoin dont vous n'étiez pas sûr? les attributs tels que categoryID et itemID sont dans la table appelée 'item' où tous les éléments sont réellement stockés –

+0

La jointure interne agit comme un filtre pour seulement les éléments avec des votes ou des commentaires. Changez-le en une jointure à gauche - est-ce que cela aide? –

+0

Retourne: Vous avez une erreur dans votre syntaxe SQL; consultez le manuel qui correspond à votre version du serveur MySQL pour la bonne syntaxe à utiliser près de 'q.itemID = i.itemID WHERE i.categoryID =' 1 'ET i.typeID =' 1 'GROUP BY' à la ligne 10 - SELECT q .itemID, COUNT (*) AS cnt FROM (SELECT 'itemID' FROM' userItem' OERE FROM_UNIXTIME ('time')> = NOW() - INTERVAL 1 DAY UNION TOUT SELECT' itemID' FROM 'userComment' O WH FROM_UNIXTIME (' time ')> = NOW() - INTERVAL 1 DAY ET' itemID'> 0) q élément de jointure gauche i q.itemID = i.itemID O i i.categoryID = '1' ET i.typeID = '1' GROUP BY q. 'itemID' ORDER BY cnt DESC –

0

Je serais enclin à inclure le filtre sur chacune des requêtes. Je devrais vérifier, mais je pense que cela fonctionnerait mieux car moins de lignes sont analysées dans le groupe. Ainsi, je ferais quelque chose comme (ce qui est une supposition car on ne dit pas comment la table item se rapporte aux autres):

$sql = "Select itemID, Count(*) AS cnt 
From (
     Select ui.`itemID` 
     From `userItem` ui 
      Join `item` i 
       On i.itemid = ui.itemid 
     Where From_UnixTime(`time`) >= Now() - Interval 1 Day 
      And i.categoryID = 'xx' 
      And i.typeid = 'xx' 
     Union All 
     Select uc.`itemID` 
     From `userComment` uc 
      Join `item` i 
       On i.itemid= uc.itemid 
     Where From_UnixTime(`time`) >= Now() - Interval 1 Day 
      And uc.itemID > 0 
      And i.categoryID = 'xx' 
      And i.typeid = 'xx' 
     ) q 
Group By `itemID` 
Order By cnt Desc"; 
+0

Obtenir cette réponse, des idées? La colonne 'itemID' dans la liste des champs est ambiguë - SELECT itemID, Count (*) AS cnt FROM (CHOISIR 'itemID' FROM 'userItem' ui JOIN' item' i ON i.itemid = ui.itemid WHERE From_UnixTime ('time') > = Maintenant() - Intervalle 7 Jour ET i.categoryID = 'populaire' UNION ALL SELECT 'itemID' FROM' userComment' uc Rejoindre 'item' i Sur i.itemid = uc.itemid Où From_UnixTime (' time')> = Maintenant() - Intervalle de 7 jours et uc.itemID> 0 Et i.categoryID = 'populaire') q Grouper par 'itemID' Commander par cnt Desc –

+0

@Stefan - Vous devez simplement alias' itemid' qui est dans chacun des clauses de sélection internes. J'ai mis à jour mon message pour illustrer. – Thomas