2009-11-17 3 views
2

J'ai une table (offre) avec trois colonnes, id, product_id et le prix. Je voulais déclencher une requête SQL qui retournera le nombre d'offres entre une fourchette de prix. gamme devrait être comme 0-1, 1-2, 2-3, etc.Requête SQL pour obtenir toutes les données dans la plage spécifique

price_lower price_upper number_of_offers 
------------------------------------------------------------- 
0      1   4 
1      2   1 
2      3   0 
3      4   6 
4      5   2 
... etc 

Je l'ai fait pour obtenir le nombre d'offres entre 0 et 1

SELECT * FROM offer WHERE price BETWEEN 0 and 1; 

Quelle devrait être la requête obtenir le résultat souhaité.

Toute sorte d'aide sera appréciée. Merci d'avance.

+1

Vous allez avoir des doubles comptes si vous ne séparez pas mieux votre groupe. IE: price_upper = 1 et sur la 2ème ligne - price_lower = 1; Cela signifie que vous compterez où le prix est 1 dans les deux totaux. –

+0

Certaines des solutions proposées ne fonctionneront que pour certains produits SQL. Il serait utile de nous indiquer le logiciel de base de données que vous utilisez. – Chris

Répondre

4

En vérifiant toutes les réponses. J'ai réussi à écrire la requête bien sûr avec votre aide. Comme peu d'entre vous ont suggéré de créer une nouvelle table pour stocker la gamme d'offres que je ne veux pas faire.

Donc, voici la requête SQL ce que je voulais:

SELECT price as price_lower, (price + 1) as price_upper, (SELECT count(*) from offer WHERE price BETWEEN o.price and (o.price + 0.99)) from offer o GROUP BY price; 

Merci à tous pour vos grands efforts. Vous êtes top les gars.

1

SELECT SUM (number_of_offers) FROM l'offre WHERE price_lower> = [prix le plus bas] AND price_upper < = [prix le plus élevé].

Les bits entre crochets que vous devrez remplir, par exemple vous pourriez y substituer des paramètres.

+0

Merde, je marquerais mon propre poste si je pouvais - je n'ai pas lu la qwuestion correctement. Meh. – slugster

+0

+1 pour votre acceptation ... – simplyharsh

0

Cela devrait être correct. Une mise en garde est que si quelque chose coûte un montant intégral, il apparaîtra en fonction de votre saveur de sql parce que "entre" est parfois inclusif.

1

Pour obtenir la sortie que vous avez indiqué:

SELECT MIN(t.price) 'price_lower', 
     MAX(t.price) 'price_upper', 
     COUNT(*) 'number_of_offers' 
    FROM OFFER t 
WHERE t.price BETWEEN 0 AND 1 
UNION ALL 
SELECT MIN(t.price) 'price_lower', 
     MAX(t.price) 'price_upper', 
     COUNT(*) 'number_of_offers' 
    FROM OFFER t 
WHERE t.price BETWEEN 1 AND 2 
UNION ALL 
... 

... ajoutant des instructions SQL distinctes pour chaque regroupement que vous voulez, changer la clause WHERE en fonction de.

+0

Il n'est pas nécessaire d'avoir un tas de requêtes unies comme ceci, cela peut être fait en une seule requête en utilisant floor/ceiling/group-by. – Chris

+0

@Chris: Il y a si FLOOR/CEILING n'est pas supporté par la DB, ce que l'OP n'a pas encore fourni. –

3

Vous pouvez essayer quelque chose comme ça

DECLARE @Offer TABLE(
     ID INT IDENTITY (1,1), 
     Product_ID INT, 
     Price FLOAT 
) 

INSERT INTO @Offer SELECT 1, 0 
INSERT INTO @Offer SELECT 1, .25 
INSERT INTO @Offer SELECT 1, .5 
INSERT INTO @Offer SELECT 1, .75 
INSERT INTO @Offer SELECT 1, 1. 
INSERT INTO @Offer SELECT 1, 1.25 
INSERT INTO @Offer SELECT 1, 1.5 
INSERT INTO @Offer SELECT 1, 1.75 
INSERT INTO @Offer SELECT 1, 2. 

