SQL Query including pivot - sql

I have done a query which include the left outer join and the pivot.
However I keep getting a bugs saying incorrect column.
SELECT * FROM
(select Max(datetimestamp)as datetimestamp, currentSet, tGroup_id from tPhos_Line_Operator
group by currentSet, tGroup_id)T
LEFT OUTER JOIN
(SELECT PO.tGroup_id AS G_ID, PO.CurrentSet AS cr,gP.tTest_id AS Header,convert(float,Po.Results) as Results from tPhos_Line_Operator PO
inner join tPhos_Line_Parameter pp
on PO.tPhos_Line_Parameter_id = PP.id
INNER JOIN tGroup_Parameter GP
on pp.tGroup_Parameter_id = gp.id
where PP.tPhosline_id=134)P
on T.tGroup_id = P.G_ID
AND T.CurrentSet = p.cr
PIVOT ( MAX(p.Results) For Header IN ([4],[23],[24])) AS pvt
Anyone know how to get the DateTimeStamp and the pivot record?
Which mean i will only have 4 columns in this case.
Currently i need to select * from.
I'm sorry still a junior in query.
Thanks in advance.
sample data could go here:
sample of expected result:
dateTime | currentset | tGroup_id | G_ID | cr | 4 | 23 | 24 |
2015-03-11 07:00:24.313 1 69 69 1 8.36 10 14.4
2015-03-12 00:31:58.257 2 69 69 2 9.12 8 14.4

I am making a guess. It appears that you want to "pivot" some results so you get to see these side by side instead of across multiple rows.
While PIVOT has been added into many SQL implementations, it is not the only way to achieve pivoted data nor is it always the best or easiest way to do it. Here is an old fashioned "pivot" that uses a set of case expressions and 'GROUP BY':
SELECT
PO.tGroup_id AS G_ID
, PO.CurrentSet AS cr
, MAX( datetimestamp ) AS datetimestamp
, MAX( CASE WHEN gP.tTest_id = 4 THEN CONVERT(float, Po.Results) END ) AS Results4
, MAX( CASE WHEN gP.tTest_id = 23 THEN CONVERT(float, Po.Results) END ) AS Results23
, MAX( CASE WHEN gP.tTest_id = 24 THEN CONVERT(float, Po.Results) END ) AS Results24
FROM tPhos_Line_Operator PO
INNER JOIN tPhos_Line_Parameter pp ON PO.tPhos_Line_Parameter_id = PP.id
INNER JOIN tGroup_Parameter GP ON pp.tGroup_Parameter_id = gp.id
WHERE PP.tPhosline_id = 134
GROUP BY
PO.currentSet
, PO.tGroup_id
Because you haven't supplied sample data I don't know the details but hopefully you can bend this to suit your data.
This is an alternative approach using the PIVOT operator but this also relies on using MAX() OVER(). One complication for using the PIVOT operator here is that you require a maximum datetime value as well as pivoted rows which is complex using the inbuilt pivot operator. I believe that complexity can be overcome by the MaxDateTime column seen below:
SELECT
MaxDateTime , CR, G_ID, [4], [23], [24]
FROM (
SELECT
PO.tGroup_id AS G_ID
, PO.CurrentSet AS cr
, gP.tTest_id AS Header
, MAX( PO.datetimestamp ) OVER (PARTITION BY PO.tGroup_id, PO.CurrentSet, gP.tTest_id) AS MaxDateTime
, CONVERT( float, Po.Results ) AS Results
FROM tPhos_Line_Operator PO
INNER JOIN tPhos_Line_Parameter pp ON PO.tPhos_Line_Parameter_id = PP.id
INNER JOIN tGroup_Parameter GP ON pp.tGroup_Parameter_id = gp.id
WHERE PP.tPhosline_id = 134
) AS sourve_tbl
PIVOT (MAX( Results ) FOR Header IN ([4], [23], [24])
) AS pvt_tbl
;

Yes your existing query is wrong.
I hv tried to correct it.
;With CTE as
(
select Max(datetimestamp)as datetimestamp, currentSet, tGroup_id
from tPhos_Line_Operator
group by currentSet, tGroup_id
)
Select * from
( SELECT PO.tGroup_id AS G_ID, PO.CurrentSet AS cr,gP.tTest_id AS Header
,convert(float,Po.Results) as Results
,T.*
from tPhos_Line_Operator PO
inner join tPhos_Line_Parameter pp
on PO.tPhos_Line_Parameter_id = PP.id
INNER JOIN tGroup_Parameter GP
on pp.tGroup_Parameter_id = gp.id
left join CTE T on T.tGroup_id = P.PO.tGroup_id
AND T.CurrentSet = PO.CurrentSet
where PP.tPhosline_id=134)tbl
PIVOT ( MAX(p.Results) For Header IN ([4],[23],[24])) AS pvt

