Produce all row groups having a SUM between two values - sql

I have table as below(products)
id name quality weight
1 Demir-1 ST-1 10
2 Demir-2 ST-2 7
3 Demir-3 ST-1 20
4 Demir-2 ST-3 8
5 Demir-1 ST-3 6
6 Demir-4 ST-2 10
7 Demir-2 ST-2 12
8 Demir-1 ST-1 15
9 Demir-1 ST-3 10
10 Demir-3 ST-3 5
11 Demir-2 ST-2 5
Now if a user wants to get list of products which sum of weight will between 20 and 25 and name='Result-2' then the result should be as below. All combination must be shown where sum of weight between 20 and 25.
id name quality weight
4 Demir-2 ST-3 8
7 Demir-2 ST-2 12
11 Demir-2 ST-2 5
------------------------------
2 Demir-2 ST-2 7
4 Demir-2 ST-3 8
11 Demir-2 ST-2 5
------------------------------
------------------------------
1 Demir-1 ST-1 10
8 Demir-1 ST-1 15
You can see that the sum(weight) is 25.

DECLARE #tblProducts TABLE(Id INT IDENTITY, ProductName varchar(50),Quality varchar(50), ProductWeight int)
INSERT INTO #tblProducts SELECT 'Demir-1','ST-1',10
INSERT INTO #tblProducts SELECT 'Demir-2','ST-2',7
INSERT INTO #tblProducts SELECT 'Demir-3','ST-1',20
INSERT INTO #tblProducts SELECT 'Demir-2','ST-3',8
INSERT INTO #tblProducts SELECT 'Demir-1','ST-3',6
INSERT INTO #tblProducts SELECT 'Demir-4','ST-2',10
INSERT INTO #tblProducts SELECT 'Demir-2','ST-2' ,12
INSERT INTO #tblProducts SELECT 'Demir-1','ST-1',15
INSERT INTO #tblProducts SELECT 'Demir-1','ST-3',10
INSERT INTO #tblProducts SELECT 'Demir-3','ST-3' ,5
INSERT INTO #tblProducts SELECT 'Demir-2' ,'ST-2 ',5
;WITH Cte (Id,ProductQuality,ProductIds,ProductNames,ProductQualities,ProductTotalWeight,ProductWeights,ProductName1,ProductName2) AS
(
SELECT Id
,Quality
, ',' + CAST(Id AS VARCHAR(MAX))
,',' + CAST(ProductName AS VARCHAR(MAX))
,',' + CAST(Quality AS VARCHAR(MAX))
,ProductWeight
, ',' + CAST(ProductWeight AS VARCHAR(MAX))
,ProductName
,CAST(ProductName AS VARCHAR(MAX))
FROM #tblProducts
UNION ALL
SELECT p.Id
, p.Quality
,c.ProductIds + ',' + CAST(p.Id AS VARCHAR(MAX))
,c.ProductNames + ',' + CAST(p.ProductName AS VARCHAR(MAX))
,c.ProductQualities + ',' + CAST(p.Quality AS VARCHAR(MAX))
,c.ProductTotalWeight + p.ProductWeight
,c.ProductWeights + ',' + CAST(p.ProductWeight AS VARCHAR(MAX))
,p.ProductName
,c.ProductName2
FROM #tblProducts AS p JOIN Cte c ON p.Id < c.Id
WHERE p.ProductName = c.ProductName2
)
SELECT
ProductIds = STUFF(ProductIds,1,1,'')
,ProductNames = STUFF(ProductNames,1,1,'')
,ProductQualities = STUFF(ProductQualities,1,1,'')
,ProductTotalWeight
,ProductWeights = STUFF(ProductWeights,1,1,'')
FROM CTE
WHERE ProductTotalWeight BETWEEN 20 AND 25
Result
ProductIds ProductNames ProductQualities ProductTotalWeight ProductWeights
3 Demir-3 ST-1 20 20
11,7,2 Demir-2,Demir-2,Demir-2 ST-2 ,ST-2,ST-2 24 5,12,7
11,7,4 Demir-2,Demir-2,Demir-2 ST-2 ,ST-2,ST-3 25 5,12,8
11,4,2 Demir-2,Demir-2,Demir-2 ST-2 ,ST-3,ST-2 20 5,8,7
10,3 Demir-3,Demir-3 ST-3,ST-1 25 5,20
9,1 Demir-1,Demir-1 ST-3,ST-1 20 10,10
9,8 Demir-1,Demir-1 ST-3,ST-1 25 10,15
8,1 Demir-1,Demir-1 ST-1,ST-1 25 15,10
8,5 Demir-1,Demir-1 ST-1,ST-3 21 15,6
7,4 Demir-2,Demir-2 ST-2,ST-3 20 12,8

