Multiple sql query or Cursor? - sql

I need help on something that seems to be complex to me.
I made a query to create a tbl1 which is the Cartesian product of the tables Item and Warehouse. It give’s me back all items in all warehouses:
SELECT i.ItemID, w.WarehouseID
FROM Item i, Warehouse w
I made a second query (tbl2) where I check the date of the last document previous or equal to a variable date (#datevar) and whose quantity rule is 1 (PhysicalQtyRule = 1), this by Item and Warehouse, obtained from StockHistory table
SELECT MAX(CreateDate) AS [DATE1], ItemID, Quantity, WarehouseID
FROM StockHistory
WHERE PhysicalQtyRule = 1 AND CreateDate <= #datevar
GROUP BY ItemID, Quantity, WarehouseID
Now, I need more three steps:
Build a third table containing per item and warehouse the sum of quantity, but the quantity rule is 2 (PhysicalQtyRule = 2) and date between tbl2.date (if exists) and the date of the variable #datevar, obtained from the table StockHistory. Something like that:
SELECT ItemID, WarehouseID, SUM(Quantity)
FROM StockHistory
WHERE PhysicalQtyRule = 2 AND CreateDate > tbl2.DATE1 --If exists
AND CreateDate <= #datevar
GROUP BY ItemID, WarehouseID
Build a fourth table containing per item and warehouse the sum of quantity, but the quantity rule is 3 (PhysicalQtyRule = 3) and date between tbl2.date (if any) and the date of the variable #datevar, obtained from the table StockHistory. Something like that:
SELECT ItemID, WarehouseID, SUM(Quantity)
FROM StockHistory
WHERE PhysicalQtyRule = 3 AND CreateDate > tbl2.DATE1 --If exists
AND CreateDate <= #datevar
GROUP BY ItemID, WarehouseID
Create a final table based on the first one, with an sum quantity column, something like that:
SELECT i.ItemID, w.WarehouseID, tbl2.Quantity + tbl3.Quantity – tbl4.Quantity AS [Qty]
FROM Item i, Warehouse w
I don't know if need cursors (something new for me) or multiple querys, but it's important the best performance because my StockHistory table have millions of records.
Can anyone help-me please? Thank you!
Some sample data, only for one Item and one warehouse:
+--------+-------------+------------+-----------------+----------+
| ItemID | WarehouseID | CreateDate | PhysicalQtyRule | Quantity | Balance | comments
+--------+-------------+------------+-----------------+----------+
| 1234 | 11 | 2013-03-25 | 2 | 35 | 35 | Rule 2 = In
| 1234 | 11 | 2013-03-28 | 3 | 30 | 5 | Rule 3 = Out
| 1234 | 11 | 2013-04-01 | 1 | 3 | 3 | Rule 1 = Reset
| 1234 | 11 | 2013-07-12 | 2 | 40 | 43 | Rule 2 = In
| 1234 | 11 | 2013-09-05 | 3 | 20 | 23 | Rule 3 = Out
| 1234 | 11 | 2013-12-31 | 1 | 25 | 25 | Rule 1 = Reset
| 1234 | 11 | 2014-01-09 | 3 | 11 | 14 | Rule 3 = Out
| 1234 | 11 | 2014-01-16 | 3 | 6 | 8 | Rule 3 = Out
I want to know the balance on any variable date.

Without your data, I can't test this but I believe this should be your solution.
SELECT i.ItemID
,w.WarehouseID
,[Qty] = tbl2.Quantity + tbl3.Quantity – tbl4.Quantity
FROM Item i
CROSS JOIN Warehouse w
OUTER APPLY (
SELECT [DATE1] = MAX(sh.CreateDate)
,sh.ItemID
,sh.Quantity
,sh.WarehouseID
FROM StockHistory sh
WHERE sh.PhysicalQtyRule = 1 AND sh.CreateDate <= #datevar
AND i.ItemID = sh.ItemID
AND w.WarehouseID = sh.WarehouseID
GROUP BY sh.ItemID, sh.Quantity, sh.WarehouseID ) tbl2
OUTER APPLY (
SELECT sh.ItemID
,sh.WarehouseID
,[Quantity] = SUM(sh.Quantity)
FROM StockHistory sh
WHERE sh.PhysicalQtyRule = 2 AND sh.CreateDate > tbl2.DATE1 --If exists
AND sh.CreateDate <= #datevar AND i.ItemID = sh.ItemID
AND w.WarehouseID = sh.WarehouseID
GROUP BY sh.ItemID, sh.WarehouseID ) tbl3
OUTER APPLY (
SELECT sh.ItemID
,sh.WarehouseID
,[Quantity] = SUM(sh.Quantity)
FROM StockHistory sh
WHERE sh.PhysicalQtyRule = 3 AND sh.CreateDate > tbl2.DATE1 --If exists
AND sh.CreateDate <= #datevar AND i.ItemID = sh.ItemID
AND w.WarehouseID = sh.WarehouseID
GROUP BY sh.ItemID, sh.WarehouseID ) tbl4

Related

Need help for MS Access Select Request using 2 tables

For a "products reservation system", I have 2 tables :
"RD", for global reservations data (fieds: ID, CustomerID, Date, ...)
"RP", for reserved products data per reservation (fields: ID, RD_ID, ProductID, Status, ...). RD_ID fits with the ID in RD table (field for joining). Status field can have these values: O, C, S.
I need to extract (with 2 Select instructions) the list of reservations and the number of reservations for which all products have status 'O' .
Data example for RP:
ID | RD_ID | ProdID | Status
----------------------------
1 | 1 | 100 | O
2 | 1 | 101 | O
3 | 1 | 102 | O
4 | 2 | 105 | O
5 | 2 | 100 | S
6 | 3 | 101 | C
7 | 3 | 102 | O
In this example, Select statement should return only RD_ID 1
For the number of ID, the following request does not work because it also includes reservations with products having different status:
SELECT COUNT(rd.ID) FROM rd INNER JOIN rp ON rp.RD_ID = rd.ID WHERE rp.Status = 'O';
Could you help me for the right Select statement?
Thank you.
SELECT rd.ID, COUNT(rd.ID) CountOfRD, status
FROM rd INNER JOIN rp ON rp.RD_ID
GROUP BY rd.ID, status
Use not exists as follows:
Select t.* from your_table t
Where t.status = 'O'
And not exists (select 1 from your_table tt
Where t.rd_id = tt.rd_id
And t.status != tt.status)
You can also use group by and having as follows:
Select rd_id
From your_table t
Group by rd_id
Having sum(case when status <> 'O' then 1 end) > 0

SQL logic to determine unsold inventory and corresponding available dates (Available to sell)

I am looking for advice on how to generate SQL to be used in SQL Server that will show available inventory to sell and the corresponding date that said inventory will be available. I am easily able to determine if we have inventory that is available immediately but can't wrap my head around what logic would be needed to determine future available quantities.
In the below table. The +/- column represents the weekly inbound vs outbound and the quantity available is a rolling SUM OVER PARTITION BY of the +/- column. I was able to get the immediate quantity available through this simple logic:
Case when Min(X.Qty_Available) > 0 Then Min(X.Qty_Available) else 0 END
AS Immediate_available_Qty
Table:
+-------------+---------------+---------------+------+---------------+
| Item Number | Item Name | week_end_date | +/- | Qty_Available |
+-------------+---------------+---------------+------+---------------+
| 123456 | Fidget Widget | 7/13/2019 | 117 | 117 |
| 123456 | Fidget Widget | 7/20/2019 | 49 | 166 |
| 123456 | Fidget Widget | 7/27/2019 | -7 | 159 |
| 123456 | Fidget Widget | 8/3/2019 | -12 | 147 |
| 123456 | Fidget Widget | 8/10/2019 | -1 | 146 |
| 123456 | Fidget Widget | 8/17/2019 | 45 | 191 |
| 123456 | Fidget Widget | 8/24/2019 | -1 | 190 |
| 123456 | Fidget Widget | 8/31/2019 | -1 | 189 |
| 123456 | Fidget Widget | 9/7/2019 | 50 | 239 |
+-------------+---------------+---------------+------+---------------+
My desired results of this query would be as follows:
+-----------+-----+
| Output | Qty |
+-----------+-----+
| 7/13/2019 | 117 |
| 7/20/2019 | 29 |
| 8/17/2019 | 43 |
+-----------+-----+
the second availability is determined by taking the first available quantity of 117 out of each line in Qty_Available column and finding the new minimum. If the new min is Zero, find the next continuously positive string of data (that runs all the way to the end of the data). Repeat for the third_available quantity and then stop.
I was on the thought train of pursuing RCTE logic but don't want to dive into that rabbit hole if there is a better way to tackle this issue and I'm not even sure the RCTE work for this problem?
This should return your expected result:
SELECT Item_Number, Min(week_end_date), Sum("+/-")
FROM
(
SELECT *
-- put a positive value plus all following negative values in the same group
-- using a Cumulative Sum over 0/1
,Sum(CASE WHEN "+/-" > 0 THEN 1 ELSE 0 end)
Over (PARTITION BY Item_Number
ORDER BY week_end_date
ROWS UNBOUNDED PRECEDING) AS grp
FROM my_table
) AS dt
WHERE grp <= 3 -- only the 1st 3 groups
GROUP BY Item_Number, grp
So here's what I came up with. I know this is poor, I didn't want to leave this thread high and dry and maybe I can get more insight on a better path. Please know that I've never had any real training so I don't know what I don't know.
I ended up running this into a temp table and altering the commented out section in table "A". then re-running that into a temp table.
Select
F.Upc,
F.name,
F.Week_end_date as First_Available_Date,
E.Qty_Available_1
From
(
Select Distinct
D.Upc,
D.name,
Case When Min(D.Rolling_Qty_Available) Over ( PARTITION BY D.upc) < 1 then 0 else
Min(D.Rolling_Qty_Available) Over ( PARTITION BY D.upc) END as Qty_Available_1,
Case When Max(D.Look_up_Ref) Over ( PARTITION BY D.upc) = 0 then '-1000' else
Max(D.Look_up_Ref) Over ( PARTITION BY D.upc) END as Look_up_Ref_1
From
(
Select
A.Upc,
A.name,
A.Week_end_Date,
A.Rolling_Qty_Available,
CASE WHEN
C.Max_Row = A.Row_num and A.[Rolling_Qty_Available] >1 THEN 1
ELSE
CASE WHEN
Sum(A.Calc_Row_Thing) OVER (Partition by A.UPC Order by A.Row_Num DESC
ROWS BETWEEN UNBOUNDED PRECEDING
AND Current ROW
) = (C.Max_Row - A.Row_num + 1)
THEN
C.Max_Row - A.Row_num + 1
ELSE 0 END
END as Look_up_Ref
FROM (
Select
G.Upc,
G.Name,
G.Week_End_Date,
G.Row_num,
G.Calc_Row_Thing,
G.Rolling_Qty_Available
--CASE When (G.Rolling_Qty_Available -
--isnull(H.Qty_Available_1,0)) > 0 then 1 else - 0 END as
--Calc_Row_Thing,
From [dbo].[ATS_item_detail_USA_vw] as G
--Left Join [dbo].[tmp_ats_usa_qty_1] as H on G.upc = H.upc
) AS A --Need to subtract QTY 1 out of here and below
join (
SELECT
B.upc,
Max(Row_num) AS Max_Row
FROM [dbo].[ATS_item_detail_USA_vw] AS B
GROUP BY B.upc
) as C on A.upc = C.upc
) as D
GROUP BY
D.Upc,
D.name,
D.Rolling_Qty_Available,
D.Look_up_Ref
HAVING Max(D.Look_up_Ref) > 1
) as E
Left join
(
SELECT
A.Upc,
A.name,
A.Week_end_Date,
A.Rolling_Qty_Available,
CASE WHEN
C.Max_Row = A.Row_num and A.[Rolling_Qty_Available] >1 THEN 1
ELSE
CASE WHEN
Sum(A.Calc_Row_Thing) OVER (Partition by A.UPC Order by A.Row_Num DESC
ROWS BETWEEN UNBOUNDED PRECEDING
AND Current ROW
) = (C.Max_Row - A.Row_num + 1)
THEN
C.Max_Row - A.Row_num + 1
ELSE 0 END
END as Look_up_Ref
From (
Select
G.Upc,
G.Name,
G.Week_End_Date,
G.Row_num,
G.Calc_Row_Thing,
G.Rolling_Qty_Available
--CASE When (G.Rolling_Qty_Available -
--isnull(H.Qty_Available_1,0)) > 0 then 1 else - 0 END as
--Calc_Row_Thing,
From [dbo].[ATS_item_detail_USA_vw] as G
--Left Join [dbo].[tmp_ats_usa_qty_1] as H on G.upc = H.upc
) as A --subtract qty_1 out the start qty 2 calc
join (
SELECT
B.upc,
Max(Row_num) as Max_Row
FROM [dbo].[ATS_item_detail_USA_vw] as B
GROUP BY B.upc
) AS C ON A.upc = C.upc
) AS F ON E.upc = F.upc and E.Look_up_Ref_1 = F.Look_up_Ref

SQL How to select contents of a row directly above a row, and move both into a new table

I am trying to write something to automatically clean up some travel data. See these as flights:
FLIGHTS:
ID DocType Name Travel Date Fare Paid
1 INV Mrs G 13/03/2017 37.6
2 INV Mrs G 13/03/2017 200
3 INV Mr H 14/03/2017 60
4 INV Mr H 15/03/2017 126
5 CRN Mr H 15/03/2017 126
6 INV Mr H 20/03/2017 126
7 INV Mrs S 29/03/2017 110
8 INV Mr J 26/03/2017 54
9 INV Mr R 13/03/2017 200
10 INV Miss C 27/03/2017 78.98
Sometimes people buy a flight and then get a refund. This shows up as two identical entries in the data, except that the refund is DocType 'CRN'. I need to be able to pull both the booking and the refund line out of the dataset.
I can do this for the CRN tagged rows. But how can I pull out rows that are immediately above the CRN rows? The ID of the related INV row will always have an ID that is directly and sequentially lower than the CRN row.
I have managed
INSERT INTO TRAVEL.REFUNDS (ID, DocType, Name, [Travel Date], [Fare Paid])
SELECT ID, DocType, Name, [Travel Date], [Fare Paid]
FROM TRAVEL.FLIGHTS
WHERE [DocType] = 'CRN';
GO
Thank you in advance
using exists():
select *
from t
where DocType = 'CRN'
or exists (
select 1
from t i
where i.DocType='CRN'
and i.id-1 = t.id
)
or a left join
select t.*
from t
left join t i
on i.id-1 = t.id
where t.DocType = 'CRN'
or i.DocType = 'CRN'
rextester demo: rextester.com/MSGGX10058
returns:
+----+---------+--------+------------+----------+
| ID | DocType | Name | TravelDate | FarePaid |
+----+---------+--------+------------+----------+
| 4 | INV | Mr H | 15.03.2017 | 126.00 |
| 5 | CRN | Mr H | 15.03.2017 | 126.00 |
+----+---------+--------+------------+----------+
using not exists() for the opposite result set:
select *
from t
where DocType = 'INV'
and not exists (
select 1
from t i
where i.DocType='CRN'
and i.id-1 = t.id
)
returns:
+----+---------+--------+------------+----------+
| ID | DocType | Name | TravelDate | FarePaid |
+----+---------+--------+------------+----------+
| 1 | INV | Mrs G | 13.03.2017 | 37.60 |
| 2 | INV | Mrs G | 13.03.2017 | 200.00 |
| 3 | INV | Mr H | 14.03.2017 | 60.00 |
| 6 | INV | Mr H | 20.03.2017 | 126.00 |
| 7 | INV | Mrs S | 29.03.2017 | 110.00 |
| 8 | INV | Mr J | 26.03.2017 | 54.00 |
| 9 | INV | Mr R | 13.03.2017 | 200.00 |
| 10 | INV | Miss C | 27.03.2017 | 78.98 |
+----+---------+--------+------------+----------+
This is for SELECT purposes, not sure if you wanted that or INSERT or DELETE, but hopefully it's easily reworkable to those, plus it's good to check before modifying, right?
What I'm doing is, I'm using LAG/LEAD to add one new column, which is mostly a copy of some other row column, although shifted one row up or down. With that, you'll have each row containing everything needed to decide what to do with it, which will be done in the higher query that targets the lower query's results.
-- Making an MCVE, first time I know its name though.
DECLARE #Flights TABLE (ID int, DocType char(3))
INSERT INTO #Flights VALUES
( 1, 'INV')
, ( 2, 'INV')
, ( 3, 'INV') -- Should not show up.
, ( 4, 'CRN') -- Should not show up.
, ( 5, 'INV')
, ( 6, 'INV')
, ( 7, 'INV')
, ( 8, 'INV')
, ( 9, 'INV')
, (10, 'INV') -- Should not show up.
, (11, 'CRN') -- Should not show up.
-- Querying via LEAD(), with 1 level nesting (or subquerying, I dunno which is which).
SELECT *
FROM (
SELECT ID
, DocType AS DocTypeThis
, LEAD(DocType) OVER(ORDER BY ID ASC) AS DocTypeOther -- Seems like the choice of ASC/DESC reverses LAG/LEAD behaviours into each other, although not sure.
FROM #Flights
) AS T
WHERE (DocTypeOther IS NULL AND DocTypeThis = 'INV') -- Special treatment for last row (for other implementations, might be first row).
OR DocTypeThis = DocTypeOther -- This is the core of filtering, this fails only when the row is a 'CRN', or is superceded directly by a 'CRN'.
ORDER BY ID ASC

SQL Server - Insert lines with null values when month doesn't exist

I have a table like this one:
Yr | Mnth | W_ID | X_ID | Y_ID | Z_ID | Purchases | Sales | Returns |
2015 | 10 | 1 | 5210 | 1402 | 2 | 1000.00 | etc | etc |
2015 | 12 | 1 | 5210 | 1402 | 2 | 12000.00 | etc | etc |
2016 | 1 | 1 | 5210 | 1402 | 2 | 1000.00 | etc | etc |
2016 | 3 | 1 | 5210 | 1402 | 2 | etc | etc | etc |
2014 | 3 | 9 | 880 | 2 | 7 | etc | etc | etc |
2014 | 12 | 9 | 880 | 2 | 7 | etc | etc | etc |
2015 | 5 | 9 | 880 | 2 | 7 | etc | etc | etc |
2015 | 7 | 9 | 880 | 2 | 7 | etc | etc | etc |
For each combination of (W, X, Y, Z) I would like to insert the months that don't appear in the table and are between the first and last month.
In this example, for combination (W=1, X=5210, Y=1402, Z=2), I would like to have additional rows for 2015/11 and 2016/02, where Purchases, Sales and Returns are NULL. For combination (W=9, X=880, Y=2, Z=7) I would like to have additional rows for months between 2014/4 and 2014/11, 2015/01 and 2015/04, 2016/06.
I hope I have explained myself correctly.
Thank you in advance for any help you can provide.
The process is rather cumbersome in this case, but quite possible. One method uses a recursive CTE. Another uses a numbers table. I'm going to use the latter.
The idea is:
Find the minimum and maximum values for the year/month combination for each set of ids. For this, the values will be turned into months since time 0 using the formula year*12 + month.
Generate a bunch of numbers.
Generate all rows between the two values for each combination of ids.
For each generated row, use arithmetic to re-extract the year and month.
Use left join to bring in the original data.
The query looks like:
with n as (
select row_number() over (order by (select null)) - 1 as n -- start at 0
from master.spt_values
),
minmax as (
select w_id, x_id, y_id, z_id, min(yr*12 + mnth) as minyyyymm,
max(yr*12 + mnth) as maxyyyymm
from t
group by w_id, x_id, y_id, z_id
),
wxyz as (
select minmax.*, minmax.minyyyymm + n.n,
(minmax.minyyyymm + n.n) / 12 as yyyy,
((minmax.minyyyymm + n.n) % 12) + 1 as mm
from minmax join
n
on minmax.minyyyymm + n.n <= minmax.maxyyyymm
)
select wxyz.yyyy, wxyz.mm, wxyz.w_id, wxyz.x_id, wxyz.y_id, wxyz.z_id,
<columns from t here>
from wxyz left join
t
on wxyz.w_id = t.w_id and wxyz.x_id = t.x_id and wxyz.y_id = t.y_id and
wxyz.z_id = t.z_id and wxyz.yyyy = t.yr and wxyz.mm = t.mnth;
Thank you for your help.
Your solution works, but I noticed it is not very good in terms of performance, but meanwhile I have managed to get a solution for my problem.
DECLARE #start_date DATE, #end_date DATE;
SET #start_date = (SELECT MIN(EOMONTH(DATEFROMPARTS(Yr , Mnth, 1))) FROM Table_Input);
SET #end_date = (SELECT MAX(EOMONTH(DATEFROMPARTS(Yr , Mnth, 1))) FROM Table_Input);
DECLARE #tdates TABLE (Period DATE, Yr INT, Mnth INT);
WHILE #start_date <= #end_date
BEGIN
INSERT INTO #tdates(PEriod, Yr, Mnth) VALUES(#start_date, YEAR(#start_date), MONTH(#start_date));
SET #start_date = EOMONTH(DATEADD(mm,1,DATEFROMPARTS(YEAR(#start_date), MONTH(#start_date), 1)));
END
DECLARE #pks TABLE (W_ID NVARCHAR(50), X_ID NVARCHAR(50)
, Y_ID NVARCHAR(50), Z_ID NVARCHAR(50)
, PerMin DATE, PerMax DATE);
INSERT INTO #pks (W_ID, X_ID, Y_ID, Z_ID, PerMin, PerMax)
SELECT W_ID, X_ID, Y_ID, Z_ID
, MIN(EOMONTH(DATEFROMPARTS(Ano, Mes, 1))) AS PerMin
, MAX(EOMONTH(DATEFROMPARTS(Ano, Mes, 1))) AS PerMax
FROM Table1
GROUP BY W_ID, X_ID, Y_ID, Z_ID;
INSERT INTO Table_Output(W_ID, X_ID, Y_ID, Z_ID
, ComprasLiquidas, RTV, DevManuais, ComprasBrutas, Vendas, Stock, ReceitasComerciais)
SELECT TP.DB, TP.Ano, TP.Mes, TP.Supplier_Code, TP.Depart_Code, TP.BizUnit_Code
, TA.ComprasLiquidas, TA.RTV, TA.DevManuais, TA.ComprasBrutas, TA.Vendas, TA.Stock, TA.ReceitasComerciais
FROM
(
SELECT W_ID, X_ID, Y_ID, Z_ID
FROM #tdatas CROSS JOIN #pks
WHERE Period BETWEEN PerMin And PerMax
) AS TP
LEFT JOIN Table_Input AS TA
ON TP.W_ID = TA.W_ID AND TP.X_ID = TA.X_ID AND TP.Y_ID = TA.Y_ID
AND TP.Z_ID = TA.Z_ID
AND TP.Yr = TA.Yr
AND TP.Mnth = TA.Mnth
ORDER BY TP.W_ID, TP.X_ID, TP.Y_ID, TP.Z_ID, TP.Yr, TP.Mnth;
I do the following:
Get the Min and Max date of the entire table - #start_date and #end_date variables;
Create an auxiliary table with all dates between Min and Max - #tdates table;
Get all the combinations of (W_ID, X_ID, Y_ID, Z_ID) along with the min and max dates of that combination - #pks table;
Create the cartesian product between #tdates and #pks, and in the WHERE clause I filter the results between the Min and Max of the combination;
Compute a LEFT JOIN of the cartesian product table with the input data table.