Related

PIVOT on multiple columns SQL server (Aspen Relay Database)

I'm using a vendor supplied Relay Database (Aspen), which is running on MS SQL server). I'm attempting to write a pivot query that needs to pivot on 2 columns.
I created a temp table since the data is across multiple tables.
WITH TEMP_TABLE AS (
SELECT
R.LOCATIONID LLOCATIONID, R.ID RID, s.groupname SGROUPNAME,t.settingname TSETTINGNAME, s.setting SSETTING
from tsetting1 s
inner join tsettype1 t on t.relaytype=s.relaytype and t.groupname = s.groupname and t.rownumber = s.rownumber
INNER JOIN TREQUEST Q ON S.REQUESTID = Q.ID
INNER JOIN TRELAY R ON R.ID = Q.RELAYID
INNER JOIN TLOCATION L ON L.ID = R.LOCATIONID
where s.requestid=29117
)
select * from TEMP_TABLE
That select all from Temp returns 38 rows of data, a subset is shown here:
RID -----SGROUPNAME------TSETTINGNAME-------SSETTING
31297 LOAD1 ENABLE TRUE
31297 LOAD1 ANGLE 60
31297 LOAD2 CALCULATED_LOAD 12269
ETC....
I added this pivot, which gets me close:
PIVOT (MAX(SSETTING) FOR TSETTINGNAME IN (ENABLE, REACH, ANGLE, CALCULATED_LOADABILITY, ZLE, CTR, PTR, KVNOM, PICKUP, PERCENTAGE)) P
Returned result from Pivot:
RID-----SGROUPNAME-----ENABLE----REACH----ANGLE----CALCULATED_LOADABILITY
31297 LOAD1 TRUE 15 60 9444
31297 LOAD2 TRUE 10 30 12269
31297 LOAD3 TRUE 20 60 14167
ETC...
I would like to have the data as 1 record for RID 31297, where LOAD1-ENABLE, LOAD2-ENABLE, LOAD3-ENABLE, LOAD1-REACH, ETC. are all headers.
I've tried multiple pivots and cross apply, but I can't seem to get the data to display correctly.
Let me know if anything is unclear or if you need more information. Any help will be greatly appreciated.
Thanks,
Joe C.
It may be easier with a bunch of case statements and a group by RID. By the way this is the "original" method of pivoting before PIVOT was implemented.
select RID
, Load1_Enable = MAX(case when SGROUPNAME = 'Load1' then enable else null end)
, Load2_Enable = MAX(case when SGROUPNAME = 'Load2' then enable else null end)
from [YourTable]
group by RID
I would go all the way to the first cte though:
WITH TEMP_TABLE AS (
SELECT
R.LOCATIONID LLOCATIONID, R.ID RID, s.groupname SGROUPNAME,t.settingname TSETTINGNAME, s.setting SSETTING
from tsetting1 s
inner join tsettype1 t on t.relaytype=s.relaytype and t.groupname = s.groupname and t.rownumber = s.rownumber
INNER JOIN TREQUEST Q ON S.REQUESTID = Q.ID
INNER JOIN TRELAY R ON R.ID = Q.RELAYID
INNER JOIN TLOCATION L ON L.ID = R.LOCATIONID
where s.requestid=29117
)
select RID
,Load1_Enable = MAX(case when SGROUPNAME = 'Load1' and TSETTINGNAME = 'Enable' then SSETTING else null end)
from TEMP_TABLE
group by RID
Note MAX is only there for an aggregate -- you should be aggregating only one record.

How to Join two select statements

