Je concevons un panier d'achat. Pour contourner le problème des anciennes factures montrant des prix inexacts après la modification du prix d'un produit, j'ai déplacé le champ de prix de la table des produits en une table de produits de produits composé de 3 champs, PID, date et prix. PID et date forment la clé primaire de la table. Voici un exemple de ce que la table ressemble à: à l'aide de La date et le PID renvoyé étaient exacts. J'ai reçu exactement 1 entrée pour chaque PID unique et la date qui l'a accompagnée était la dernière date de cette PID. Cependant, ce qui est arrivé comme une surprise était le prix renvoyé. Il a renvoyé le prix de la première rangée correspondant au PID, ce qui était dans ce cas 50. P> Après avoir retravaillé ma déclaration, je suis venu avec ceci: p> sélectionnez code> et
groupe par code> pour trouver le dernier prix de chaque produit, je est venu avec: p>
SELECT pp.pid, pp.price, pp.date FROM ProductPrice AS pp
INNER JOIN (
SELECT pid AS lastPid, max(date) AS lastDate FROM ProductPrice GROUP BY pid
) AS m
ON pp.pid = lastPid AND pp.date = lastDate
7 Réponses :
Vous voudrez peut-être essayer ceci:
SELECT pid, price, date FROM ProductPrice GROUP BY pid ORDER BY date DESC
Cela ne fonctionnera pas. Il commande la table résultante par date descendante, pas la table d'origine, le dernier prix ne sera pas sélectionné.
Je pense que vous avez enfreint votre schéma de base de données. P>
Pour contourner le problème des anciennes factures montrant des prix inexacts Après modification du prix d'un produit, j'ai déplacé le champ de prix de la table de produits dans une table de produits de produit composé de 3 champs, PID, date et prix. PID et date forment la clé primaire de la table. P> blockQuote>
Comme vous l'avez souligné, vous devez conserver une histoire de changement de prix. Mais vous pouvez toujours garder le prix actuel dans la table des produits en plus de cette nouvelle table. Cela rendrait votre vie beaucoup plus facile (et vos requêtes plus rapidement). P>
La raison pour laquelle vous obtenez un prix arbitraire est que MySQL ne peut pas savoir quelles colonnes à sélectionner si vous Votre deuxième requête semble ok, mais voici une alternative plus courte: P> groupe par code> quelque chose. Il sait qu'il a besoin un em> prix et a em> date par pid et peut aller chercher la date la plus dernière que vous avez demandée avec
max (date) code> mais choisit de revenir Un prix qui est le plus efficace pour lui de récupérer - vous n'avez pas fourni de fonction globale pour cette colonne (votre première requête n'est pas valide SQL, réellement.)
SELECT pid, price, date
FROM ProductPrice p
WHERE date = (SELECT MAX(date) FROM ProductPrice tmp WHERE tmp.pid = p.pid)
D'autres SGBD se plainent que le prix n'est pas inclus en tant qu'agrégation ou en tant que groupement.
Je dois convenir que cela est beaucoup plus propre.
Voici une autre-personne inefficace - un:
Je pense que la clé ici est simple sondage em> Query - Vous pouvez voir ce que vous voulez, mais les ordinateurs ne sont pas humains et afin de produire le résultat souhaité à partir d'opérations basées sur définies, vous devez être explicite. Dans la deuxième requête. P>
La requête interne identifie le dernier prix pour chaque produit, puis la requête externe vous permet d'obtenir la valeur du dernier prix - c'est à peu près aussi simple que possible. P>
En tant que mis à part, si vous avez un système de facturation, vous devez vraiment stocker le prix du produit (et les taux d'imposition ainsi que les «codes») avec la facture, c'est-à-dire que les tables de facturation doivent contenir tous les besoins financiers nécessaires. informations pour reproduire la facture. En général, vous ne veulent pas em> vouloir compter sur la possibilité de rechercher un prix (ou un taux d'imposition) dans une table mutable, même permettant au système introduit comme ci-dessus. Indépendamment de cela que l'histoire de la tarification a son propre mérite. P>
Vous ne pouvez pas résoudre votre problème avec le groupe par clause, car pour chaque groupe de PID MySQL cherchera simplement la première PID, la date maximale et le premier prix trouvé (ce dont vous avez besoin).
Vous pouvez Utilisez une sous-requête (qui peut être inefficace): p> ou vous pouvez simplement rejoindre la table avec elle-même: p> Jetez un coup d'œil à Cette section < / a> de MySQL DOCS. P> P>
J'ai fait face au même problème dans l'un de mes projets, j'ai utilisé la sous-requête pour aller chercher la date, puis le comparer, mais cela rend le système lent lorsque les données augmentent. Donc, il est préférable de stocker le dernier prix de votre tableau en plus de la nouvelle table que vous avez créée pour conserver l'historique des changements de prix. P>
Vous pouvez toujours utiliser l'une quelconque de la requête PPL suggérée pour obtenir le dernier prix du produit à une date particulière. Mais aussi, vous pouvez ajouter un champ dans la même table est le plus dernier. Donc, pour une date, vous pouvez rendre le drapeau vrai une fois. et vous pouvez toujours trouver le dernier prix du produit pour une date particulière par une simple requête. P>
Plus simple, bien que sur PostgreSQL uniquement: Sélectionnez Distinct sur (PID) PID, date, prix de Productprice Commander par pid, date de descendance