Unfortunately, SQL is not the correct coding engine for coming up with all combinations from a table with a given calculation, as SQL code I hacked together shows.
Normally I would recommend this is coded in a procedural language given it's nature.
Note also that the solution here, with larger input data sets can quickly exhaust SQL's recursion limit. The number of possible products can also grow to sufficently large numbers that it will run very slowly.
drop table products
drop table #MinW
drop table #Products
go
create table products
(
id int,
name varchar(20),
quality varchar(20),
[weight] int
)
go
insert into products
select
1, 'Demir-1', 'ST-1', 10
union
select 2, 'Demir-2', 'ST-2', 7
union
select 3, 'Demir-3', 'ST-1', 20
union
select 4, 'Demir-2', 'ST-3', 8
union
select 5, 'Demir-1', 'ST-3', 6
union
select 6, 'Demir-4', 'ST-2', 10
union
select 7, 'Demir-2', 'ST-2', 12
union
select 8, 'Demir-1', 'ST-1', 15
union
select 9, 'Demir-1', 'ST-3', 10
union
select 10, 'Demir-3', 'ST-3', 5
union
select 11, 'Demir-2', 'ST-2', 5
go
select
p.id, p.name, p.quality, p.weight
into #MinW
from products p
inner join
(
select name,min(weight) as weight
from products group by name having min(weight) < 25
) as minW
on p.name = minW.name and p.weight = minW.weight
go
with weightProducts (id, name, [weight],history)
as
(
select id, name,[weight],convert(varchar(1024),'"'+convert(varchar(10),id)+'",') from #minW
union all
select products.id, products.name,products.[weight] + weightProducts.[weight],convert(varchar(1024),weightProducts.history+'"'+convert(varchar(10),products.id)+'",') from products, weightProducts where products.name = weightproducts.name and charindex('"'+convert(varchar(10),products.id)+'",',weightProducts.history)<=0 and (products.weight + weightProducts.weight) < 25
)
-- Statement using the CTE
select *
into #Products
from weightProducts
where weight between 20 and 25
go
select
p1.history,
p2.id,
p2.quality,
p2.weight,
p1.weight as totalWeight
from #Products p1
inner join
products p2 on p1.name = p2.name and charindex('"'+convert(varchar(10),p2.id)+'",',p1.history)>0
order by
p1.history,
p2.id

SELECT * FROM tablename
WHERE name IN (
SELECT name FROM tablename
GROUP BY name
HAVING SUM(weight) BETWEEN 20 AND 25)

Try this:
SELECT * FROM products
WHERE name IN (
SELECT name FROM products
GROUP BY name
HAVING SUM(weight) BETWEEN 20 AND 25)

How about this query:
select id, name, quality, weight from PRODUCTS
group by id, name, quality, weight
having sum(weight) between 20 and 25

Related

SQL Server - How to query the set of maximum numbers from a list of numbers from top to bottom

