KDB+ Q Create a looping/iteration id column - loops

I have a kdb/q question I would like some help with. Please see the table below
`A B Run
99 newcol Start
99 newcol Start
99 newcol Start
99 newcol During
99 newcol During
99 newcol End
99 newcol End
99 newcol End
99 newcol Start
99 newcol During
99 newcol End
80 newcol2 Start
80 newcol2 End
80 newcol End`
In the table above there is 3 columns A,B,Run I would ideally like to create a run id column
col A is a unique identifier
col b is not unique
What I would like to create below
`A B Run Run-ID
99 newcol Start 99-1
99 newcol Start 99-1
99 newcol Start 99-1
99 newcol During 99-1
99 newcol During 99-1
99 newcol End 99-1
99 newcol End 99-1
99 newcol End 99-1
99 newcol Start 99-2
99 newcol During 99-2
99 newcol End 99-2
80 newcol2 Start 80-1
80 newcol2 End 80-1
80 newcol End 80-1`
Would it be possibly to iterate/loop this kind of logic in q? any help is grateful thankyou!
How to id a complete run to create an id?
A run begins with the word Start
A run ends with the word End
If a run has consecutive starts at the beginning and col A is the same then this is the same run and the id should stay the same until the run ends
A new id should only be generated after and end and the next row is a start ie if there is consecutive ends the id should keep looping until there is a new start

Provide the sample in a format more easily added to a kdb+ table if you can.
Makes it easier for responders to help you:
tab:flip `A`B`Run!flip (
(99 ;`newcol ;`Start);
(99 ;`newcol ;`Start);
(99 ;`newcol ;`Start);
(99 ;`newcol ;`During);
(99 ;`newcol ;`During);
(99 ;`newcol ;`End);
(99 ;`newcol ;`End);
(99 ;`newcol ;`End);
(99 ;`newcol ;`Start);
(99 ;`newcol ;`During);
(99 ;`newcol ;`End);
(80 ;`newcol2 ;`Start);
(80 ;`newcol2 ;`End);
(80 ;`newcol ;`End))
One way to perform what you want:
update RunID:{`$x,"-",y}'[string[A];string sums 1=deltas Run=`Start] by A from tab
A B Run RunID
-----------------------
99 newcol Start 99-1
99 newcol Start 99-1
99 newcol Start 99-1
99 newcol During 99-1
99 newcol During 99-1
99 newcol End 99-1
99 newcol End 99-1
99 newcol End 99-1
99 newcol Start 99-2
99 newcol During 99-2
99 newcol End 99-2
80 newcol2 Start 80-1
80 newcol2 End 80-1
80 newcol End 80-1
Note I named the column RunID not Run-ID as using - in column names is not recommended. - is used for minus and causes errors if you try to select a column with it in it's name.

Related

how to remove specific pattern from string in sql

