Related
I have a log file I need to either rank (but treating sequential and equal rows as ties), or merge sequential equal rows (based on specific column). My table looks like below, The Start and Stop are all being sequential (within the same ID window)
ID Start Stop Value
1 0 1 A
1 1 2 A
1 2 3 A
1 3 4 B
1 4 5 B
1 5 6 A
2 3 4 A
I have two approches to get what I need.
Approach 1: Rank (treating sequential rows with equal values in "Value" as ties) and using ID as partition.
This should give the output below. But how do I do the special rank: Treating sequential rows with equal values in "Value" as ties.
Select *,
rank() OVER (partition by id order by start, stop) as Rank,
XXX as SpecialRank
from Table
ID Start Stop Value Rank SpecialRank
1 0 1 A 1 1
1 1 2 A 2 1
1 2 3 A 3 1
1 3 4 B 4 2
1 4 5 B 5 2
1 5 6 A 6 3
2 3 4 A 1 1
Approach 2: Merge sequential rows with equal values in "Value".
This will shall create a table like below.
ID Start Stop Value
1 0 3 A
1 3 5 B
1 5 6 A
2 3 4 A
I don't know if this helps, but I have also a nextValue column that might help in this
ID Start Stop Value NextValue
1 0 1 A A
1 1 2 A A
1 2 3 A B
1 3 4 B B
1 4 5 B A
1 5 6 A A
2 3 4 A ...
Example-table:
CREATE TABLE #Table ( id int, start int, stop int, Value char(1), NextValue char(1));
INSERT INTO #Table values (1,0, 1, 'A', 'A');
INSERT INTO #Table values (1,1, 2, 'A', 'A');
INSERT INTO #Table values (1,2, 3, 'A', 'B');
INSERT INTO #Table values (1,3, 4, 'B', 'B');
INSERT INTO #Table values (1,4, 5, 'B', 'A');
INSERT INTO #Table values (1,5, 6, 'A', 'A');
INSERT INTO #Table values (2,3, 4, 'A', null);
Use a self join to an aggregate subquery from the full set, e.g.
with rankTable (id, value) as
( select 1, 'A' union all select 1, 'A' union all select 1, 'B' union all select 2, 'A')
select t2.* from rankTable t1 join (
select id, value, rank() over (partition by id order by value) as specialRank from
(
select distinct id, value
from rankTable
) t) t2 on t2.id =t1.id and t2.value = t1.value
id value specialRank
1 A 1
1 A 1
1 B 2
2 A 1
I'm trying to create a query that will return Total Claims reported in 0-3 days, 4-7 days, 8-14 days, and 15+
Select DATEDiff(DD,LossDate,DateReported) As TimeToReport,Count(ClaimId) As Num from LossRun
where PolicyNum='1234567890'
And PolTerm='201403'
Group By DATEDiff(DD,LossDate,DateReported)
order by DATEDiff(DD,LossDate,DateReported);
This is what i get
TimeToReport NumofClaims
0 5
1 3
2 1
3 4
4 3
5 2
6 2
7 2
8 1
12 1
13 1
14 2
15 2
48 1
52 1
107 1
121 1
147 1
533 1
Basically i want to see the total for 0-3, 4-7,8-14,and the rest,,,, timeToReport
You can try to use SUM with CASW WHEN
select
SUM(CASW WHEN TimeToReport <= 3 THEN NumofClaims ELSE 0 END) '0~3 day',
SUM(CASW WHEN TimeToReport >= 4 AND TimeToReport <=7 THEN NumofClaims END) '4-7 days',
SUM(CASW WHEN TimeToReport >= 8 AND TimeToReport <=14 THEN NumofClaims ELSE 0 END) '8-14 days',
SUM(CASW WHEN TimeToReport >= 15 THEN NumofClaims ELSE 0 END) '15+ day'
from (
Select DATEDiff(DD,LossDate,DateReported) As TimeToReport,Count(ClaimId) As Num
from LossRun
where PolicyNum='1234567890'
And PolTerm='201403'
Group By DATEDiff(DD,LossDate,DateReported)
) t
The most simple way is going to be by creating your own temp table which includes the min and max for each bucket and then joining to it.
declare #t table (OrderedID int, EmpID int, EffDate date, Salary money)
insert into #t
values
(1,1234,'20150101',1)
,(2,1234,'20160101',2)
,(3,1234,'20170101',8)
,(4,1234,'20180101',15)
,(1,2351,'20150101',17)
,(5,1234,'20190101',4)
,(5,1234,'20190101',2)
,(5,1234,'20190101',9)
declare #Bin table (MinVal int, MaxVal int)
insert into #Bin
values
(1,3)
,(4,6)
,(7,9)
,(10,15)
,(15,20)
,(20,25)
Select
B.MinVal,count(T.EmpID) as EmpsInBin
From #t T
inner join #Bin B on T.Salary between B.MinVal and B.MaxVal
group by B.MinVal
Output
MinVal EmpsInBin
1 3
4 1
7 2
10 1
15 2
I'm trying to write a incremental update statement using SQL Server 2012.
Current Data:
RecNo Budget_ID Item_Code Revision
---------------------------------------
1 16 xxx 2
2 16 xxx NULL
3 16 xxx NULL
12 19 yyy 3
13 19 yyy NULL
14 19 yyy NULL
15 19 yyy NULL
Expected result:
RecNo Budget_ID Item_Code Revision
---------------------------------------
1 16 xxx 2
2 16 xxx 1
3 16 xxx 0
12 19 yyy 3
13 19 yyy 2
14 19 yyy 1
15 19 yyy 0
However with following approach, I ended up with the result set as below.
UPDATE a
SET a.Revision = (SELECT MIN(b.Revision)
FROM [dbo].[foo] b
WHERE b.item_code = a.item_code
AND b.budget_id = a.budget_id
GROUP BY b.item_code ) -1
FROM [dbo].[foo] a
WHERE a.Revision is NULL
Result:
RecNo Budget_ID Item_Code Revision
---------------------------------------
1 16 xxx 2
2 16 xxx 1
3 16 xxx 1
12 19 yyy 3
13 19 yyy 2
14 19 yyy 2
15 19 yyy 2
Can anyone help me to get this right?
Thanks in advance!
Try this:
;with cte as
(select *, row_number() over (partition by budget_id order by rec_no desc) rn from dbo.foo)
update cte
set revision = rn - 1
Basically, since the revision value seems to be decreasing with increase in rec_no, we simply use the row_number() function to get row number of each record within the subset of all records with a particular budget_id, sorted in descending order of rec_no. Since the least possible value of row_number() will be 1, we subtract 1 so that the last record in the partition will have revision set to 0 instead 1.
You may test the code here
I found this example from this link https://stackoverflow.com/a/13629639/1692632
First you select MIN value to some variable and then you can update table by decreasing variable at same time.
DECLARE #table TABLE (ID INT, SomeData VARCHAR(10))
INSERT INTO #table (SomeData, ID) SELECT 'abc', 6 ;
INSERT INTO #table (SomeData) SELECT 'def' ;
INSERT INTO #table (SomeData) SELECT 'ghi' ;
INSERT INTO #table (SomeData) SELECT 'jkl' ;
INSERT INTO #table (SomeData) SELECT 'mno' ;
INSERT INTO #table (SomeData) SELECT 'prs' ;
DECLARE #i INT = (SELECT ISNULL(MIN(ID),0) FROM #table)
UPDATE #table
SET ID = #i, #i = #i - 1
WHERE ID IS NULL
SELECT *
FROM #table
I'm not sure if this will do the trick but you can try with
Update top(1) a
SET a.Revision = (Select MIN(b.Revision)
FROM [dbo].[foo] b where b.item_code = a.item_code and b.budget_id = a.budget_id
group by b.item_code ) -1
FROM [dbo].[foo] a
WHERE a.Revision is NULL
and repeat until there's no changes left
Update Data
set Revision = x.Revision
from
(select RecNo, Budget_ID, Item_Code, case when Revision is null then ROW_NUMBER() over(partition by Budget_ID order by RecNo desc) - 1 else Revision end Revision
from Data
) x
where x.RecNo = data.RecNo
You basically use ROW_NUMBER() to count backwards for each Budget_ID, and use that row number minus 1 where Revision is null. This is basically the same as Shree's answer, just without the CTE.
I have one table with 4 columns, say Rec_Id, as int, Name as varchar, ID1 as int, ID2 as int datatypes.
Create table:
Create table Sample
(
Rec_Id Int Not null,
Name varchar(30) null,
ID1 int null,
ID2 int null,
CONSTRAINT [PK_Sample] PRIMARY KEY NONCLUSTERED
(
[Rec_Id] ASC
)
Insert Statement:
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 1 ,'A',1,2)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 2 ,'A', 2,3)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 3 ,'A', 3 ,1)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 4 ,'B', 1 , 2)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 5 , 'B', 2 , 3)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 6 , 'B' , 3 , null)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 7 ,'C', 1 , 2)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 8 ,'C' , 2 , 3)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 9 ,'C' , 3 , 4)
Insert into sample (Rec_ID,Name,ID1,ID2) values (10 ,'C' , 5 , 1 )
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 11 ,'D', 2 , 3)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 12 , 'D', 3 , 4)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 13 , 'D' , 4 , 3)
My source data looks like this..
Rec_Id Name ID1 ID2
1 A 1 2
2 A 2 3
3 A 3 1
4 B 1 2
5 B 2 3
6 B 3 null --> Need to display this row in the output, because 1 is missing in ID2
7 C 1 2
8 C 2 3
9 C 3 4
10 C 5 1 --> Need to display this row in the output, because 4 is missing after 3 in ID1
11 D 2 3
12 D 3 4
13 D 4 3 --> Need to display this row in the output, because 2 is missing in ID2
My Output should look like below:
Rec_Id Name ID1 ID2
6 B 3
10 C 5 1
13 D 4 3
ok, let me explain in other words...In the above example right now 'Name' column has 4 groups, Name =A, B, C ,D.
A group- has 3 records which make one loop. I am saying it formed one loop becoz 3rd row value in ID2 column(ID2=1) matches with 1st row ID1 column(ID1=1).
Same loop concept implies for B , C and D groups.
--A - group records:
Name ID1 ID2
A 1 2
A 2 3
A 3 1
--B - group records:
Name ID1 ID2
B 1 2
B 2 3
B 3 null
B group - has 3 records which is broken loop. I am saying it is broken loop becoz 3rd row value in ID2 column(ID2=null) doesn't matches with 1st row ID1 column(ID1=1).
C- group records: Same loop concept implies for C group. If there is a break in the series need to display.
D- group records:
Name ID1 ID2
D 2 3
D 3 4
D 4 3
D group - has 3 records which is broken loop. I am saying it is broken loop becoz 3rd row value in ID2 column(ID2=3) doesn't matches with 1st row ID1 column(ID1=2).
So, I need t-sql to get above output.
Thanks in advance,
RH
Here is one way to answer your question. You may want to break it up some depending on your business rules. Based on your sample I could see that the sum of ID1 column equals sum of ID2 column. The rules depend on the first and last values in the ID columns so I figured those out too (used MIN and MAX to get those and add to each row so I could filter at the end).
WITH errs AS (
SELECT s.Rec_id, s.[Name], s.ID1, s.ID2, p.startId, p.lastId, p.TotID1, p.TotID2, 0 AS artificialID
FROM Sample AS s
INNER JOIN (
-- general filter for which groups have problems, assumes sum of ID1 column equals sum of ID2 column (optimize query in case this is bigger data set)
SELECT s0.[Name], SUM(ISNULL(s0.ID1,0)) AS TotID1, SUM(ISNULL(s0.ID2,0)) AS TotID2
, MIN(s0.ID1) AS startId
, MAX(s0.ID1) AS lastId
FROM Sample AS s0
GROUP BY s0.[Name]
HAVING SUM(ISNULL(s0.ID1,0)) <> SUM(ISNULL(s0.ID2,0))) AS p ON s.[Name] = p.[Name]
),
-- get a list of those with a missing row when the last row in the group exists and has the right ID2 value
er1 AS (
SELECT * FROM (
SELECT e.Rec_id, e.[Name], e.ID1, e.ID2, e.startId, e.lastId, e.totID1, e.TotID2, ROW_NUMBER() OVER (PARTITION BY e.[Name] ORDER BY e.ID1) AS artificialID
FROM errs AS e
WHERE e.[Name] NOT IN (SELECT o.[Name] FROM errs AS o WHERE (ISNULL(o.ID1,0) = 0 OR ISNULL(o.ID2,0) = 0))
) AS er1a
WHERE er1a.ID1 <> er1a.artificialID
-- get a list of those where the last row exists and ID2 is correct, IE, something missing in the middle
AND er1a.[Name] IN (SELECT o1.[Name] FROM errs AS o1 WHERE (ISNULL(o1.ID1,0) = lastId AND ISNULL(o1.ID2,0) = o1.startId))
)
SELECT e.*
FROM errs AS e
WHERE (ISNULL(e.ID1,0) = 0 OR ISNULL(e.ID2,0) = 0)
UNION
SELECT e1.*
FROM er1 AS e1
UNION
-- the third group - where the last row does not have the right ID2 on it
SELECT e2.*
FROM errs AS e2
WHERE (ISNULL(e2.ID1,0) = lastId AND ISNULL(e2.ID2,0) <> e2.startId)
ORDER BY [Name],ID1, ID2
i am using sql server 2008, in which i have some trouble i can not find one column
TblMaster
ID Name City
1 Hiren Juanagadh
2 Ashish Gandhinagar
2 Mayur Ahmedabad
3 Hitesh Junagadh
4 Nipun Ahmedabad
4 Vivek Rajkot
4 Samir Surat
5 Sagar Vadodara
Now i want Anoter column CountId so i want output like below
TblMaster
ID Name City CountId
1 Hiren Juanagadh 0
2 Ashish Gandhinagar 2
2 Mayur Ahmedabad 2
3 Hitesh Junagadh 0
4 Nipun Ahmedabad 3
4 Vivek Rajkot 3
4 Samir Surat 3
5 Sagar Vadodara 0
Means if Id column only one then CountId = 0
If Id column more than one then CountId = Count of Idcolumn
Prepare table
declare #T table (
id int,
Name nvarchar(6),
City nvarchar(20))
insert #T values
( 1 , 'Hiren', 'Juanagadh'),
( 2 , 'Ashish', 'Gandhinagar'),
( 2 , 'Mayur', 'Ahmedabad'),
( 3 , 'Hitesh', 'Junagadh'),
( 4 , 'Nipun', 'Ahmedabad'),
( 4 , 'Vivek', 'Rajkot'),
( 4 , 'Samir', 'Surat'),
( 5 , 'Sagar', 'Vadodara')
Select statement
without 1->0 correction
SELECT *, CountID = count(*) over (Partition by ID)
from #T
with 1->0 correction
select id, Name,City,CountID = case when CountID = 1 then 0 else CountID end
from (
SELECT *, CountID = count(*) over (Partition by ID)
from #T )
RES
Try this query:::
select *,(case when (select count(id) from TblMaster )=1
then 0 else (select count(id) from TblMaster) end) as count
from tblmaster