/ / Pivot / Aggregate score w zakresach? - sql-server-2008, pivot

Pivot / Aggregate wyniki w zakresie? - sql-server-2008, pivot

Mam tabelę składającą się z około 12 000 wierszy i każda z nich ma „liczbę punktów”. Chciałbym wybrać liczbę każdej liczby wierszy, w których punkty są w zakresie, np. 0 - 1000, 1000 - 2000 itd.

W tej chwili używam metody „długiej rundy”, ale czy jest o wiele prostszy sposób na osiągnięcie tego?

select
SUM(pts.[UNDER 1000]) AS "UNDER 1000"
, SUM(pts.[UPTO 2000]) AS "UPTO 2000"
, SUM(pts.[UPTO 3000]) AS "UPTO 3000"
, SUM(pts.[UPTO 4000]) AS "UPTO 4000"
, SUM(pts.[UPTO 5000]) AS "UPTO 5000"
, SUM(pts.[UPTO 6000]) AS "UPTO 6000"
, SUM(pts.[UPTO 7000]) AS "UPTO 7000"
, SUM(pts.[UPTO 8000]) AS "UPTO 8000"
, SUM(pts.[UPTO 9000]) AS "UPTO 9000"
, SUM(pts.[UPTO 10000]) AS "UPTO 10000"
from
(
select
case when HouseholdPointTotal < 1000 THEN 1 ELSE 0 END AS "UNDER 1000"
, case when HouseholdPointTotal >= 1000 AND HouseholdPointTotal < 2000 THEN 1 ELSE 0 END AS "UPTO 2000"
, case when HouseholdPointTotal >= 2000 AND HouseholdPointTotal < 3000 THEN 1 ELSE 0 END AS "UPTO 3000"
, case when HouseholdPointTotal >= 3000 AND HouseholdPointTotal < 4000 THEN 1 ELSE 0 END AS "UPTO 4000"
, case when HouseholdPointTotal >= 4000 AND HouseholdPointTotal < 5000 THEN 1 ELSE 0 END AS "UPTO 5000"
, case when HouseholdPointTotal >= 5000 AND HouseholdPointTotal < 6000 THEN 1 ELSE 0 END AS "UPTO 6000"
, case when HouseholdPointTotal >= 6000 AND HouseholdPointTotal < 7000 THEN 1 ELSE 0 END AS "UPTO 7000"
, case when HouseholdPointTotal >= 7000 AND HouseholdPointTotal < 8000 THEN 1 ELSE 0 END AS "UPTO 8000"
, case when HouseholdPointTotal >= 8000 AND HouseholdPointTotal < 9000 THEN 1 ELSE 0 END AS "UPTO 9000"
, case when HouseholdPointTotal >= 9000 AND HouseholdPointTotal < 10000 THEN 1 ELSE 0 END AS "UPTO 10000"
from MRS_Retail_HouseholdPoints
) pts

Odpowiedzi:

0 dla odpowiedzi № 1

Nie jestem pewien, czy jest to najlepszy czy najbardziej czytelny sposób, ale.

Możesz wybrać wybrane liczby od 1 do 10.

Który możesz zrobić w ten sposób

SELECT TOP 10 ROW_NUMBER() OVER (ORDER BY number)  rn
FROM [master]..spt_values

teraz budujesz CTE z tym, co daje ci dolną granicę i górną granicę

(0-999, 1000-1999, 2000-2999)

with CTE as (select
(rn-1) * 1000 as low,
(rn * 1000)-1 as up
FROM (SELECT
TOP 10 ROW_NUMBER() OVER (ORDER BY number)  rn
FROM [master]..spt_values )
s)

Oczywiście tę część można zastąpić tabelą zawierającą liczby lub dolną i górną granicę, co sprawi, że rzeczy będą mniej „skomplikowane” i bardziej czytelne ...

Tak czy inaczej, możesz zrobić lewe połączenie na swoim stole i zbudować etykiety (nie dokładnie takie same jak ty, ale ...

Więc

with CTE as (select
(rn-1) * 1000 as low,
(rn * 1000)-1 as up
FROM (SELECT
TOP 10 ROW_NUMBER() OVER (ORDER BY number)  rn
FROM [master]..spt_values ) s
)

select
cast(low as varchar) + "-" + cast(up as varchar) as label,
count(p.Id) as number
from cte c
left join MRS_Retail_HouseholdPoints p on p.HouseholdPointTotal between low and up
group by  low, up

Ale to zwróci ci wiersze, a nie kolumny.

Więc musisz przestawić, jeśli chcesz kolumny

with CTE as (select
(rn-1) * 1000 as low,
(rn * 1000)-1 as up
FROM (SELECT
TOP 10 ROW_NUMBER() OVER (ORDER BY number)  rn
FROM [master]..spt_values )
s)
select [0-999], [1000-1999], [2000-2999], [3000-3999], [4000-4999], [5000-5999], [6000-6999]--etc.
from
(select
cast(low as varchar) + "-" + cast(up as varchar) as label,
count(p.Id) as nb
from cte c
left join MRS_Retail_HouseholdPoints p on p.HouseholdPointTotal between low and up
group by  low, up) p
PIVOT (min(nb)
FOR label in (for label in ([0-999], [1000-1999], [2000-2999], [3000-3999], [4000-4999], [5000-5999], [6000-6999]--etc))
as  pvt

Nie tak czytelne, huh;)

Możesz nawet wykonać dynamiczny ruch obrotowy, jeśli chcesz uniknąć konieczności pisania w górę iw dół.