I have four tables. I wrote 2 queries independently and those are working. But what I want to do is join those two queries and generate one result.
Here is my code
Query #1
SELECT
pm.DATE
,pm.customer
,pm.gp_no AS Gatepass_Num
,pf.style
,pf.color
,pf.batch_no
,COUNT(pf.roll_no) AS Roll_QTY
,SUM(pf.meter) AS QTY
FROM
(packinglists_fabrics_items pf
,packinglists_main pm
WHERE
pf.p_id = pm.id
[AND pm.date between {DateR,RANGE1} and {DateR,RANGE2}]
[AND pm.customer_id = "{factory,false}"]
GROUP BY
pm.DATE, pm.gp_no, pf.style, pf.color, pf.batch_no)
Query #2:
SELECT
lo.DATE
,lo.customer_name
,flo.style
,flo.color
,flo.batch_no
,COUNT(flo.rowno) AS Roll_QTY
,SUM(flo.meter) AS QTY_Meter
FROM
loadinglists_fabrics_items flo, loadinglists lo
WHERE
flo.p_id = lo.id
[AND lo.date between {DateR,RANGE1} and {DateR,RANGE2}]
[AND lo.customer_id = "{factory,false}"]
GROUP BY
lo.DATE, flo.style, flo.color, flo.batch_no
batch_no is unique for loadinglists_fabrics_items table and packinglists_fabrics_items table
Result of query 1
Result of query 2
Expected output
Try like this, I assume that you are using SQL Server
SELECT A.*
,B.*
FROM (
SELECT pm.DATE
,pm.customer
,pm.gp_no AS Gatepass_Num
,pf.style
,pf.color
,pf.batch_no
,COUNT(pf.roll_no) AS Roll_QTY
,SUM(pf.meter) AS QTY
FROM packinglists_fabrics_items pf
,packinglists_main pm
WHERE pf.p_id = pm.id
AND pm.DATE BETWEEN {DateR
,RANGE1}
AND {DateR
,RANGE2}
AND pm.customer_id = "{factory,false}"
GROUP BY pm.DATE
,pm.gp_no
,pf.style
,pf.color
,pf.batch_no
) A
INNER JOIN (
SELECT lo.DATE
,lo.customer_name
,flo.style
,flo.color
,flo.batch_no
,COUNT(flo.rowno) AS Roll_QTY
,SUM(flo.meter) AS QTY_Meter
FROM loadinglists_fabrics_items flo
,loadinglists lo
WHERE flo.p_id = lo.id
AND lo.DATE BETWEEN {DateR
,RANGE1}
AND {DateR
,RANGE2}
AND lo.customer_id = "{factory,false}"
GROUP BY lo.DATE
,flo.style
,flo.color
,flo.batch_no
) B ON A.batch_no = B.batch_no

Difference Max and Min from Different Dates

