# cursor to split the column # - sql

I have a table
WS_ID WS_WEBPAGE_ID WS_SPONSORS_ID WS_STATUS WS_CREATEDTS
2 3 2 N 2012-06-07 15:32:00
3 3 3 N 2012-06-07 15:37:00
4 3 4 Y 2012-06-07 15:41:00
5 1 1 Y 2012-06-07 16:05:00
6 2 1 Y 2012-06-07 16:05:00
7 2 4 Y 2012-06-07 16:05:00
8 4 1 Y 2012-06-07 16:05:00
9 1 3 Y 2012-06-07 16:05:00
10 1 2 Y 2012-06-07 16:05:00
11 1 4 Y 2012-06-07 16:05:00
12 2 3 Y 2012-06-07 16:05:00
13 2 3 Y 2012-06-07 16:05:00
14 2 1 Y 2012-06-07 16:05:00
24706 3 8,7,9,5,5 NULL NULL
I wrote a cursor and calling the split function in to that cursor to split the last record
Declare #splitc varchar(250)
Declare splitcursor cursor for
select ws_sponsors_id from dbo.TBL_WD_SPONSORS
open splitcursor
fetch next from splitcursor into #splitc
while(##FETCH_STATUS = 0)
begin
print '#splitcursor'
--select * from dbo.Comma_Split(#ws_sponsors_id,',')
select dbo.Comma_Split(ws_sponsors_id,',') from dbo.TBL_WD_SPONSORS where ws_id = 24706
--select * from dbo.TBL_WD_SPONSORS where WS_SPONSORS_ID in(select * from dbo.Comma_Split(ws_sponsors_id,','))
fetch next from splitcursor into #splitc
end
close splitcursor
deallocate splitcursor
And I am getting the Error
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.Comma_Split", or the name is ambiguous.
WS_ID WS_WEBPAGE_ID WS_SPONSORS_ID WS_STATUS WS_CREATEDTS
24706 3 8,7,9,5,5 NULL NULL
But I need the Output
WS_ID WS_WEBPAGE_ID WS_SPONSORS_ID WS_STATUS WS_CREATEDTS
24706 3 8 NULL NULL
24707 3 7 NULL NULL
24708 3 9 NULL NULL
24709 3 5 NULL NULL
24710 3 5 NULL NULL
How to get the Output
Help me out.

Why not re-architect your tables so you only have 1 value entered in your WS_SPONSORS_ID column so it's a foreign-key relationship, then you wouldn't have to do this split function.

It looks like the function you're trying to use does not exist on the database you're running it on. For instance, try this and you'll get the same error:
SELECT dbo.This_Function_Most_Certainly_Doesnt_Exist('Unless you''re trying to break my example.')
This will prove if it is there or not so that you don't have to take my word for it. Run this on the database that you're running your cursor based query on:
SELECT * FROM INFORMATION_SCHEMA.ROUTINES R WHERE R.ROUTINE_NAME = 'Comma_Split'
If you don't get any rows back, that is because the function doesn't exist there. Either you're on the wrong database, the wrong version, you need to run the CREATE FUNCTION on it, or something like that.
EDIT: By the way, as for how to solve the actual problem: Don't use a cursor. A cursor is used as a form of iteration over a data result set. In your cursor you're selecting the value for a single row:
select dbo.Comma_Split(ws_sponsors_id,',') from dbo.TBL_WD_SPONSORS where ws_id = 24706
The way you have it, you'd call that function, on that row, once for every row on the table. Here's a good example of a split function: http://praveenbattula.blogspot.com/2010/06/best-split-udf-function-with-delimeter.html
Using that you would just need to write:
SELECT dbo.fnStringSplitter(ws_sponsors_id, ',') FROM dbo.TBL_WT_SPONSORS WHERE ws_id = 24706

Related

Dynamic column names in bigquery procedure

How can I dynamically assign the Column Names in Bigquery Procedure. I have a counter declared in my procedure:
DECLARE counter int64 default 1;
And in the procedure, I use while loop to keep self joining till the time there are no more parents remaining. My only question is to determine a way to find the dynamic column names. like manager_id_{#counter} based on the hierarchy available.
I have the following tables available:
Table 1:
emp_id
manager_id
1
1
2
1
3
2
4
3
10
10
20
10
30
20
My Output:
emp_id
manager_id
manager_id_1
manager_id_2
manager_id_3
manager_id_4
1
1
1
NULL
NULL
NULL
2
1
1
2
NULL
NULL
3
2
1
2
3
NULL
4
3
1
2
3
4
10
10
10
NULL
NULL
NULL
20
10
10
20
NULL
NULL
30
20
10
20
30
NULL
I am able to come up with the logic, the only missing piece is the column name. I saw many posts which were related to SQL and other DBMS. But couldn't find something for BigQuery.
DECLARE counter int64 default 1;
execute immediate "Select " || 5 || " as manager_id_" || counter
The way I resolved it was using Jinja like scripting.

How to Update column Num with an incremental number in Master-Detail with row_number()?

I want to update my column Acc.DocHeader.Num and Acc.DocItem.Num with an incremental number. I have:
UPDATE x
SET x.Num = x.newNum,x.iNum=x.newNum
FROM (
SELECT Num,iNum, ROW_NUMBER() OVER (ORDER BY DocCreateDate ,DailyNum) AS newNum
FROM (SELECT h.Num,h.DocCreateDate,h.DailyNum,i.Num iNum FROM Acc.DocHeader h INNER JOIN Acc.DocItem i ON i.DocHeaderRef = h.Id WHERE h.Year = 1395 AND h.BranchRef = 1) AS header
) x
Why do I get Derived table 'x' is not updatable because the modification affects multiple base tables?
DocHeader Table :
Id Num Year DocCreateDate
-------------------------------------------------------
1 NULL 1396 2016-03-20
2 NULL 1395 2016-04-02
3 NULL 1395 2016-04-05
4 NULL 1395 2016-04-10
DocItem Table:
Id Num DocHeaderRef
----------------------------------------------
1 NULL 1
2 NULL 1
3 NULL 1
4 NULL 4
5 NULL 4
6 NULL 3
7 NULL 3
8 NULL 3
output:
DocHeader Table:
Id Num Year DocCreateDate
-------------------------------------------------------
1 1 1396 2016-03-20
2 1 1395 2016-04-02
3 2 1395 2016-04-05
4 3 1395 2016-04-10
DocItem Table:
Id Num DocHeaderRef
----------------------------------------------
1 1 1
2 1 1
3 1 1
4 3 4
5 3 4
6 4 3
7 4 3
8 4 3
You are attempting to update columns from two different tables in a single update statement:
Num comes from Acc.DocHeader
iNum comes from Acc.DocItem
In SQL Server, you can only update one table at a time in an UPDATE.
You can update multiple tables in a single transaction. You can also use the OUTPUT clause to capture the values from the rows being updated. This answers the question of why you cannot do what you want.
I find your query a bit hard to follow -- and your question doesn't explain what you are trying to do -- so it is hard to suggest alternatives.

Using temporary extended table to make a sum

From a given table I want to be able to sum values having the same number (should be easy, right?)
Problem: A given value can be assigned from 2 to n consecutive numbers.
For some reasons this information is stored in a single row describing the value, the starting number and the ending number as below.
TABLE A
id | starting_number | ending_number | value
----+-----------------+---------------+-------
1 2 5 8
2 0 3 5
3 4 6 6
4 7 8 10
For instance the first row means:
value '8' is assigned to numbers: 2, 3 and 4 (5 is excluded)
So, I would like the following intermediairy result table
TABLE B
id | number | value
----+--------+-------
1 2 8
1 3 8
1 4 8
2 0 5
2 1 5
2 2 5
3 4 6
3 5 6
4 7 10
So I can sum 'value' for elements having identical 'number'
SELECT number, sum(value)
FROM B
GROUP BY number
TABLE C
number | sum(value)
--------+------------
2 13
3 8
4 14
0 5
1 5
5 6
7 10
I don't know how to do this and didn't find any answer on the web (maybe not looking with appropriate key words...)
Any idea?
You can do what you want with generate_series(). So, TableB is basically:
select id, generate_series(starting_number, ending_number - 1, 1) as n, value
from tableA;
Your aggregation is then:
select n, sum(value)
from (select id, generate_series(starting_number, ending_number - 1, 1) as n, value
from tableA
) a
group by n;

MDX: iif condition on the value of dimension

I have 1 Virtual cube consists of 2 cubes.
Example of fact table of 1st cube.
id object_id time_id date_id state
1 10 2 1 0
2 11 5 1 0
3 10 7 1 1
4 10 3 1 0
5 11 4 1 0
6 11 7 1 1
7 10 8 1 0
8 11 5 1 0
9 10 7 1 1
10 10 9 1 2
Where State: 0 - Ok, 1 - Down, 2 - Unknown
For this cube I have one measure StateCount it should count States for each object_id.
Here for example we have such result:
for 10 : 3 times Ok , 2 times Down, 1 time Unknown
for 11 : 3 times Ok , 1 time Down
Second cube looks like this:
id object_id time_id date_id status
1 10 2 1 0
2 11 5 1 0
3 10 7 1 1
4 10 3 1 1
5 11 4 1 1
Where Status: 0 - out, 1 - in. I keep this in StatusDim.
In this table I keep records that should not be count. If object have status 1 that means that I have exclude it from count.
If we intersect these tables and use StateCount we will receive this result:
for 10 : 2 times Ok , 1 times Down, 1 time Unknown
for 11 : 2 times Ok , 1 time Down
As far as i know, i must use calculated member with IIF condition. Currently I'm trying something like this.
WITH MEMBER [Measures].[StateTimeCountDown] AS(
iif(
[StatusDimDown.DowntimeHierarchy].[DowntimeStatus].CurrentMember.MemberValue
<> "in"
, [Measures].[StateTimeCount]
, null )
)
The multidimensional way to do this would be to make attributes from your state and status columns (hopefully with user understandable members, i. e. using "Ok" and not "0"). Then, you can just use a normal count measure on the fact tables, and slice by these attributes. No need for complex calculation definitions.

Collating data in SQL Server

I have the following data in SQL Server
St 1 2 3 4 5 6 7 8
===========================================
603 2 5 1.5 3 0 0 0 0
603 0 0 0 0 2 1 3 5
As I insert the data by batches, each batch only has 4 columns each and I want to collate the data to the following
St 1 2 3 4 5 6 7 8
===========================================
603 2 5 1.5 3 2 1 3 5
but most of the threads I see here are about concatenating strings of a single column.
Anyone has any idea on how to collate or even merge different rows into a single row.
You can use the group by and Sum key word of the t-SQL
SELECT SUM(COL1) , SUM(COL2)..... FROM tbl GROUP BY ST
You can use the GROUP BY clause and aggregate with SUM fields 1-8 :
SELECT St, SUM(1), SUM(2),.. FROM tbl GROUP BY St