SQL Server view for calc ParentId column - sql-server

I have a table with following sampled rows:
Id CompanyId value
1 X a
2 X b
3 X c
4 X d
5 Y e
6 Y f
7 z g
8 Z h
9 X i
10 X j
I want to have a view with following result :
Id CompanyId ParentId
1 X NULL
2 X NULL
3 X NULL
4 X NULL
5 Y 1
6 Y 1
7 z 5
8 Z 5
9 X 7
10 X 7
On this result calculated ParentId for each row. ParentId for each row equal to Id of first row from previous companyId.

I hope that SQL Server 2012 tag is here for reason :)
;with x as (
select *, lag(companyid) over(order by id) as prev
from #t1
),
y as (
select *, sum(case when prev = companyid then 0 else 1 end) over(order by id) as grp
from x
)
select y.id, y.companyid, min(y1.id)
from y
left join y y1 on y1.grp = y.grp-1
group by y.id, y.companyid

Related

Conditional ROW NUMBER to create a Column in SQL

I have two columns ID and FLAG as :
ID FLAG
1 Y
1 N
1 Y
1 N
1 N
1 N
1 N
1 Y
1 N
2 N
2 Y
2 N
2 N
2 Y
2 Y
2 N
Required Output:
ID FLAG REQ_COL
1 Y null
1 N 1
1 Y null
1 N 1
1 N 2
1 N 3
1 N 4
1 Y null
1 N 1
2 N null
2 Y null
2 N 1
2 N 2
2 Y null
2 Y null
2 N 1
Logic for required column :
For first occurence of ID , REQ_COL is null
If FLAG=Y then REQ_COL is null
IF previous value of FLAG is Y and there are consecutive N in FLAG , then the REQ_COL values are 1,2,3,4, 5.....
Else Null
I am trying to apply conditional row_number but not getting idea how to proceed.
Please help.
This might give you the result you are searching for...
Data Preparation
DECLARE #SOURCE_TABLE AS TABLE (realid int identity (1,1), ID int, FLAG CHAR(1))
INSERT INTO #SOURCE_TABLE (ID, FLAG)
VALUES (1, 'Y'),(1, 'N'),(1, 'Y'),(1, 'N'),(1, 'N'),(1, 'N'),
(1, 'N'),(1, 'Y'),(1, 'N'),(2, 'N'),(2, 'Y'),(2, 'N'),
(2, 'N'),(2, 'Y'),(2, 'Y'),(2, 'N')
Actual Select
SELECT ST2.ID, ST2.FLAG,
NULLIF(NULLIF (CHARINDEX('Y', REVERSE(
(
SELECT ST1.FLAG AS [text()]
FROM #SOURCE_TABLE ST1
WHERE ST1.ID = ST2.ID AND ST1.realid <= ST2.realid
ORDER BY ST1.realid
FOR XML PATH (''), TYPE
).value('text()[1]','VARCHAR(MAX)')
)), 1) - 1, -1) AS [REQ_COL]
FROM #SOURCE_TABLE AS ST2
ORDER BY ST2.realid

Calculate Page number based on two columns

I have the below table I want to find the Page number.
The logic is if the sum of both col A and col b is greater than or equal to 15 then it should be page and it should be incremented.
Col A will be always 1 or 0. Only Col B will changed
Problem :
Col X
Col y
col A
Col B
Pagenumber
x
y
1
105
x
y
1
0
x
y
1
2
x
y
1
6
x
y
1
3
null
y
0
1
x
y
1
2
x
y
1
3
x
y
1
1
x
y
1
4
Expected output :
Col X
Col y
col A
Col B
Pagenumber
x
y
1
105
Page 1
x
y
1
0
Page 2
x
y
1
2
Page 2
x
y
1
6
Page 2
x
y
1
3
Page 2
null
y
0
1
Page 3
x
y
1
2
Page 3
x
y
1
3
Page 3
x
y
1
1
Page 3
x
y
1
4
Page 3
Query without pagenumber column:
SELECT
IIF(c2.isdeleted = 1 OR c2.approved = 0, NULL, c2.content) AS Content,
(SELECT STRING_AGG(c1.content, ', ')
FROM comments c1
WHERE c1.parentcommentid = c2.id
AND c1.isdeleted = 0
AND c1.approved = 1) ChildContent,
IIF(c2.isdeleted = 1 OR c2.approved = 0, 0, 1) AS Contentcount,
(SELECT COUNT(c1.content)
FROM comments c1
WHERE c1.parentcommentid = c2.id
AND c1.isdeleted = 0
AND c1.approved = 1) ChildContentcount
FROM
comments c2
WHERE
c2.discussionid = '402930'
AND c2.parentcommentid IS NULL
-- AND Content IS NOT NULL
ORDER BY
c2.pinned DESC,
c2.createddate
You need to specify the order of rows in which the cumulative sum should be calculated.
You can use a recursive CTE to calculate and partition the running sum.
with t(rn, x, y, a, b) as (
select row_number() over (order by ???), -- set the ordering columns here
x, y, a, b
from your_table
),
cte(rn, x, y, a, b, running_sum, page) as (
select t.rn, t.x, t.y, t.a, t.b, t.a + t.b, 1
from t where rn = 1
union all
select t.rn, t.x, t.y, t.a, t.b,
t.a + t.b + case when cte.running_sum >= 15 then 0 else cte.running_sum end,
case when cte.running_sum >= 15 then cte.page + 1 else cte.page end
from cte join t on t.rn = cte.rn + 1
where t.rn > 1
)
select *
from cte;
Result:

How to select k distinct value by a field?

How to select all infos from k distinct value of field X?
I have an idea to group by by some field X and then select like this
Table
id name
1 x
2 y
3 x
4 y
5 z
6 w
Group by name:
id name
1 x
3 x
2 y
4 y
5 z
6 w
Select k=3 distinct value of name:
id name
1 x
3 x
2 y
4 y
5 z
Any idea how to write this query?
Try this -
WITH CTE AS (SELECT DISTINCT name
FROM TAB
LIMIT 3)
SELECT * FROM TAB
WHERE NAME IN (SELECT name FROM CTE)
ORDER BY name;
select id, name
from (
select id, name, dense_rank() over (order by name) as ds
from t
) s
where ds <= 3

Optimize query of sql server

I want number of users present in a department.i have 9 department.
now i am using "while" loop to count no of users present in an department.
Can you please suggest how to count no of users present in an department.
Department table(Columns: Id and DeptName)
User Table(Columns: Id, Name, deptId)
Please help me
Thanks
[EDIT]
User table
----------
id name deptid
1 a 1
2 b 1
3 c 2
4 d null
5 e 3
6 f 4
7 g 2
8 h 4
9 i 5
10 j 5
11 k null
Department
----------
id name
1 x
2 x1
3 y
4 y1
5 z
6 z1
Result
------
count depetname
9 all
2 x
2 x1
1 y
2 y1
2 z
0 z1
[/EDIT]
see DEMO
EDIT
you should be use RIGHT JOIN
select 'all', count(0) from users
union
SELECT department.name, COUNT(users.id) FROM users Right Outer JOIN department
ON users.deptId=department.id GROUP BY department.id

What would be my SqlServer query?

Table1
P R E Value
X 1 10 1
Y 2 30 2
Z 3 CR 3
X 1 30 4
Table2
P R E Value
X 1 CR 4
Y 2 10 5
Y 3 CR 6
W 1 30 7
Query1 - Merge these two tables. I'm able to achieve this using union clause.
Query2 - On the merged table select all records except for entries where for a combination of P, R & E; there are similar records with the only mismatch of 'E' as 30 & 10, then ignore record with E as 30. In case only 30 is present then consider it.
Conditions:
10 & 30 - consider only 10, ignore 30
10 - consider it
30 - consider it
CR - consider it
10 & CR - consider both
30 & CR - consider both
10 & 30 & CR - consider 10 & CR
Expected Output table
P R E Value
X 1 10 1
Z 3 CR 3
X 1 CR 4
Y 2 10 5
Y 3 CR 6
W 1 30 7
Ignored records
Y 2 30 2
X 1 30 4
I was able to achieve your desired result set with the following query.
insert into #Table1
values ('X','1','10','1'),
('Y','2','30','2'),
('Z','3','CR','3'),
('X','1','30','4')
insert into #Table2
values ('X','1','CR','4'),
('Y','2','10','5'),
('Y','3','CR','6'),
('W','1','30','7')
--Query2
select * from(
--Query1
select * from #Table1 union select * from #Table2) x
where E != '30' OR
(
E = '30' AND P+':'+R NOT IN
(
--Modified Query1
select P+':'+R from #Table1 where E = '10'
union
select P+':'+R from #Table2 y where E = '10'
)
)
order by Value

Resources