I'm going to try to explain this the best I can.
The code below does the following:
Finds a service address from the ServiceLocation table.
Finds a service type (electric or water).
Finds how many days in the past to pull data.
Once it has this, it calculates the "daily usage" by subtracting the max meter read for a day from the minimum meter read for a day.
(MAX(mr.Reading) - MIN(mr.Reading)) AS 'DaytimeUsage'
However, what I'm missing is the max reading from the day prior and the minimum reading from the current day. Mathematically, this should look something like this:
MAX(PriorDayReading) - MIN(ReadDateReading)
Essentially, if it goes back 5 days it should kick out a table that reads as follows:
Service Location | Read Date | Usage |
123 Main St | 4/20/15 | 12 |
123 Main St | 4/19/15 | 8 |
123 Main St | 4/18/15 | 6 |
123 Main St | 4/17/15 | 10 |
123 Main St | 4/16/15 | 11 |
Where "Usage" is the 'DaytimeUsage' + usage that I'm missing (and the question above). For example, 4/18/15 would be the 'DaytimeUsage' in the query below PLUS the the difference between the MAX read from 4/17/15 and the MIN read from 4/18/15.
I'm not sure how to accomplish this or if it is possible.
SELECT
A.ServiceAddress AS 'Service Address',
convert(VARCHAR(10),A.ReadDate,101) AS 'Date',
SUM(A.[DaytimeUsage]) AS 'Usage'
FROM
(
SELECT
sl.location_addr AS 'ServiceAddress',
convert(VARCHAR(10),mr.read_date,101) AS 'ReadDate',
(MAX(mr.Reading) - MIN(mr.Reading)) AS 'DaytimeUsage'
FROM
DimServiceLocation AS sl
INNER JOIN FactBill AS fb ON fb.ServiceLocationKey = sl.ServiceLocationKey
INNER JOIN FactMeterRead as mr ON mr.ServiceLocationKey = sl.ServiceLocationKey
INNER JOIN DimCustomer AS c ON c.CustomerKey = fb.CustomerKey
WHERE
c.class_name = 'Tenant'
AND sl.ServiceLocationKey = #ServiceLocation
AND mr.meter_type = #ServiceType
GROUP BY
sl.location_addr,
convert(VARCHAR(10),
mr.read_date,101)
) A
WHERE A.ReadDate >= GETDATE()-#Days
GROUP BY A.ServiceAddress, convert(VARCHAR(10),A.ReadDate,101)
ORDER BY convert(VARCHAR(10),A.ReadDate,101) DESC
It seems like you could solve this by just calculating the difference between the MAX of yesterday & today, however this is how I would approach it. Join to the same table again for the previous day relative to any given day, and select the Max/Min for that too within your inner query. Also if you place the date in the inner query where clause the data set you return will be quicker & smaller.
SELECT
A.ServiceAddress AS 'Service Address',
convert(VARCHAR(10),A.ReadDate,101) AS 'Date',
SUM(A.[TodayMax]) - SUM(A.[TodayMin]) AS 'Usage',
SUM(A.[TodayMax]) - SUM(A.[YesterdayMax]) AS 'Usage with extra bit you want'
FROM
(
SELECT
sl.location_addr AS 'ServiceAddress',
convert(VARCHAR(10),mr.read_date,101) AS 'ReadDate',
MAX(mrT.Reading) AS 'TodayMax',
MIN(mrT.Reading) AS 'TodayMin',
MAX(mrY.Reading) AS 'YesterdayMax',
MIN(mrY.Reading) AS 'YesterdayMin',
FROM
DimServiceLocation AS sl
INNER JOIN FactBill AS fb ON fb.ServiceLocationKey = sl.ServiceLocationKey
INNER JOIN FactMeterRead as mrT ON mrT.ServiceLocationKey = sl.ServiceLocationKey
INNER JOIN FactMeterRead as mrY ON mrY.ServiceLocationKey = s1.ServiceLocationKey
AND mrY.read_date = mrT.read_date -1)
INNER JOIN DimCustomer AS c ON c.CustomerKey = fb.CustomerKey
WHERE
c.class_name = 'Tenant'
AND sl.ServiceLocationKey = #ServiceLocation
AND mr.meter_type = #ServiceType
AND convert(VARCHAR(10), mrT.read_date,101) >= GETDATE()-#Days
GROUP BY
sl.location_addr,
convert(VARCHAR(10),
mr.read_date,101)
) A
GROUP BY A.ServiceAddress, convert(VARCHAR(10),A.ReadDate,101)
ORDER BY convert(VARCHAR(10),A.ReadDate,101) DESC
You can use the APPLY operator if you are above sql server 2005. Here is a link to the documentation. https://technet.microsoft.com/en-us/library/ms175156(v=sql.105).aspx The APPLY operation comes in two forms OUTER APPLY AND CROSS APPLY - OUTER works like a left join and CROSS works like an inner join. They let you run a query once for each row returned. I setup my own sample of what you were trying to do, here it is and I hope it helps.
http://sqlfiddle.com/#!6/fdb3f/1
CREATE TABLE SequencedValues (
Location varchar(50) NOT NULL,
CalendarDate datetime NOT NULL,
Reading int
)
INSERT INTO SequencedValues (
Location,
CalendarDate,
Reading
)
SELECT
'Address1',
'4/20/2015',
10
UNION SELECT
'Address1',
'4/19/2015',
9
UNION SELECT
'Address1',
'4/19/2015',
20
UNION SELECT
'Address1',
'4/19/2015',
25
UNION SELECT
'Address1',
'4/18/2015',
8
UNION SELECT
'Address1',
'4/17/2015',
7
UNION SELECT
'Address2',
'4/20/2015',
100
UNION SELECT
'Address2',
'4/20/2015',
111
UNION SELECT
'Address2',
'4/19/2015',
50
UNION SELECT
'Address2',
'4/19/2015',
65
SELECT DISTINCT
sv.Location,
sv.CalendarDate,
sv_dayof.MINDayOfReading,
sv_daybefore.MAXDayBeforeReading
FROM SequencedValues sv
OUTER APPLY (
SELECT MIN(sv_dayof_inside.Reading) AS MINDayOfReading
FROM SequencedValues sv_dayof_inside
WHERE sv.Location = sv_dayof_inside.Location
AND sv.CalendarDate = sv_dayof_inside.CalendarDate
) sv_dayof
OUTER APPLY (
SELECT MAX(sv_daybefore_max.Reading) AS MAXDayBeforeReading
FROM SequencedValues sv_daybefore_max
WHERE sv.Location = sv_daybefore_max.Location
AND sv_daybefore_max.CalendarDate IN (
SELECT TOP 1 sv_daybefore_inside.CalendarDate
FROM SequencedValues sv_daybefore_inside
WHERE sv.Location = sv_daybefore_inside.Location
AND sv.CalendarDate > sv_daybefore_inside.CalendarDate
ORDER BY sv_daybefore_inside.CalendarDate DESC
)
) sv_daybefore
ORDER BY
sv.Location,
sv.CalendarDate DESC
I'm not sure I full understood your db structure but I may have a solution so feel free to edit my answer to adapt or correct any mistake.
The idea is to use two aliases for the table FactMeterRead. mrY (Y as yesterday) and mrT (T as Today). And differentiate them with a read_date restriction.
However I didn't understand enough your tables to write a fully functional query. I hope you will get the idea anyway with this example.
SELECT
sl.location_addr AS 'ServiceAddress',
convert(VARCHAR(10),mrT.read_date,101) AS 'ReadDate',
(MAX(mrY.Reading) - MIN(mrT.Reading)) AS 'DaytimeUsage'
FROM
DimServiceLocation AS sl
INNER JOIN FactMeterRead as mrY ON mrY.ServiceLocationKey = sl.ServiceLocationKey
INNER JOIN FactMeterRead as mrT ON mrT.ServiceLocationKey = sl.ServiceLocationKey
WHERE mrY.read_date=DATE_SUB(mrT.read_date,1 DAY)