I have so many strings like below
COLGATE GRF 75 GMS (Rs. 65)( 72 PCS )
COLGATE GRF 100 GM (RS.90) - RELAUNCH( 72 PCS )
COLGATE GRF 100 GM (RS.88) COLLECTIBLES( 72 PCS )
COLGATE GRF 100 GMS (Rs. 85)( 72 PCS )
and want to remove (Rs. 65) and so on from string in sql. What I have try is below.
select SUBSTRING ('COLGATE GRF 75 GMS (Rs. 65)( 72 PCS )',0,CHARINDEX('(','COLGATE GRF 75 GMS (Rs. 65)( 72 PCS )'))
You can Use Both SUBSTRING & REPLACE functions to achieve this:
DECLARE #STR VARCHAR(MAX)='COLGATE GRF 75 GMS (RS. 65)( 72 PCS )'
SELECT SUBSTRING (#STR,CHARINDEX('(',#STR),(CHARINDEX(')',#STR)-CHARINDEX('(',#STR))+1)
SELECT REPLACE (#STR,SUBSTRING (#STR,CHARINDEX('(',#STR),(CHARINDEX(')',#STR)-CHARINDEX('(',#STR))+1),'')
Output:
COLGATE GRF 75 GMS ( 72 PCS )
Reading your intentions as removing the first set of brackets from the string (you say nothing about all bracket) then that's simply a single statement:
declare #s varchar(100)='COLGATE GRF 100 GM (RS.88) COLLECTIBLES( 72 PCS )'
select Left(#s,CharIndex('(',#s)-1)+Right(#s,Len(#s)-charIndex(')',#s))
Find the start and end of the parenthesis. For start, find using (Rs. After that use STUFF() to remove it. This will works for (Rs ??) as the first occurrence or not. Note that it will only remove the first occurrence.
SELECT *,
STUFF(col, s, e - s + 1, '')
FROM tbl t
CROSS APPLY
(
SELECT s = CHARINDEX('(Rs', col)
) s
CROSS APPLY
(
SELECT e = CHARINDEX(')', col, s)
) e
dbfiddle demo

Trying to Replace While loop that executes based on a value in a row from a view to a Set query

I am trying to create a query that will give me random rows from a view (view_XYZ) based on the value in the SampleSizeByRow (in view_SampleSizeByRow) then it inserts the random value from view_XYZ into tbl_Randomization.
view_SampleSizeByRow looks like
ID_x SampleSizeByRow
49 1
87 1
47 6
41 2
247 13
96 3
99 1
31 1
91 13
DECLARE #CurrSize AS INT
DECLARE #CurrID AS INT
DECLARE #SampleByValTbl AS TABLE(
Samplesize INT,
ID INT
)
INSERT INTO #SampleByValTbl (
Samplesize
, ID
)
SELECT SampleSizeByRow, ID_x
FROM view_SampleSizeByRow
ORDER BY ID_x;
WHILE(1=1) -- Infinite Loop until it is broken
BEGIN
SET #CurrID = NULL -- Reset pointer variables
SET #CurrSize = NULL
SELECT TOP(1) #CurrID = ID
FROM #SampleByValTbl
SELECT TOP(1) #CurrSize = Samplesize
FROM #SampleByValTbl
IF (#CurrID IS NULL OR #CurrSize IS NULL) -- End loop if there are no ID's to go through
BREAK
IF #CurrSize <= 0
BEGIN
DELETE TOP(1) FROM #SampleByValTbl
CONTINUE
END
ELSE
BEGIN
WHILE #CurrSize > 0
BEGIN
INSERT INTO tbl_Randomization (
ID_x
, Num_y
)
SELECT TOP(1) ID_x
, Num_y
FROM view_XYZ
ORDER BY NEWID() -- Random Selection
SET #CurrSize = #CurrSize - 1
END
DELETE TOP(1) FROM #SampleByValTbl -- To shorten the size of the table each time we parse through it
END
END
Results should be something like the table below
ID_x Num_y
41 4888084
41 4895898
46 4889509
46 4889493
47 4891612
47 4898679
47 4889485
47 4902432
49 4893435
91 4898447
91 4898892
91 4895738
91 4888350
91 4898920
91 4886422
91 4899137
91 4895741
91 4886918
91 4894146
91 4888301
91 4888383
91 4882095
91 4898402
96 4893927
96 4893738
96 4887504
99 4893713
247 4897332
247 4902343
247 4897769
247 4895529
247 4885333
247 4895512
247 4895488
247 4885279
247 4893031
247 4891872
247 4896523
247 4901417
247 4885181
247 4897541
...
I have tried to use CTE and various joins but I can't figure out how to code them so they return the same results.
If I followed you correctly, you want to select sample_size random values from view_XYZ for each id_x listed in view_SampleSizeByRow.
Here is an approach that uses a recursive query to generate the rows, then a correlated subquery to retrieve the random value:
with cte as (
select id_x, sample_size - 1 from view_SampleSizeByRow where sample_size > 0
union all
select id_x, sample_size - 1 from cte where sample_size > 0
)
insert into tbl_Randomization (id_x, num_y)
select
id_x,
(select top (1) num_y from view_XYZ v where v.id_x = c.id_x order by newid())
from cte c

This nested cursor loop is looping forever

I have a table that contains desired table names, column names, column data types, and column data length that I want to create a new database with.
right now I am working nesting some cursors to print out each unique table name and their accompanying column names.
when I run the below code it loops forever. What am I missing?
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE spC1 CURSOR
FOR
SELECT DISTINCT tblNm
FROM tblDef
DECLARE #curTabNm AS varchar(60) = ''
DECLARE #curColNm as varchar(60) = ''
DECLARE #Outer_Loop AS int = 0
OPEN spC1
FETCH NEXT FROM spC1 INTO #curTabNm
WHILE #Outer_Loop = 0
PRINT #curTabNm
BEGIN
DECLARE spC2 CURSOR
FOR
SELECT colNm FROM tblDef
WHERE tblNm = #curTabNm
open spC2
FETCH NEXT FROM spC2 INTO #curColNm
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #curColNm
FETCH NEXT FROM spC2 INTO #curColNm
END
CLOSE spC2
DEALLOCATE spC2
FETCH NEXT FROM spC1 INTO #curTabNm
SET #Outer_Loop = 1
END
CLOSE spC1
DEALLOCATE spC1
END
The first step here is to create consumable ddl and sample data. I left off some of the datatypes that you said are not yet defined from your client.
if OBJECT_ID('tempdb..#Something') is not null
drop table #Something
create table #something
(
tblNm sysname
, colNm sysname
, colTyp varchar(20)
, colLen int
, colReq bit
)
insert #something(tblNm, colNm, colTyp, colLen, colReq)
values
('account', 'studentNum', 'String', 15, 0)
,('account', 'employNum', 'String', 15, 0)
,('account', 'firstName', 'String', 35, 0)
,('account', 'lastName', 'String', 40, 0)
,('assignment', 'vSource', 'String', 255, 0)
,('assignment', 'schoolNum', 'String', 7, 1)
,('assignment', 'calendarName', 'String', 30, 1)
,('assignment', 'courseNum', 'String', 13, 1)
Now that we have data to work with we can work on the actual query here. This uses the FOR XML trick to generate a delimited list. In this case the delimited list is our columns. We then use some grouping in the outer query to get each table. The code looks like this.
declare #SQL nvarchar(max) = ''
select #SQL = #SQL + 'create table [' + tblNm + '](' + STUFF((select ', [' + s2.colNm + '] ' + Case s2.colTyp when 'String' then 'varchar' end
+ isnull('(' + convert(varchar(4), s2.colLen) + ') ', ' ')
+ case s2.colReq when 1 then 'NOT ' else '' end + 'NULL'
from #something s2
where s2.tblNm = s.tblNm
order by s2.colNm
FOR XML PATH('')), 1,1, '') + ');'
from #something s
group by s.tblNm
select #SQL
--exec sp_executesql #SQL
That is it. The whole thing. When you are happy with the contents of the #SQL variable you can simply uncomment the execute statement and it will create your tables.
As stated previously the load on the system is not likely going to be huge for using cursors here but once you learn this type of technique it really is a lot simpler than cursors and it is far less code.
Check this out
BEGIN
DECLARE spC1 CURSOR
FOR
SELECT DISTINCT tblNm
FROM tblDef
DECLARE #curTabNm AS varchar(60) = ''
DECLARE #curColNm as varchar(60) = ''
DECLARE #Outer_Loop AS int = 0
OPEN spC1
FETCH NEXT FROM spC1 INTO #curTabNm
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE spC2 CURSOR FOR
SELECT colNm FROM tblDef
WHERE tblNm = #curTabNm
open spC2
FETCH NEXT FROM spC2 INTO #curColNm
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #curColNm
FETCH NEXT FROM spC2 INTO #curColNm
END
CLOSE spC2
DEALLOCATE spC2
FETCH NEXT FROM spC1 INTO #curTabNm
END
CLOSE spC1
DEALLOCATE spC1
END
Ah it was at lines
WHILE #Outer_Loop = 0
PRINT #curTabNm
are in opposite order. whoops!
tblNm colNm colTyp colLen colReq
account personID Decimal NULL 0
account studentNum String 15 0
account employNum String 15 0
account firstName String 35 0
account lastName String 40 0
account birthDate String NULL 0
account accountNumber Decimal NULL 0
account accountPIN String 50 0
account reminder String 5 0
account remAmount String 5 0
account blockConcessions String 5 0
account blockAlaCarte String 5 0
account singlePurch String 5 0
account eligibility String 20 0
account certifiedType String 20 0
account startDate String NULL 0
account endDate String NULL 0
account beginningBalance String 12 0
account vSource String 255 0
assignment vSource String 255 0
assignment schoolNum String 7 1
assignment calendarName String 30 1
assignment courseNum String 13 1
assignment sectionNum Int 5 1
assignment groupName String 50 1
assignment assignmentName String 50 1
assignment abbreviation String 5 1
assignment assignmentSeq String 5 0
assignment totalPoints String 5 1
assignment curveName String 80 0
assignment dueDate String NULL 1
assignment assignedDate String NULL 0
assignment multiplier String 6 0
assignment description String 255 0
assignment objectives String 255 0
assignment references String 255 0
assignmentScore schoolNum String 7 1
assignmentScore calendarName String 30 1
assignmentScore courseNum String 13 1
assignmentScore sectionNum Int 5 1
assignmentScore groupName String 50 1
assignmentScore assignmentName String 50 1
assignmentScore studentNum String 15 1
assignmentScore score String 20 1
assignmentScore flag String 20 0
assignmentScore comments String 250 0
assignmentScore vSource String 255 0
attendance vSource String 255 0
attendance schoolNum String 7 1
attendance calendarName String 30 1
attendance studentNum String 15 1
attendance date DateTime NULL 1
attendance scheduleSeq String 3 0
attendance periodSeq Int 3 0
attendance code String NULL 1
attendance comments String 50 0
attendanceExcuse schoolNum String 7 1
attendanceExcuse calendarName String 30 1
attendanceExcuse code String NULL 1
attendanceExcuse description String 50 1
attendanceExcuse status String 20 1
attendanceExcuse excuse String 20 1
attendanceExcuse vSource String 255 0
behaviorEvent vSource String 255 0
behaviorEvent eventType String 100 1
behaviorEvent incidentID Int 0 1
behaviorEvent eventID Int 50 1
behaviorEvent referralEmployNum String 15 0
behaviorEvent adminEmployNum String 15 0
behaviorEvent weaponCode String 2 0
behaviorEvent calendarName String 30 1
behaviorResolution eventID String 50 1
behaviorResolution studentNum String 15 1
behaviorResolution resolutionDate DateTime NULL 1
behaviorResolution resolutionTime String 20 1
behaviorResolution endDate DateTime NULL 0
behaviorResolution ParentInvolvementComment String 255 0
behaviorResolution ParentCode Int NULL 0
behaviorResolution AssignedAlternateEducation String 50 0
behaviorResolution AdjudicationCode String 50 0
behaviorResolution ArrestCode String 50 0
behaviorResolution LLEOffice String 50 0
behaviorResolution LLENotified String 50 0
behaviorResolution Duration Int NULL 0
behaviorResolution adminEmployNum String 50 0
behaviorResolution DisciplinaryActionComment String 255 0
behaviorResolution resolutionType String 50 0
behaviorResolution vSource String 255 0
behaviorRole vSource String 255 0
behaviorRole OffenderType String NULL 0
behaviorRole injury String NULL 1
behaviorRole relationshipToSchool String NULL 1
behaviorRole InfractionComment String NULL 0
behaviorRole ReceivedServices Boolean NULL 0
behaviorRole WeaponCount Int NULL 0
behaviorRole WeaponDetectedMethod String NULL 0
behaviorRole victimType String NULL 0
behaviorRole eventID String 50 1
behaviorRole studentNum String 15 1
behaviorRole role String 15 1
behaviorRole demerits String 5 0
bus number String 10 1
bus description String 250 0
bus contracted String 5 0
bus vSource String 255 0
busRider vSource String 255 0
busRider schoolNum String 7 1
busRider calendarName String 30 1
busRider studentNum String 15 1
busRider inBusNumber String 10 0
busRider inTime String 20 0
busRider inBusStop String 20 0
busRider outBusNumber String 10 0
busRider outTime String 20 0
busRider outBusStop String 20 0
busRider lateBus String 10 0
busRider transMiles String 7 0

How to get weekly report with weekstart date and end date as column name in SQL Server

Data:
Date Productivity
-------------------------
01/06/2015 50
01/06/2015 50
02/06/2015 60
02/06/2015 50
01/06/2015 55
03/06/2015 50
03/06/2015 50
03/06/2015 50
04/06/2015 50
04/06/2015 50
04/06/2015 50
05/06/2015 50
05/06/2015 50
05/06/2015 50
06/06/2015 50
06/06/2015 50
08/06/2015 50
08/06/2015 50
09/06/2015 50
10/06/2015 50
11/06/2015 50
12/06/2015 50
13/06/2015 50
13/06/2015 50
13/06/2015 50
I want output like this, which contains average of week productivity:
Date Productivity
------------------------------------------
01/06/2015-06/06/2015 50.93
08/06/2015-13/06/2015 50
SqlFiddle
SELECT
[date] = CONVERT(NVARCHAR(100), MIN([date]), 103 ) + '-' +
CONVERT(NVARCHAR(100), MAX([date]), 103 )
,[Productivity] = CAST(AVG(Productivity * 1.0) AS DECIMAL(10,2))
FROM tab
GROUP BY DATEPART(wk, [Date]);
EDIT:
Added calculating week start and end if data doesn't contain all days.
SqlFiddleDemo2
set datefirst 1;
SELECT
[date] = CONVERT(NVARCHAR(100), DATEADD(dd, -(DATEPART(dw, MIN([date]))-1), MIN([date])), 103 ) + ' - ' + CONVERT(NVARCHAR(100), DATEADD(dd, 7-(DATEPART(dw, MAX([date]))), MAX([date])), 103 )
,[Productivity] = CAST(AVG(Productivity * 1.0) AS DECIMAL(10,2))
FROM tab
GROUP BY DATEPART(wk, [Date]);
Lad's answer will do what you needs. But if there needs the weeks which don't have entry as Avg '0' you may have to write a cte for finding out the weeks which should left join with lad's answer

SQL Server - Update data

I have an table with this structure (example) ORIGNTABLE:
ID IDParent
80 0
81 80
82 0
83 82
Then I make a duplicate of this data obtaining the following data:
ID IDParent
80 0
81 80
82 0
83 82
---- duplicated data ---
84 0
85 80
86 0
87 82
on the other hand, with the duplication of data also get a temporary table with the following information AUXTABLE:
OldID NewID OldParentID
80 84 0
81 85 80
82 86 0
83 87 82
So, my problem is update the new data, specifically, the IDParent. I'm failing to do this.
I pretend the final data like that:
ID IDParent
80 0
81 80
82 0
83 82
---- duplicated data ---
84 0
85 **84**
86 0
87 **86**
Anyone can help me to update the data? i'm trying many options but none work:
1st try
UPDATE ORIGINTABLE
SET IDParent = AT.NewID
FROM ORIGINTABLE OT
INNER JOIN AUXTABLE AT ON AT.NewID=OT.ID
AND AT.OldParentID=OT.IDParent
2st try
UPDATE ORIGINTABLE
SET IDParent =AT.NewID
FROM ORIGINTABLE OT
INNER JOIN AUXTABLE AT ON AT.OldParentID=OT.ID
The trick is to join AUXTABLE twice. One instance will act as a filter, so that only new rows become updated. The other instance will provide the necessary mapping between old and new ID values.
This is the query:
UPDATE ot
SET ot.IDParent = mapping.NewID
FROM ORIGINTABLE AS ot
INNER JOIN AUXTABLE AS filter ON filter.NewID = ot.ID
INNER JOIN AUXTABLE AS mapping ON mapping.OldID = ot.IDParent
;

Resources