Best way to explain this would be through an example. Let's say I have this simple 2 column table:
Id | Score
1 | 10
2 | 5
3 | 20
4 | 15
5 | 20
6 | 25
7 | 30
8 | 30
9 | 10
10 | 40
The query should return the IDs of each item where the max score changed. So, from the top, 10 would be the top score since item 1 has 10 the first time through but then on item 3 it has a score of 20 so it just had a new max score and this continues until the bottom of the table. So eventually, the query will result to:
1, 3, 6, 7, 10
I tried doing a Cursor and loop through the table but I was wondering if there was a much simple way of doing this.
Thanks
Solution (SQL2012+):
SELECT v.MaxScore, MIN(v.Id) AS FirstId
FROM (
SELECT *, MAX(t.Score) OVER(ORDER BY t.Id ASC) AS MaxScore
FROM #Table AS t
) v
GROUP BY v.MaxScore
Demo
one more version,works for versions >= 2008,you can remove apply to make it work for 2005 as well
;with cte
(Id , Score)
as
(
select 1 , 10 union all
select 2 , 5 union all
select 3 , 20 union all
select 4 , 15 union all
select 5 , 20 union all
select 6 , 25 union all
select 7 , 30 union all
select 8 , 30 union all
select 9 , 10 union all
select 10 , 40
)
select min(id)
from
cte c2
cross apply
(select case when score -(select max(score) from cte c1 where c1.id<=c2.id )=0
then 1 else 0 end) b(val)
where val=1
group by Score
Output:
1
3
6
7
10
I think you can just do a MIN on the id with a GROUP BY Score. Like this:
SELECT MIN(Id) FROM table GROUP BY Score
Using LAG function, that returns prev value of score:
DECLARE #Table TABLE(Id int, Score int)
INSERT INTO #Table
VALUES
(1 , 10),
(2 , 10),
(3 , 20),
(4 , 20),
(5 , 20),
(6 , 25),
(7 , 30),
(8 , 30),
(9 , 30),
(10 , 40)
SELECT *
FROM
(
SELECT
*,
LAG(t.Score, 1, NULL) OVER (ORDER BY t.Id) AS PrevScore
FROM #Table AS t
) AS p
WHERE p.Score <> p.PrevScore OR p.PrevScore IS NULL
Try This
declare #scores varchar(max)
select #scores = isnull(#scores+',','')+convert(varchar,min(id))
from #temp group by score
select #scores

How to get comma delimited CategoryIds recursively?

I have a table like this:
Name CategoryId ParentCategoryId
Footwear 93 0
Men Shoes 6 93
Female Shoes 7 93
Mobile 2 0
Smartphone 4 2
I need output like:
Name Categories
Footwear 93,0
Men Shoes 6,93,0
Female Shoes 7,93,0
Mobile 2,0
Smartphone 4,2,0
Basically, I need to recursively get the category ids and make them into a comma delimited string. I am getting into SQL after 3 years now and I have no idea how to get this result. I have tried solutions from other SO questions but still no luck.
You do this with recursive cte:
DECLARE #t TABLE
(
Name VARCHAR(100) ,
CategoryId INT ,
ParentCategoryId INT
)
INSERT INTO #t
VALUES ( 'Footwear', 93, 0 ),
( 'Men Shoes', 6, 93 ),
( 'Female Shoes', 7, 93 ),
( 'Mobile', 2, 0 ),
( 'Smartphone', 4, 2 );
WITH cte
AS ( SELECT * ,
CAST(CategoryId AS VARCHAR(100)) AS Categories
FROM #t
WHERE ParentCategoryId = 0
UNION ALL
SELECT t.* ,
CAST(CAST(t.CategoryId AS VARCHAR(100)) + ','
+ c.Categories AS VARCHAR(100))
FROM #t t
JOIN cte c ON c.CategoryId = t.ParentCategoryId
)
SELECT *
FROM cte
Try it with a recursive CTE:
DECLARE #tbl TABLE(Name VARCHAR(100),CategoryId INT,ParentCategoryId INT);
INSERT INTO #tbl VALUES
('Footwear',93,0)
,('Men Shoes',6,93)
,('Female Shoes',7,93)
,('Mobile',2,0)
,('Smartphone',4,2);
--based on this: http://stackoverflow.com/a/5522641/5089204
WITH tree (CategoryId, ParentCategoryId, level, Name, rn, IdList) as
(
SELECT CategoryId, ParentCategoryId, 0 as level, Name,
convert(varchar(max),right(row_number() over (order by CategoryId),10)) AS rn,
convert(varchar(max),ISNULL(CategoryId,0)) AS IdList
FROM #tbl
WHERE ParentCategoryId = 0
UNION ALL
SELECT c2.CategoryId, c2.ParentCategoryId, tree.level + 1, c2.Name,
rn + '/' + convert(varchar(max),right(row_number() over (order by tree.CategoryId),10)),
convert(varchar(max),c2.CategoryId) + ',' + IdList
FROM #tbl c2
INNER JOIN tree ON tree.CategoryId = c2.ParentCategoryId
)
SELECT *
FROM tree
order by RN
Part of the result:
1 Mobile 2
1/1 Smartphone 4,2
2 Footwear 93
2/1 Men Shoes 6,93
2/2 Female Shoes 7,93