INSERT INTO @Offer SELECT 2, 1 
INSERT INTO @Offer SELECT 2, 1.25 
INSERT INTO @Offer SELECT 2, 1.5 
INSERT INTO @Offer SELECT 2, 1.75 
INSERT INTO @Offer SELECT 2, 2. 
INSERT INTO @Offer SELECT 2, 2.25 
INSERT INTO @Offer SELECT 2, 2.5 
INSERT INTO @Offer SELECT 2, 2.75 
INSERT INTO @Offer SELECT 2, 3. 

SELECT Product_ID, 
     FLOOR(Price) StartPrice, 
     FLOOR(Price) + 1 EndPrice, 
     COUNT(1) NumberItems 
FROM @Offer 
GROUP BY Product_ID, 
     FLOOR(Price) 
ORDER BY 1, 2 
1

je:

select floor(price) as price_lower, 
     ceiling(price) as price_upper, 
     count(*) as offercount 
    from tbl_offer 
    group by floor(price), ceiling(price)

Pour les données de test suivant:

insert into tbl_offer ([product_id],[price]) values (1, 1.9) 
insert into tbl_offer ([product_id],[price]) values (2, 2.2) 
insert into tbl_offer ([product_id],[price]) values (3, 2.3) 
insert into tbl_offer ([product_id],[price]) values (4, 4.5) 
insert into tbl_offer ([product_id],[price]) values (5, 2.7)

J'ai obtenu les résultats suivants:

price_lower price_upper offercount 
----------- ----------- ----------- 
1   2   1 
2   3   3 
4   5   1

La seule chose qui manque dans la table d'exemple que vous avez donné est que je n'ai pas une ligne avec price_lower 3, 4 price_upper, offerCount 0.

0
create table offer_range (price_lower integer, price_upper integer); 

insert into offer_range (price_lower, price_upper) 
values (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), -- ...etc 
; 

select r.price_lower, 
r.price_upper, 
(
select count(*) 
from offer o 
where o.price between r.price_lower and r.price_upper 
) as number_of_offers 
from offer_range r 
; 
0

Celui-ci vous permet de définir une séparée pricerange table avec des gammes pour chaque produit.

DECLARE @Offer TABLE(
    ID INT IDENTITY (1,1) 
    ,Product_ID INT 
    ,Price decimal(8,2) 
) 

DECLARE @PriceRange TABLE(
    ID INT IDENTITY (1,1) 
    ,Product_ID INT 
    ,price_lower decimal(8,2) 
    ,price_upper decimal(8,2) 
) 

SELECT x.Product_ID, x.price_lower, x.price_upper, COUNT(*) as "number_of_offers" 
    FROM 
    (
    SELECT o.Product_ID, o.Price, p.price_lower, p.price_upper, 
     CASE 
     WHEN o.Price >= p.price_lower and o.Price < p.price_upper THEN 1 
     ELSE 0 
     END AS InRange   
    FROM @Offer AS o 
     JOIN @PriceRange as p ON o.Product_ID = p.Product_ID 
    ) AS x 
WHERE x.InRange = 1 
GROUP BY x.Product_ID, x.price_lower, x.price_upper 
0

Si vous devez spécifier un nombre maximal de plages, essayez cette approche: Vous pouvez indiquer un nombre maximum de plages de prix et créer automatiquement les plages de prix et les totaux de groupe.

declare @Max_Steps int 
set @Max_Steps= 6 

select Price_Group * data.Price_Step as price_lower, (Price_Group+1)*data.Price_Step as price_upper, count(id) as number_of_offers 
from 
(
    select id, price, ceiling(price/Price_Step) as Price_Group, Price_Step 
    from 
    (
     select cast((max(price) - min(price))/@Max_Steps as decimal(15,2)) as Price_Step 
     FROM offer 
    ) PriceRangeCalculator 
cross join 
    (
     SELECT id, price 
     FROM offer 
    ) SourceData 
) data 
group by data.Price_Group, data.Price_Step 
order by data.Price_Group 
Questions connexes