Modifying a column in a table - sql-server

I have the following table test
iD Name ParentId GroupID
-----------------------------
1 1 Null
2 1 Null
3 1 Null
4 7 Null
5 7 Null
6 7 Null
7 9 Null
How can I modify it to get the column GroupID like this:
iD Name ParentId GroupID
------------------------------
1 1 1
2 1 1
3 1 1
4 7 2
5 7 2
6 7 2
7 9 3

; WITH CTE
AS
(
SELECT iDName, ParentId, GroupID,
DENSE_RANK() OVER (ORDER BY ParentId ASC) RN
FROM Test
)
UPDATE CTE
SET GroupID = RN
Working SQL FIDDLE

UPDATE test SET GroupID = 1 WHERE ParentId = 1
UPDATE test SET GroupID = 2 WHERE ParentId = 7
UPDATE test SET GroupID = 3 WHERE ParentId = 9

Related

SQL Server query to retrieve all from View

I have a SQL View, similiar to the one below:
map_id | type_id | path
1 1 0
2 2 0
3 3 0
4 1 A>B
5 1 A>B>C
6 2 T>Z
7 2 T>Z>X
8 3 U
9 3 X>Y
10 1 D
And another table, tblRoles
role_group_id | type_id | map_id
1 1 1
2 1 4
I want to build a query that will include all map_id where role_group_id has the map_id = 1 and for the rest it should only get the corresponding map_id
So, the query result should look like:
role_group_id | type_id | map_id | path
1 1 4 A>B
1 1 5 A>B>C
1 1 10 D
1 1 1 0
2 1 4 A>B
Could someone point me to the correct way?
Thank you!
Haven't tested this yet, I hope this should work.
SELECT r.role_group_id
,r.type_id
,sv.map_id
,sv.path
FROM tblRoles r
LEFT JOIN sampleView sv ON r.type_id = sv.type_id
WHERE r.map_id = 1
UNION
SELECT r.role_group_id
,r.type_id
,r.map_id
,sv.path
FROM tblRoles r
INNER JOIN sampleView sv ON r.map_id = sv.map_id
WHERE r.map_id <> 1
You can use UNION
#rosuandreimihai: select all when map_id=1 and if map_id is different, select only the
corresponding row
DECLARE #CurrentMapId INT = 1
SELECT * FROM FirstTable
WHERE
TYPE_ID IN
(
SELECT r.type_id FROM tblRoles r
WHERE
map_id = #CurrentMapId
)
UNION
SELECT * FROM FirstTable
WHERE
map_id IN
(
SELECT r.map_id FROM tblRoles r
WHERE
#CurrentMapId = 1 OR
map_id = #CurrentMapId
)

SQL Server 2008 R2: Recursive query

This is the follow up question of : Prepare a recursive query
I have the table with the two columns namely cola and colb as shown below:
Table : Test
create table Test
(
cola int,
colb int
);
Records I have entered are:
Cola Colb
------------
1 2
1 3
1 4
2 5
2 6
2 3
3 2
3 4
3 7
3 10
10 11
11 12
11 13
11 14
12 15
13 16
14 99
15 88
16 77
Note: Now I want to show the only records who are connected with value I have pass. For example If I pass the value as 1 then it should display me the connected number to it and form connect like a tree.
For the above requirement I have got the script from Dark Knight as shown below which works fine.
;WITH CTE AS
(
SELECT COLA,COLB,','+CAST(COLA AS VARCHAR(MAX))+',' AS CHCK FROM test WHERE COLA=1
UNION ALL
SELECT C1.COLA,C1.COLB,C.CHCK+CAST(C1.cola AS VARCHAR(MAX))+','
FROM CTE C INNER JOIN test C1 ON C.colb = C1.cola
WHERE CHARINDEX(','+CAST(C.colb AS VARCHAR(MAX))+',',C.CHCK)=0
),
OUTERCTE AS
(
SELECT DISTINCT COLA,COLB,ROW_NUMBER() OVER(PARTITION BY Colb ORDER BY Cola) rn FROM CTE --ORDER BY COLA
)
SELECT Cola,Colb FROM OUTERCTE
WHERE rn<=1
ORDER BY CASE WHEN Cola = 1 THEN 1 ELSE 2 END;
Which gives me this:
----------------
Cola Colb
----------------
1 2
1 3
1 4
2 5
2 6
3 7
3 10
10 11
11 12
11 13
11 14
12 15
13 16
16 77
15 88
14 99
Requirement: Now I want to show the levels of records.
Expected Result:
------------------------------
Cola Colb Level
------------------------------
1 2 1
1 3 1
1 4 1
2 5 2
2 6 2
3 7 2
3 10 2
10 11 3
11 12 4
11 13 4
11 14 4
12 15 5
13 16 5
16 77 6
15 88 6
14 99 5
;WITH CTE AS
(
SELECT COLA,COLB
,','+CAST(COLA AS VARCHAR(MAX))+',' AS CHCK
, 1 as lvl FROM #Test WHERE COLA=1
UNION ALL
SELECT C1.COLA,C1.COLB ,C.CHCK+CAST(C1.cola AS VARCHAR(MAX))+','
, c.lvl+1
FROM CTE C INNER JOIN #Test C1 ON C.colb = C1.cola
WHERE CHARINDEX(','+CAST(C.colb AS VARCHAR(MAX))+',',C.CHCK)=0
),
cte2 as (
select * , ROW_NUMBER() over (partition by colb order by lvl)as rn From CTE
)
select cola,colb,lvl from cte2 where rn = 1

Update a table column with shuffled numbers within a range