Major issues with a query

I have a query
SELECT
ZEML.ICC_CODE AS ICC_CODE
,SUM(CS.TOT_HOURS) AS TOT_HOURS
,SUM(CS.NUM_INCIDENT_ALL) AS NUM_INCIDENTS
,(VALUE(FLOAT(SUM(CS.NUM_INCIDENT_ALL)) * 200000 / SUM(TOT_HOURS)
,0)) AS INC_RATE
FROM TR.CLAIMS_SUMM CS
INNER JOIN TR.LOCATION_MASTER LM
ON LM.LOCATION = CS.LOCATION
AND CS.LOCATION < '900'
LEFT JOIN TR.LOCATION_ASSIGNMENTS DISTRICT
ON DISTRICT.LOCATION = LM.LOCATION
AND DISTRICT.ASSIGNMENT_TYPE = 'District'
LEFT JOIN TR.LOCATION_ASSIGNMENTS TERRITORY
ON TERRITORY.LOCATION = LM.LOCATION
AND TERRITORY.ASSIGNMENT_TYPE = 'Territory'
LEFT JOIN TR.EMPL_CLAIMS ZEML
ON CS.LOCATION = ZEML.LOCATION
AND ZEML.TYPE = 'WC'
AND ZEML.STATUS <> 'V'
AND ZEML.CLAIM_ACTION NOT IN ('D','F','I','H')
WHERE CS.DW_DATE BETWEEN '01/01/2014'
AND '05/31/2014'
AND (MONTH(ZEML.DATE_OF_INCIDENT) = MONTH(CS.DW_DATE)
AND YEAR(ZEML.DATE_OF_INCIDENT) = YEAR(CS.DW_DATE))
GROUP BY ZEML.ICC_CODE
UNION
SELECT
'OTHER' AS ICC_CODE
, 0 AS TOT_HOURS
, 0 AS NUM_INCIDENTS
, 0 AS INC_RATE
FROM SYSIBM.SYSDUMMY1
WHERE 1 = 1
ORDER BY 1
in my union where I made an other I want to select everything else from the tr.empl_claims table and store it in the other from the union because this is what I have many other ICC codes without incidents on them and I am doing calculations on our incident rate and hourse based off of all the data but my query right now is only selecting the ones that currently is having incidents which is throwing off my calculations.
From your use of FROM SYSIBM.SYSDUMMY1 I believe you are using DB2 database. If yes, you can use CTE (common table expression) to achieve the desired result like
WITH cte1 AS
(
SELECT
ZEML.ICC_CODE AS ICC_CODE
,SUM(CS.TOT_HOURS) AS TOT_HOURS
,SUM(CS.NUM_INCIDENT_ALL) AS NUM_INCIDENTS
,(VALUE(FLOAT(SUM(CS.NUM_INCIDENT_ALL)) * 200000 / SUM(TOT_HOURS)
,0)) AS INC_RATE
FROM TR.CLAIMS_SUMM CS
... <rest of the code> ...
)
select * from cte1
UNION ALL
SELECT
ICC_CODE
, 0 AS TOT_HOURS
, 0 AS NUM_INCIDENTS
, 0 AS INC_RATE
FROM TR.EMPL_CLAIMS
WHERE ICC_CODE NOT IN
(
SELECT distinct ICC_CODE
FROM cte1
)
ORDER BY 1
SideNote: You are joining the same table LOCATION_ASSIGNMENTS twice (as below) which is not needed.
LEFT JOIN TR.LOCATION_ASSIGNMENTS DISTRICT
ON DISTRICT.LOCATION = LM.LOCATION
AND DISTRICT.ASSIGNMENT_TYPE = 'District'
LEFT JOIN TR.LOCATION_ASSIGNMENTS TERRITORY
ON TERRITORY.LOCATION = LM.LOCATION
AND TERRITORY.ASSIGNMENT_TYPE = 'Territory'
This can be transformed to below using a IN operator
LEFT JOIN TR.LOCATION_ASSIGNMENTS DISTRICT
ON DISTRICT.LOCATION = LM.LOCATION
AND DISTRICT.ASSIGNMENT_TYPE IN ('District', 'Territory')
See more about Common Table Expression in DB2 Here.
Hope this helps.

