I have a query that returns something similar to the following:
Zone | NeededItems
===========================
209 | 5
213 | 1
216 | 1
220 | 2
218 | 1
219 | 4
215 | 1
The query behind it is something like:
SELECT
r.Zone as Zone, r.Required - COUNT(i.Item) as NeededItems
FROM
MyItems i
INNER JOIN
MyRequirements r ON i.Zone = r.Zone
GROUP BY
r.Zone, r.Required
Where MyItems looks like: (Value of Item doesn't matter)
Zone | Item
================
209 | a
209 | b
209 | c
216 | a
220 | a
213 | z
218 | x
219 | q
219 | w
219 | e
219 | r
215 | t
And MyRequirements looks like:
Zone | Required
======================
209 | 8
213 | 2
216 | 2
220 | 3
218 | 2
219 | 5
215 | 2
What I need to be able to do is print out the Zone multiple times based on the value in Needed. The value in Needed is a calculated value which is what is making this difficult (I can't just remove the count!)
So the results I am looking for is simply a list of zones, each appearing the number of times it is needed.
Zone
====
209
209
209
209
209
213
216
220
220
218
219
219
219
219
215
Is there any way in SQL that this can be done? Using SQL Server 2012.
Below is one way to do it - using the e1, e2 and e3 queries are not the cleanest way to do it, but it's the only way that I could manage to get it working.
One bit limitation: it only works for up to 1000 items of each (more than enough for mine.) This could be changed by editing WHERE c<9
but be aware this is recursive so best not to have it more than what is needed.
WITH CTE as
(
SELECT
r.Zone as Zone, r.Required - COUNT(i.Item) as NeededItems
FROM
MyItems i
INNER JOIN
MyRequirements r ON i.Zone = r.Zone
GROUP BY
r.Zone, r.Required
),
e1(n,c ) AS
(
SELECT 1, 0
UNION ALL
SELECT n, c + 1
FROM e1
WHERE c<9
), -- 10
e2(n) AS
(
SELECT 1 FROM e1 CROSS JOIN e1 AS b -- 100
),
e3(n) AS
(
SELECT 1 FROM e1 CROSS JOIN e2 -- 1000
),
Numbers AS
(
SELECT n = ROW_NUMBER() OVER (ORDER BY n) FROM e3
)
SELECT
Zone
FROM
Numbers
INNER JOIN
CTE on CTE.NeededItems >= n ORDER BY Zone
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.