How do you select from a date range as the data source

Short of creating a table with all of the values of a date range, how would I select from a datarange as a datasource.
What I'm trying to accomplish is to create a running total of all items created within the same week from separate tables, while showing weeks with 0 new
example table:
items
-----------------------------
created_on | name | type
-----------------------------
2012-01-01 | Cards | 1
2012-01-09 | Red Pen | 2
2012-01-31 | Pencil | 2
2012-02-01 | Blue Pen | 2
types
--------------
name | id
--------------
Fun | 1
Writing | 2
sample output:
----------------------------
year | week | fun | writing
----------------------------
2012 | 1 | 1 | 0
2012 | 2 | 0 | 1
2012 | 3 | 0 | 0
2012 | 4 | 0 | 0
2012 | 5 | 0 | 2
You could generate a number series for the week numbers
SELECT
w.week
FROM
(SELECT generate_series(1,52) as week) as w
Example
SELECT
w.year,
w.week,
COUNT(i1) as fun,
COUNT(i2) as writing
FROM (SELECT 2012 as year, generate_series(1,6) as week) as w
LEFT JOIN items i1 ON i1.type = 1 AND w.week = EXTRACT(WEEK FROM i1.created_on)
LEFT JOIN items i2 ON i2.type = 2 AND w.week = EXTRACT(WEEK FROM i2.created_on)
GROUP BY
w.year,
w.week
ORDER BY
w.year,
w.week
Very close erikxiv, but you got me in the right direction. I have multiple tables I need to grab information from, this the additional select in the select fields.
select
date_year.num,
date_week.num,
( select count(*) from items x
and EXTRACT(YEAR FROM x.created_on) = date_year.num
and EXTRACT(WEEK FROM x.created_on) = date_week.num
) as item_count
from
(SELECT generate_series(2011, date_part('year', CURRENT_DATE)::INTEGER) as num) as date_year,
(SELECT generate_series(1,52) as num) as date_week
where
(
date_year.num < EXTRACT (YEAR FROM CURRENT_DATE)
OR
(
date_year.num = EXTRACT (YEAR FROM CURRENT_DATE) AND
date_week.num <= EXTRACT (WEEK FROM CURRENT_DATE)
)
)