2008-12-11 10 views
1

J'ai une table où je stocke des données de ventes aux clients (sur des périodiques, comme des journaux). Le produit est stocké par problème. ExempleSQL Query Advice - Le plus récent article

 
custid prodid issue qty  datesold 
1  123  2  12  01052008 
2  234  1  5  01022008 
1  123  1  5  01012008 
2  444  2  3  02052008 

Comment puis-je récupérer (ce qui est un moyen plus rapide) la présentation de la dernière édition pour tous les produits, pour un client spécifique? Puis-je avoir des exemples pour SQL Server 2000 et 2005? S'il vous plaît noter, la table est plus de 500k lignes.

Merci

+0

Une clarification, est-ce que la colonne vendue est un type de date dans la base de données? – JohnFx

+0

Qu'entendez-vous par "le dernier numéro"? –

+0

oui, la date vendue –

Répondre

3

En supposant que « dernier » est déterminé par date (plutôt que par numéro d'émission), cette méthode est généralement assez rapide, en supposant des index décents:

SELECT 
    T1.prodid, 
    T1.issue 
FROM 
    Sales T1 
LEFT OUTER JOIN dbo.Sales T2 ON 
    T2.custid = T1.custid AND 
    T2.prodid = T1.prodid AND 
    T2.datesold > T1.datesold 
WHERE 
    T1.custid = @custid AND 
    T2.custid IS NULL 

Manipulation 500k lignes est quelque chose qu'un ordinateur portable peut probablement gérer sans problème, sans parler d'un vrai serveur, donc je rester à l'écart de dénormaliser votre base de données pour la « performance ». N'ajoutez pas de maintenance supplémentaire, d'inexactitude et surtout de maux de tête en suivant un «dernier vendu» ailleurs.

EDIT: J'ai oublié de mentionner ... cela ne gère pas spécifiquement les cas où deux problèmes ont la même date exacte. Vous devrez peut-être le modifier en fonction de vos règles métier pour cette situation.

3

Générique SQL; La syntaxe de SQL Server ne doit pas être très différente:

SELECT prodid, max(issue) FROM sales WHERE custid = ? GROUP BY prodid; 
+0

Il suffit de changer le? au format @CustID et vous l'avez. –

+0

Si elle est trop lente, ajoutez un index sur custid, prodid et issue. Dans cet ordre je pense. – pipTheGeek

0

L'interrogation d'une table historique croissante est beaucoup trop lente! Nous vous suggérons fortement de créer une nouvelle table tblCustomerSalesLatest qui stocke les dernières données d'émission de chaque client. et sélectionnez à partir de là.

+0

Cette "optimisation" entraînera un schéma de base de données qui n'est plus normalisé. L'optimisation prématurée est la racine de tous les maux. Avec des index appropriés, la réponse "max/group by" devrait être correcte. –

+0

Il ressemble à une base de données olap analytique et non transactionnelle oltp, auquel cas il doit être dénormalisé. – dkretz

+0

Par cas d'utilisation! C'est ce que le client a payé. La solution propre n'est pas normalisée à 100% mais rapide et pratique. –

2

Est-ce un nouveau projet? Si oui, je me méfie de la configuration de votre base de données comme celui-ci et lire un peu sur la normalisation, de sorte que vous pourriez vous retrouver avec quelque chose comme ceci:

CustID LastName FirstName 
------ -------- --------- 
1  Woman Test 
2  Man  Test 

ProdID ProdName 
------ -------- 
123 NY Times 
234 Boston Globe 

ProdID IssueID PublishDate 
------ ------- ----------- 
123 1  12/05/2008 
123 2  12/06/2008 

CustID OrderID OrderDate 
------ ------- --------- 
1  1  12/04/2008 

OrderID ProdID IssueID Quantity 
------- ------ ------- -------- 
1  123 1  5 
2  123 2  12 

Je dois connaître votre base de données mieux Trouver un meilleur schéma, mais il semble que vous construisez trop de choses dans une table plate, ce qui causera beaucoup de problèmes sur la route.

+0

Ceci est 95% à mon mon schéma. Votre dernière table est là où j'ai besoin pour obtenir le dernier numéro pour chaque produit, pour un client –

+0

J'apprécierais vos commentaires. –

1

Si vous cherchez la plus récente vente par date peut-être c'est ce que vous avez besoin:

SELECT prodid, issue 
    FROM Sales 
WHERE custid = @custid 
     AND datesold = SELECT MAX(datesold) 
         FROM Sales s 
         WHERE s.prodid = Sales.prodid 
         AND s.issue = Sales.issue 
         AND s.custid = @custid