Rollup / recursive addition SQL Server 2008

I have a query with rollup that outputs data like (the query is a little busy, but I can post if necessary)
range subCounts Counts percent
1-9 3 100 3.0
10-19 13 100 13.0
20-29 30 100 33.0
30-39 74 100 74.0
NULL 100 100 100.0
How is it possible to keep a running summation total of percent? Say I need to find the bottom 15 percentile, in this case 3+13=16 so I would like for the last row to be returned read
range subCounts counts percent
10-19 13 100 13.0
EDIT1: here the query
select '$'+cast(+bin*10000 + ' ' as varchar(10)) + '-' + cast(bin*10000+9999 as varchar(10)) as bins,
count(*) as numbers,
(select count(distinct patient.patientid) from patient
inner join tblclaims on patient.patientid = tblclaims.patientid
and patient.admissiondate = tblclaims.admissiondate
and patient.dischargedate = tblclaims.dischargedate
inner join tblhospitals on tblhospitals.hospitalnpi = patient.hospitalnpi
where (tblhospitals.hospitalname = 'X')
) as Totals
, round(100*count(*)/cast((select count(distinct patient.patientid) from patient
inner join tblclaims on patient.patientid = tblclaims.patientid
and patient.admissiondate = tblclaims.admissiondate
and patient.dischargedate = tblclaims.dischargedate
inner join tblhospitals on tblhospitals.hospitalnpi = patient.hospitalnpi
where (tblhospitals.hospitalname = 'X')) as float),2) as binsPercent
from
(
select tblclaims.patientid, sum(claimsmedicarepaid) as TotalCosts,
cast(sum(claimsmedicarePaid)/10000 as int) as bin
from tblclaims inner join patient on patient.patientid = tblclaims.patientid
and patient.admissiondate = tblclaims.admissiondate
and patient.dischargedate = tblclaims.dischargedate
inner join tblhospitals on patient.hospitalnpi = tblhospitals.hospitalnpi
where tblhospitals.hospitalname = 'X'
group by tblclaims.patientid
) as t
group by bin with rollup
OK, so for whomever might use this for reference I figured out what I needed to do.
I added row_number() over(bin) as rownum to the query and saved all of this as a view.
Then I used
SELECT *,
SUM(t2.binspercent) AS SUM
FROM t t1
INNER JOIN t t2 ON t1.rownum >= t2.rownum
GROUP BY t1.rownum,
t1.bins, t1.numbers, t1.uktotal, t1.binspercent
ORDER BY t1.rownum
by joining t1.rownum >=t2.rownum you can get the rolling count sort of thing.
This isn't exactly what i was looking for, but it's on the same track:
http://blog.tallan.com/2011/12/08/sql-server-2012-windowing-functions-part-1-of-2-running-and-sliding-aggregates/ and http://blog.tallan.com/2011/12/19/sql-server-2012-windowing-functions-part-2-of-2-new-analytic-functions/ - check out PERCENT_RANK
CUME_DIST
PERCENTILE_CONT
PERCENTILE_DISC
Sorry for the lame answer