SQL Server Create Grouping For Related Records

I'm running into an interesting scenario trying to assign an arbitrary FamilyId to fields that are related to each other.
Here is the structure that we're currently working with:
DataId OriginalDataId
3 1
4 1
5 1
6 1
3 2
4 2
5 2
6 2
7 10
8 10
9 10
11 15
What we're attempting to do is add a FamilyId column to all DataIds that have a relationship between each other.
In this case, Id's 3, 4, 5, and 6 have a relationship to 1. But 3, 4, 5, and 6 also have a relationship with 2. So 1, 2, 3, 4, 5, and 6 should all be considered to be in the same FamilyId.
7, 8, and 9 only have a relationship to 10, which puts this into a separate FamilyId. Same for 11 and 15.
What I am expecting as a result from this are the following results:
DataId FamilyId
1 1
2 1
3 1
4 1
5 1
6 1
7 2
8 2
9 2
10 2
11 3
15 3
Sample data, structure, and queries:
Declare #Results_Stage Table
(
DataId BigInt Not Null,
OriginalDataId BigInt Null
)
Insert #Results_Stage
Values (3,1), (4,1), (5,1), (6,1), (3,2), (4,2), (5,2), (6,2), (7,10), (8, 10), (9, 10), (11, 15)
Select DataId, Row_Number() Over(Partition By DataId Order By OriginalDataId Asc) FamilyId
From #Results_Stage R
Union
Select OriginalDataId, Row_Number() Over(Partition By DataId Order By OriginalDataId Asc) FamilyId
From #Results_Stage
I'm positive my attempt is nowhere near correct, but I'm honestly not sure where to even start on this -- or if it's even possible in SQL Server.
Does anyone have an idea on how to tackle this issue, or at least, something to point me in the right direction?
Edit Below is a query I've come up with so far to identify the other DataId records that should belong to the same FamilyId
Declare #DataId BigInt = 1
;With Children As
(
Select Distinct X.DataId
From #Results_Stage S
Outer Apply
(
Select Distinct DataId
From #Results_Stage R
Where R.OriginalDataId = S.DataId
Or R.OriginalDataId = S.OriginalDataId
) X
Where S.DataId = #DataId
Or S.OriginalDataId = #DataId
)
Select Distinct O.OriginalDataId
From Children C
Outer Apply
(
Select S.OriginalDataId
From #Results_Stage S
Where S.DataId = C.DataId
) O
Union
Select DataId
From Children
The following query, which employs FOR XML PATH:
SELECT R.OriginalDataId,
STUFF((
SELECT ', ' + + CAST([DataId] AS VARCHAR(MAX))
FROM #Results_Stage
WHERE (OriginalDataId = R.OriginalDataId)
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS GroupValues
FROM #Results_Stage R
GROUP BY R.OriginalDataId
can be used to produce this output:
OriginalDataId GroupValues
===========================
1 3, 4, 5, 6
2 3, 4, 5, 6
10 7, 8, 9
15 11
Using the above result set, we can easily identify each group and thus have something upon which DENSE_RANK() can be applied:
;WITH GroupedData AS (
SELECT R.OriginalDataId,
STUFF((
SELECT ', ' + + CAST([DataId] AS VARCHAR(MAX))
FROM #Results_Stage
WHERE (OriginalDataId = R.OriginalDataId)
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS GroupValues
FROM #Results_Stage R
GROUP BY R.OriginalDataId
), Families AS (
SELECT OriginalDataId, DENSE_RANK() OVER (ORDER BY GroupValues) AS FamilyId
FROM GroupedData
)
SELECT OriginalDataId AS DataId, FamilyId
FROM Families
UNION
SELECT DataId, F.FamilyId
FROM #Results_Stage R
INNER JOIN Families F ON R.OriginalDataId = F.OriginalDataId
ORDER BY FamilyId
Output from above is:
DataId FamilyId
===================
11 1
15 1
1 2
2 2
3 2
4 2
5 2
6 2
7 3
8 3
9 3
10 3
Check this ... it doesn't look too nice but is doing the job :)
DECLARE #T TABLE (DataId INT, OriginalDataId INT)
INSERT INTO #T(DataId , OriginalDataId)
select 3,1
union all select 4,1
union all select 5,1
union all select 6,1
union all select 3,2
union all select 4,2
union all select 5,2
union all select 6,2
union all select 7,10
union all select 8,10
union all select 9,10
union all select 11,15
SELECT * FROM #T
;WITH f AS (
SELECT DISTINCT OriginalDataId FROM #T
)
, m AS (
SELECT DISTINCT
DataId , OriginalDataId = MIN(OriginalDataId)
FROM #T
GROUP BY DataId
)
, m2 AS (
SELECT DISTINCT
x.DataId , x.OriginalDataId
FROM #T AS x
LEFT OUTER JOIN m ON x.DataId = m.DataId AND x.OriginalDataId = m.OriginalDataId
WHERE m.DataId IS NULL
)
, m3 AS (
SELECT DISTINCT DataId = x.OriginalDataId , m.OriginalDataId
FROM m2 AS x
INNER JOIN m ON x.DataId = m.DataId
)
, m4 AS (
SELECT DISTINCT
DataId = OriginalDataId , OriginalDataId
FROM #T
WHERE OriginalDataId NOT IN(SELECT DataId FROM m3)
UNION
SELECT DISTINCT
x.DataId , f.OriginalDataId
FROM f
INNER JOIN m AS x on x.OriginalDataId = f.OriginalDataId
WHERE x.DataId NOT IN(SELECT DataId FROM m3)
UNION
SELECT DataId , OriginalDataId FROM m3
)
, list AS (
SELECT
x.DataId, FamilyId = DENSE_RANK() OVER(ORDER BY x.OriginalDataId )
FROM m4 AS x
)
SELECT * FROM list
-- OUTPUT
DataId FamilyId
1 1
2 1
3 1
4 1
5 1
6 1
7 2
8 2
9 2
10 2
11 3
15 3

sql server : count records

I have a tableA (ID int, Match varchar, tot int)
ID Match Tot
1 123
2 123
3 12
4 12
5 4
6 12
7 8
Now, I want to calculate Tot which is total number of match exists in the table. for example 123 occured twice, 12 exist thrice and so on. Also note that I want the count only at first match. here is the expected result.:
ID Match Tot
1 123 2
2 123
3 12 3
4 12
5 4 1
6 12
7 8 1
Another case:
ID Match Count Tot
1 123 2
2 123 1
3 12 10
4 12 10
5 4 3
6 12 5
7 8 7
Now I want to add the count for the same match. expected result:
ID Match Count Tot
1 123 2 3
2 123 1
3 12 10 25
4 12 10
5 4 3 3
6 12 5
7 8 7 7
Thanks
WITH tableA(ID, Match) AS
(
SELECT 1,123 UNION ALL
SELECT 2,123 UNION ALL
SELECT 3,12 UNION ALL
SELECT 4,12 UNION ALL
SELECT 5,4 UNION ALL
SELECT 6,12 UNION ALL
SELECT 7,8
)
SELECT *,
CASE
WHEN ROW_NUMBER() OVER (PARTITION BY Match ORDER BY ID) = 1
THEN COUNT(*) OVER (PARTITION BY Match)
END AS Tot
FROM tableA
ORDER BY ID
SELECT match, COUNT(match ) as Tot
FROM tableA
GROUP BY match
Solution 1:
DECLARE #MyTable TABLE
(
ID INT PRIMARY KEY
,Match VARCHAR(10) NOT NULL
,Tot INT NULL
);
INSERT #MyTable(ID, Match)
SELECT 1, 123
UNION ALL
SELECT 2, 123
UNION ALL
SELECT 3, 12
UNION ALL
SELECT 4, 12
UNION ALL
SELECT 5, 4
UNION ALL
SELECT 6, 12
UNION ALL
SELECT 7, 8;
--SELECT
SELECT *
,CASE
WHEN ROW_NUMBER()OVER(PARTITION BY a.Match ORDER BY a.ID ASC)=1
THEN COUNT(*)OVER(PARTITION BY a.Match)
END TotCalculated
FROM #MyTable a;
--UPDATE
WITH MyCTE
AS
(
SELECT a.Tot
,CASE
WHEN ROW_NUMBER()OVER(PARTITION BY a.Match ORDER BY a.ID ASC)=1
THEN COUNT(*)OVER(PARTITION BY a.Match)
END TotCalculated
FROM #MyTable a
)
UPDATE MyCTE
SET Tot = TotCalculated;
SELECT *
FROM #MyTable;
Solution 2:
UPDATE #MyTable
SET Tot = NULL;
SELECT x.ID, y.Num
FROM
(
SELECT b.Match, MIN(b.ID) ID
FROM #MyTable b
GROUP BY b.Match
) x INNER JOIN
(
SELECT a.Match, COUNT(*) AS Num
FROM #MyTable a
GROUP BY a.Match
) y ON x.Match = y.Match
ORDER BY x.ID
UPDATE #MyTable
SET Tot = t.Num
FROM #MyTable z
INNER JOIN
(
SELECT x.ID, y.Num
FROM
(
SELECT b.Match, MIN(b.ID) ID
FROM #MyTable b
GROUP BY b.Match
) x INNER JOIN
(
SELECT a.Match, COUNT(*) AS Num
FROM #MyTable a
GROUP BY a.Match
) y ON x.Match = y.Match
) t ON z.ID = t.ID;
SELECT *
FROM #MyTable;

Row_Number simulation in Sql server 2000

I have a sample input table as
Declare #input TABLE(Name VARCHAR(8))
INSERT INTO #input(Name) values('Aryan')
INSERT INTO #input(Name) values('Aryan')
INSERT INTO #input(Name) values('Joseph')
INSERT INTO #input(Name) values('Vicky')
INSERT INTO #input(Name) values('Jaesmin')
INSERT INTO #input(Name) values('Aryan')
INSERT INTO #input(Name) values('Jaesmin')
INSERT INTO #input(Name) values('Vicky')
INSERT INTO #input(Name) values('Padukon')
INSERT INTO #input(Name) values('Aryan')
INSERT INTO #input(Name) values('Jaesmin')
INSERT INTO #input(Name) values('Vick')
INSERT INTO #input(Name) values('Padukon')
INSERT INTO #input(Name) values('Joseph')
INSERT INTO #input(Name) values('Marya')
INSERT INTO #input(Name) values('Vicky')
Also I have a tally table as under
declare #t table(n int)
insert into #t select 1 union all select 2 union all
select 3 union all select 4 union all select 5 union all
select 6 union all select 7 union all select 8 union all
select 9 union all select 10 union all select 11 union all
select 12 union all select 13 union all select 14 union all
select 15 union all select 16 union all select 17 union all
select 18 union all select 19 union all select 20
In Sql Server 2005 if I do as
Select rn, name from (
select ROW_NUMBER()over (order by Name) as rn , * from #input) x
where rn % 2 <> 0
I get the output as
rn name
1 Aryan
3 Aryan
5 Jaesmin
7 Jaesmin
9 Joseph
11 Padukon
13 Vick
15 Vicky
Bu I am restricted to Sql server 2000. How can I get the same output?
I have tried with
SELECT name, (SELECT COUNT(*) FROM #input AS i2 WHERE i2.Name <= i1.Name) As rn
FROM #input AS i1
but the output is wrong
name rn
Aryan 4
Aryan 4
Joseph 9
Vicky 16
Jaesmin 7
Aryan 4
Jaesmin 7
Vicky 16
Padukon 12
Aryan 4
Jaesmin 7
Vick 13
Padukon 12
Joseph 9
Marya 10
Vicky 16
Declare your table variable as
Declare #input TABLE(_id int identity(1, 1), Name VARCHAR(8))
And then reqrite your query as
Select _id, name
from #input
where _id % 2 <> 0
Use this query:
SELECT t1.name, t.n
FROM
(
SELECT a.name, a.c, (SELECT COUNT(*) FROM #input AS i2 WHERE i2.Name <= a.Name) [rn]
FROM
(
SELECT i.name, count(*) c
FROM #input i
GROUP BY i.name
)a
)t1
JOIN #t t ON t.n <= t1.rn
WHERE t.n > t1.rn - t1.c
It produces desired output:
name n
-------- -----------
Aryan 1
Aryan 2
Aryan 3
Aryan 4
Jaesmin 5
Jaesmin 6
Jaesmin 7
Joseph 8
Joseph 9
Marya 10
Padukon 11
Padukon 12
Vick 13
Vicky 14
Vicky 15
Vicky 16