I want to update a table column -Code- with shuffled numbers within its range, with no duplicates and without missing a number from the range.
for example the range is 1-9 and the following is the table:
Id|Name|Code
1 | AC | 2
2 | AB | 1
3 | CB | 5
4 | DE | 9
5 | FE | 3
6 | AE | 4
7 | FD | 6
8 | BD | 7
9 | DC | 8
I want result like in the above example. I am using SQL Server 2008.
Try this:
DECLARE #t TABLE ( ID INT, Code INT )
INSERT INTO #t
( ID )
VALUES ( 1 ),
( 2 ),
( 3 ),
( 4 ),
( 5 ),
( 6 ),
( 7 ),
( 8 ),
( 9 );
WITH cte
AS ( SELECT * ,
ROW_NUMBER() OVER ( ORDER BY NEWID() ) AS rn
FROM #t
)
UPDATE cte
SET code = rn
SELECT *
FROM #t
Output:
ID Code
1 2
2 7
3 4
4 1
5 6
6 8
7 5
8 9
9 3
If you want to manually set the range then you can set starting number of range and do something like:
DECLARE #start INT = 101
DECLARE #t TABLE ( ID INT, Code INT )
INSERT INTO #t
( ID )
VALUES ( 1 ),
( 2 ),
( 3 ),
( 4 ),
( 5 ),
( 6 ),
( 7 ),
( 8 ),
( 9 );
WITH cte
AS ( SELECT * ,
ROW_NUMBER() OVER ( ORDER BY NEWID() ) AS rn
FROM #t
)
UPDATE cte
SET code = rn + #start - 1
SELECT *
FROM #t
Output:
ID Code
1 104
2 108
3 107
4 105
5 102
6 103
7 106
8 101
9 109
NEWID() will give us a type of random id that you can use it for shuffling
As Giorgu Nakeuri answer you can use ROW_NUMBER() for a range of continuous and always start from 1
So I suggest you to use a query like this for shuffling a non-continues Range with different start point of 1:
;With t as (
SELECT *, ROW_NUMBER() OVER (ORDER BY NEWID()) As rndrn
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY Id) As rn
FROM yourTable ) t1)
SELECT Id, Name, (SELECT ti.Id FROM t ti WHERE ti.rn = t.rndrn) As Code
FROM t
ORDER BY Id
Sample Result is:
ID Name Code
2 AB 2
3 CB 8
4 DE 7
5 FE 5
6 AE 6
7 FD 9
8 BD 3
9 DC 11
11 AC 4

Populate Sequence Number by Repeated fields in Coloumns

i have below data in my table
description id
-------------- ------
desc1 0
desc2 0
desc3 0
desc4 1
desc5 1
desc6 1
I need below
description id sequenceNo
-------------- ------ ------------------
desc1 0 1
desc2 0 2
desc3 0 3
desc4 1 1
desc5 1 2
desc6 1 3
Please let me know how to solve this query by using sql function or any other alternative..?
try this
select *,ROW_NUMBER() Over(partition By ID order by ID asc)
as sequenceNo from Mytable

Count and Group By for products sold

I have a table Transaction & a table product as below .
Each Transaction has multiple products.
ProductId Name
1 ABC
2 DEF
3 GHI
Each transaction can have multiple products sold.
TransactionId ProductSoldInDept1 ProductSoldinDept2 ProductSoldinDept3
1 1 null null
2 1 2 null
3 3 1 null
4 2 3 1
I am planning to generate a report and I would like to get a result something like this :
This shows the number of products sold per each department grouped by Id
Expected Result :
ProductID Department1ProdCount Department2ProdCount Department3ProdCount
1 2 1 1
2 1 1 0
3 1 1 0
I could get till here , this is a query to get the counts for one specific product
which is productid : 1
I would like to know how I could use a group by here :
select Count(CASE WHEN ProductSoldInDept1 = 1 THEN 1 END) ,
Count(CASE WHEN ProductSoldInDept2 = 1 THEN 1 END) ,
Count(CASE WHEN ProductSoldInDept3 = 1 THEN 1 END)
from Table1
SELECT
p.ProductID,
Dept1ProdCount = COUNT(CASE WHEN t.ProductSoldInDept1 = p.ProductID THEN 1 END),
Dept2ProdCount = COUNT(CASE WHEN t.ProductSoldInDept2 = p.ProductID THEN 1 END),
Dept3ProdCount = COUNT(CASE WHEN t.ProductSoldInDept3 = p.ProductID THEN 1 END)
FROM dbo.Product AS p
LEFT OUTER JOIN dbo.[Transaction] AS t
ON p.ProductID IN
(t.ProductSoldInDept1, t.ProductSoldinDept2, t.ProductSoldinDept3)
GROUP BY p.ProductID;
Result
| PRODUCTID | DEPT1PRODCOUNT | DEPT2PRODCOUNT | DEPT3PRODCOUNT |
----------------------------------------------------------------
| 1 | 2 | 1 | 1 |
| 2 | 1 | 1 | 0 |
| 3 | 1 | 1 | 0 |
See a demo
Try this
select ProductID,
v.Department1ProdCount, v.Department2ProdCount, v.Department3ProdCount
from product a
cross apply
(
select Count(CASE WHEN ProductSoldInDept1 = a.ProductID THEN 1 END) Department1ProdCount,
Count(CASE WHEN ProductSoldInDept2 = a.ProductID THEN 1 END) Department2ProdCount,
Count(CASE WHEN ProductSoldInDept3 = a.ProductID THEN 1 END) Department3ProdCount
from Table1
) v
This:
TransactionId ProductSoldInDept1 ProductSoldinDept2 ProductSoldinDept3
1 1 null null
2 1 2 null
3 3 1 null
4 2 3 1
might be better structured as this:
transid prodsold deptid
1 1 1
2 1 1
2 2 2
3 3 1
3 1 2
4 2 1
4 3 2
4 1 3
I think that would make your queries easier to write.

Resources