Related
I have an SP which accepts the Inputtable as parameter, My Inputtable is as shown in the code
`create table inputTable ( id int,ItemQty varchar(100))
insert into inputTable(id, ItemQty) values(1,'a,b,c')
insert into inputTable(id, ItemQty) values(2,'x,y')
insert into inputTable(id, ItemQty) values(3,'l,m,n,o,p')
insert into inputTable(id, ItemQty) values(4,'a,b')
insert into inputTable(id, ItemQty) values(5,'m')`
and SP i have written is like below
`ALTER PROCEDURE [dbo].[Column_Dynamics] (#tablename varchar(50))
AS
BEGIN
-----
declare #maxcount as int
set #maxcount='select MAX(len(ITEMQTY) - len(replace(ITEMQTY, '','', '''')) +1) from '+#tablename
exec('select MAX(len(ITEMQTY) - len(replace(ITEMQTY, '','', '''')) +1) from '+#tablename)
print #maxcount
exec #maxcount
print #maxcount
declare #var varchar(100)
IF EXISTS(SELECT * FROM sys.columns WHERE object_id = Object_id(#tablename))
set #var='alter table '+ #tablename +' ADD column QTY1'
exec(#var)
select * from #tablename
select max(len(ItemQty))-max(len(replace(ItemQty, ',', ''))-1) from inputtable
END`
My table is :
step 1 ) I want to add the columns dynamically to inputtable like QTY1,QTY2,QTY3,QTY4,QTY5 because maximum count of ItemQty column is 5, by considering comma as delimiter as shown in figure1
**step 2) ** Parse values in the respective columns(by considering the delimiter comma (,).as shown in figure2
Later SP: I got till here, But Not getting the second step, that is update Parse values in the respective columns.
ALTER PROCEDURE dynamic_tbl (#tablename varchar(50))
AS
BEGIN
DECLARE #ColumnCount int
DECLARE #rowcount TABLE (Value int);
INSERT INTO #rowcount
EXEC('select MAX(len(ITEMQTY) - len(replace(ITEMQTY, '','', '''')) +1) from '+#tablename);
SELECT #ColumnCount = Value FROM #rowcount;
Declare #ColumnName nvarchar(10)='qty_'
Declare #count int =0
IF(#ColumnCount>0)
BEGIN
IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'dyn_tbl'))
BEGIN
DROP TABLE dyn_tbl
END
select * into dyn_tbl from inputtable
SET #count=#count +1;
WHile(#ColumnCount>=#count)
BEGIN
SET #ColumnName='qty_'+CONVERT(varchar(2),#count)
EXEC ('ALTER TABLE dyn_tbl ADD ['+#ColumnName +'] varchar(20)')
declare #myvar as varchar(max)
set #myvar='update '+#tablename+' set '+#ColumnName +' =itemQty'
--exec dynamic_tbl 'dyn_tbl'
--select * from dyn_tbl
--CAST('<A>'+REPLACE(ITEMQTY, ',', '</A><A>')+'</A>' AS XML)
print #myvar
exec(#myvar)
SET #count=#count +1;
END
END
----
END
Procedure to alter given table dynamically based on column length as you have asked
Alter PROCEDURE [dbo].[Column_Dynamics] (#tablename varchar(50))
AS
BEGIN
drop table ##temp
declare #query1 varchar(max)
exec ( '
create table ##temp (id int identity,columnsl varchar(100))
declare #maxcount as int
set #maxcount = (select MAX(len(ITEMQTY) - len(replace(ITEMQTY, '','', '''')) +1) from '+#tablename+')
declare #count int = 1
while (#count <= #maxcount)
begin
declare #colvar nvarchar(100)= ''QTY''
set #colvar = concat(#colvar,#count)
set #count = #count + 1
insert into ##temp select #colvar
end
')
declare #tempstart int = 1
declare #templast int = (select count(*) from ##temp)
declare #updatecol varchar(100) = ''
while (#tempstart <= #templast)
Begin
set #updatecol = (select columnsl from ##temp where id = #tempstart)
exec ('alter table '+#tablename+' Add '+#updatecol+' varchar(100) ')
set #tempstart = #tempstart + 1
end
End
output for inputTable:
id ItemQty QTY1 QTY2 QTY3 QTY4 QTY5
1 a,b,c NULL NULL NULL NULL NULL
2 x,y NULL NULL NULL NULL NULL
3 l,m,n,o,p NULL NULL NULL NULL NULL
4 a,b NULL NULL NULL NULL NULL
5 m NULL NULL NULL NULL NULL
may not be the best way but works.
edit
Altered above procedure to perform both actions, Please use below procedure
Alter PROCEDURE [dbo].[Column_Dynamics] (#tablename varchar(50))
AS
BEGIN
-- declare #tablename varchar(100) = 'inputTable'
drop table #temp if object_id('temp..#temp') is not null drop table #temp
declare #query1 varchar(max)
create table #temp (id int identity,columnsl varchar(100))
exec ( '
declare #maxcount as int
set #maxcount = (select MAX(len(ITEMQTY) - len(replace(ITEMQTY, '','', '''')) +1) from '+#tablename+')
declare #count int = 1
while (#count <= #maxcount)
begin
declare #colvar nvarchar(100)= ''QTY''
set #colvar = concat(#colvar,#count)
set #count = #count + 1
insert into #temp
select #colvar
end
')
declare #tempstart int = 1
declare #templast int = (select count(*) from #temp)
declare #updatecol varchar(100) = ''
declare #itemqty varchar(100)
while (#tempstart <= #templast)
Begin
set #updatecol = (select columnsl from #temp where id = #tempstart)
exec ('alter table '+#tablename+' Add '+#updatecol+' varchar(100) ')
set #tempstart = #tempstart + 1
end
declare #sysvar table (id int identity,cols varchar(100))
insert into #sysvar select sys.columns.name AS ColumnName FROM sys.columns JOIN sys.tables ON sys.columns.object_id = sys.tables.object_id WHERE sys.tables.name = 'inputTable'
declare #finvar table (id int identity,cols varchar(100))
insert into #finvar select cols from #sysvar where id not in (1,2)
declare #cat int = 1 declare #dog int = (select max(id) from inputTable)
while (#cat <= #dog)
begin
drop table #tab2
if object_id('temp..#tab2') is not null drop table #tab2
create table #tab2 (id int identity,fnvalues varchar(100))
set #itemqty = (select itemqty from inputTable where id = #cat)
insert into #tab2 select item from [dbo].[fnSplit](#itemQty,',')
declare #cn int = 1
declare #max int = (select max(id) from #tab2)
declare #sql nvarchar (1000);
while (#cn <= #max)
begin
declare #upcol varchar(100) = (select fnvalues from #tab2 where id = #cn)
declare #plscol varchar(100) = (select cols from #finvar where id = #cn)
set #sql = N'update '+#tablename+' set ' + #plscol + '= '''+#upcol+''' where id = '''+cast(#cat as varchar(10))+''' ';
select #sql
exec sp_executesql #sql;
set #cn = #cn + 1
end
set #cat = #cat + 1
End
End
output:
id ItemQty QTY1 QTY2 QTY3 QTY4 QTY5
1 a,b,c a b c NULL NULL
2 x,y x y NULL NULL NULL
3 l,m,n,o,p l m n o p
4 a,b a b NULL NULL NULL
5 m m NULL NULL NULL NULL
did not optimize the query but works fine.
However, if you have maximum Qty's are known which are in comma separated format then you could use xml node method to separate them into columns.QTY1...QTY5
SELECT DISTINCT ID, ITEMQTY,
a.value('/A[1]', 'VARCHAR(MAX)') as QTY1,
a.value('/A[2]', 'VARCHAR(MAX)') as QTY2,
a.value('/A[3]', 'VARCHAR(MAX)') as QTY3,
a.value('/A[4]', 'VARCHAR(MAX)') as QTY4,
a.value('/A[5]', 'VARCHAR(MAX)') as QTY5
FROM
(
SELECT ID, ITEMQTY,
CAST('<A>'+REPLACE(ITEMQTY, ',', '</A><A>')+'</A>' AS XML) AS ITEMQTY1
FROM inputTable
) A
CROSS APPLY ITEMQTY1.nodes('/A') AS split(a);
Result :
ID ITEMQTY QTY1 QTY2 QTY3 QTY4 QTY5
1 a,b,c a b c NULL NULL
2 x,y x y NULL NULL NULL
3 l,m,n,o,p l m n o p
4 a,b a b NULL NULL NULL
5 m m NULL NULL NULL NULL
Later, you could replace null by using coalesce() or isnull() function with ''
Use This
First Create a function
CREATE FUNCTION [dbo].[fn_split](
#str VARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #returnTable TABLE (idx INT PRIMARY KEY IDENTITY, item VARCHAR(8000))
AS
BEGIN
DECLARE #pos INT
SELECT #str = #str + #delimiter
WHILE LEN(#str) > 0
BEGIN
SELECT #pos = CHARINDEX(#delimiter,#str)
IF #pos = 1
INSERT #returnTable (item)
VALUES (NULL)
ELSE
INSERT #returnTable (item)
VALUES (SUBSTRING(#str, 1, #pos-1))
SELECT #str = SUBSTRING(#str, #pos+1, LEN(#str)-#pos)
END
RETURN
END
GO
and use function like this
Declare #test TABLE (
ID VARCHAR(200),
Data VARCHAR(200)
)
insert into #test
(ID, Data)
Values
(1,'a,b,c')
insert into #test
(ID, Data )
values(2,'x,y')
insert into #test
(ID, Data )
values(3,'l,m,n,o,p')
insert into #test
(ID, Data )
values(4,'a,b')
insert into #test
(ID, Data )
values(5,'m')
select ID,data AS ItemQty,
ISNULL((select item from fn_split(Data,',') where idx in (1)),'') as QTY1 ,
ISNULL((select item from fn_split(Data,',') where idx in (2)),'') as QTY2,
ISNULL((select item from fn_split(Data,',') where idx in (3)),'') as QTY3,
ISNULL((select item from fn_split(Data,',') where idx in (4)),'') as QTY5 ,
ISNULL((select item from fn_split(Data,',') where idx in (5)),'') as QTY5
from #test
Output Same as your Image
instead of using
insert into #test
(ID, Data)
Values
(1,'a,b,c')
you can also assgin it like this
insert into #test
(ID, Data)
Values
(Select Column1, Column2 From YourTable)
I have a sp in which I am returning one single column result. I am trying to store the result into a table type, but I am getting this error:
An INSERT EXEC statement cannot be nested.
I have googled around but didn't find any acceptable solution.
The sp is as follows:-
ALTER PROCEDURE [dbo].[Sp_DemographicFilter_booster]
(
#FilterSelected FilterSelected READONLY,
#CountryCategoryId int=null
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #WhereCondition varchar(500) ;
DECLARE #QueryString Varchar(MAX) ;
DECLARE #QueryString_booster Varchar(MAX) ;
DECLARE #Filter table (FilterColumn Varchar(200),FilterValue Varchar(200))
DECLARE #Result table (SERIAL int)
DECLARE #Result_booster table (SERIAL int)
if( select top 1 FilterColumn FROM #FilterSelected where FilterColumn<>'HISPANIC') is NOT NULL
BEGIN
Insert into #Filter
Select * from #FilterSelected where FilterColumn<>'HISPANIC'
--DECLARE #DemoTbl TABLE (MetricName VARCHAR(100),CatValue VARCHAR(100))
SELECT #WhereCondition= COALESCE( #WhereCondition + ' and ', '')+SubjectList FROM (
SELECT DISTINCT STD.Filtercolumn +' in ('+
ISNULL(STUFF((SELECT ', '+'''' + ssm.Filtervalue+''''
FROM #Filter SSM
INNER JOIN #Filter SUB ON SUB.FilterColumn = SSM.FilterColumn and SUB.FilterColumn=STD.FilterColumn
WHERE sub.FilterValue = ssm.FilterValue
FOR XML PATH('')
), 1, 1, ''), 'Not Assigned Yet')+')' AS SubjectList
FROM #Filter STD)A
print #WhereCondition
--INSERT INTO #DemoTbl
--select SUBSTRING(col1,1, CHARINDEX(':',col1,1)-1) MetricName,SUBSTRING(col1, CHARINDEX(':',col1,1)+1,LEN(Col1)) CatValue
--from dbo.UF_CSVDataToTable(#FilterSelectedSelected)
SET #QueryString='SELECT SERIAL FROM Logical.Demographic D
WHERE '+#WhereCondition+' and CountryCategoryId='+cast(#CountryCategoryId as varchar(10))
PRINT #QueryString
insert into #Result
EXEC(#QueryString)
--select * from #Result
END
IF(select top 1 FilterColumn FROM #FilterSelected where FilterColumn='HISPANIC') IS NOT NULL
BEGIN
Delete from #Filter;
DECLARE #Response varchar(20)=null;
Insert into #Filter
Select * from #FilterSelected where FilterColumn='HISPANIC'
select #Response=FilterValue from #Filter;
DECLARE #VariableID int=null;
select #VariableID=SurrogateKeyCounter from MetaData.Metadata_Screener where DBMetricName='HISPANIC';
SET #QueryString_booster='SELECT SERIAL FROM Logical.Response R
WHERE variableid='+cast(#VariableID as varchar(10))+' and CountryCategoryId='+cast(#CountryCategoryId as varchar(10))
+' and ResponseName='''+#Response+''''
PRINT #QueryString_booster
Insert into #Result_booster
EXEC(#QueryString_booster)
END
DECLARE #Final_Result table (SERIAL int)
insert into #Final_Result
select * from #Result
UNION
select * From #Result_booster
select * from #Final_Result
END
I am calling this procedure like this:
declare #ds FilterSelected
insert into #ds values('Hispanic','yes')
#FilterSelected=#ds,#CountryCategoryId=100
DECLARE #DemoTbl TABLE (Serial INT)
Insert into #DemoTbl
EXEC Sp_DemographicFilter_booster #FilterSelected=#ds,
#CountryCategoryId=100
Call SP Sp_DemographicFilter_booster along with unique ID .
Inside Sp_DemographicFilter_booster SP create global table (##) stored result in global table with same unique ID AS ID field
Now when return to main SP access global table with where condition that unique ID
I have created a SP like below. where i will have to pass comma separated values to #ID parameter.I have given split function. It is working fine only if i give one value as ID. Kindly help how should i change the exec statement for the SP to give comma separated values like ('123',456) to SP
EXEC usp_2090_AppRej '54862','',''
ALTER PROCEDURE [dbo].[usp_2090_AppRej]
#ID VARCHAR(100)
,#Comments VARCHAR(1000) = ''
,#ReturnMessage VARCHAR(500) OUTPUT
DECLARE #tblBPM TABLE (ids INT)
INSERT INTO #tblBPM
SELECT items
FROM dbo.Split(#ID, ',')
You are using SQL server try the following.
Create database function
ALTER FUNCTION [dbo].[fnSplit]
(
#sInputList VARCHAR(max) -- List of delimited items
,
#sDelimiter VARCHAR(max) = ',' -- delimiter that separates items
)
RETURNS #List TABLE ( item VARCHAR(max) )
BEGIN
DECLARE #sItem VARCHAR(max)
WHILE CHARINDEX(#sDelimiter, #sInputList, 0) <> 0
BEGIN
SELECT #sItem = RTRIM(LTRIM(SUBSTRING(#sInputList, 1,
CHARINDEX(#sDelimiter,
#sInputList, 0)
- 1))) ,
#sInputList = RTRIM(LTRIM(SUBSTRING(#sInputList,
CHARINDEX(#sDelimiter,
#sInputList, 0)
+ LEN(#sDelimiter),
LEN(#sInputList))))
IF LEN(#sItem) > 0
INSERT INTO #List
SELECT #sItem
END
IF LEN(#sInputList) > 0
INSERT INTO #List
SELECT #sInputList -- Put the last item in
RETURN
END
Create SP
CREATE PROCEDURE [dbo].[usp_2090_AppRej]
#ID VARCHAR(100),
#Comments VARCHAR(1000) = '',
#ReturnMessage VARCHAR(500) OUTPUT
AS
BEGIN
DECLARE #tblBPM TABLE ( ids INT )
INSERT INTO #tblBPM
SELECT item
FROM dbo.fnSplit(#ID, ',')
END
I have comma separated column which represents the ids of cities like:
ID | Name
1 | 1,2,3
2 | 2,3,4
I want to make query to get name of the this value field. There is City Table which has two columns: id and name of cities
EXPECTED OUTPUT
ID | VALUES
1 | mumbai,delhi,pune
2 | delhi,pune,chennai
I can make a query if there is only one id in a column like:
select data.id,city.name from data,city where data.values=city.cityid
but I am not getting how to retrieve the data if there are multiple comma-separated values in one field.
The easy way is to convert CSV values to rows for each Id, join that with CITY table and convert back to CSV values. I have written the logic inside the query.
;WITH CTE1 AS
(
-- Convert CSV to rows
SELECT Id,LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'NAME'
FROM
(
-- To change ',' to any other delimeter, just change ',' before '</M><M>' to your desired one
SELECT Id,CAST ('<M>' + REPLACE(Name, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM #TEMP
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
,CTE2 AS
(
-- Now join the values in rows with Id in CITY table
SELECT T.ID,T.NAME,C.CITYNAME
FROM CTE1 T
JOIN #CITY C ON T.NAME=C.ID
)
-- Now convert back to CSV format
SELECT DISTINCT ID,
SUBSTRING(
(SELECT ', ' + CITYNAME
FROM CTE2 I
WHERE I.Id=O.Id
FOR XML PATH('')),2,200000) [VALUES]
FROM CTE2 O
Click here to view result
to do this please do following sections:
1-Create Function to get table of comma separate value in each row
CREATE FUNCTION [dbo].[fn_Split](
#ForigenKey INT,
#String NVARCHAR (4000),
#Delimiter NVARCHAR(10)
)
RETURNS #ValueTable TABLE ([ID] INT IDENTITY NOT NULL,FID int null,[Value] NVARCHAR(4000))
BEGIN
DECLARE #NextString NVARCHAR(4000)
DECLARE #Pos INT
DECLARE #NextPos INT
DECLARE #CommaCheck NVARCHAR(1)
--Initialize
SET #NextString = ''
SET #CommaCheck = RIGHT(#String,1)
--Check for trailing Comma, if not exists, INSERT
--if (#CommaCheck <> #Delimiter )
SET #String = #String + #Delimiter
--Get position of first Comma
SET #Pos = CHARINDEX(#Delimiter,#String)
SET #NextPos = LEN(#Delimiter)
--Loop while there is still a comma in the String of levels
WHILE (#pos <> 0)
BEGIN
SET #NextString = SUBSTRING(#String, 1, #Pos - 1)
INSERT INTO #ValueTable ( FID,[Value]) VALUES (#ForigenKey ,#NextString)
SET #String = SUBSTRING(#String,#pos + LEN(#Delimiter),LEN(#String))
SET #NextPos = #Pos
SET #pos = CHARINDEX(#Delimiter,#String)
END
RETURN
END
GO
2- create Concat Aggregate with the folwing link
Concat Aggregate
3- you can get your data with below select
DECLARE #ID INT,#Name NVARCHAR(4000)
DECLARE #ValueTable table ([ID] int NOT NULL,[Value] INT)
DECLARE mycur CURSOR FOR
SELECT TOP(1000) ID,Name FROM TableA
OPEN mycur
FETCH NEXT FROM mycur INTO #ID,#Name
WHILE(##FETCH_STATUS=0)
BEGIN
INSERT INTO #ValueTable
( ID, Value )
SELECT #ID,Value FROM dbo.fn_Split(#Name,',')
FETCH NEXT FROM mycur INTO #ID,#Name
END
CLOSE mycur
DEALLOCATE mycur
SELECT * FROM #ValueTable
SELECT ID,dbo.ConcatAggregate(CityName) FROM #ValueTable
inner join city on value=cityid GROUP BY ID
Is there an easy way of determining the most frequently occuring word in a column/field using T-SQL or VBA?
I am working on a fuzzy matching system for two given recordsets and would like to produce a matching string where the most frequently occuring words are removed. As the data is from a customer relations management database terms like "limited", "ltd", "plc" and "CORPORATION" would be removed.
Written for sql-server 2005+
Function to split:
create function f_split
(
#a varchar(max),
#delimiter varchar(20)
)
RETURNS #t TABLE(substr varchar(200))
as
begin
set #a = #a + #delimiter
;with a as
(
select cast(1 as bigint) f1, charindex(#delimiter, #a) f2
where len(#a) > 0
union all
select f2 + (len(#delimiter)) + 1, charindex(#delimiter, #a, f2+1)
from a
where f2 > 0
)
insert #t
select substring(#a, f1, f2 - f1) from a
where f1 < f2
return
end
go
Query:
--testdata
declare #table table(name varchar(50))
insert #table values('bla bla bla ltd')
insert #table values('bla plc ltd')
insert #table values('more text CORPORATION')
declare #matchlist table(name varchar(50), replacement varchar(50))
insert #matchlist values('ltd', 'limited')
insert #matchlist values('plc', 'limited')
insert #matchlist values('CORPORATION', 'limited')
--query
select coalesce(m.replacement, a.substr) name, count(*) count from #table p
cross apply
(
select substr from
dbo.f_split(p.name, ' ')
) a
left join
#matchlist m
on a.substr = m.name
group by coalesce(m.replacement, a.substr)
order by 2 desc
Result:
name count
---- -----
bla 4
limited 4
more 1
text 1
Hope this will be useful to you.
create table sometable
( id integer not null primary key identity
, mYWords text not null
);
insert into sometable (mYWords)
values ('a word that appears maximum number of times in a column')
insert into sometable (mYWords)
values ('Is it possible to get words from text columns in a sql server database')
insert into sometable (mYWords)
values ('This could solve my problem if reffered column contain only single word')
insert into sometable (mYWords)
values ('that''s going to require that you split out every word in the column individually')
insert into sometable (mYWords)
values ('the query will definitely not be easy to write')
insert into sometable (mYWords)
values ('Please read the sticky at the top of the board')
insert into sometable (mYWords)
values ('The physical order of data in a database has no meaning')
GO
CREATE TABLE WordList (
Word varchar(256)
, WordId int IDENTITY(1,1)
, Add_Dt datetime DEFAULT (GetDate()))
GO
CREATE UNIQUE INDEX UnqueWords_PK ON WordList(Word)
GO
CREATE PROC isp_INS_WORD_LIST
AS
BEGIN
SET NOCOUNT ON
DECLARE #Words INT, #Pos INT, #x Int, #str varchar(256)
, #word varchar(256), #start int, #end int, #exitstart int
SELECT #Words = 0, #Pos = 1, #x = -1, #Word = '', #start = 1
DECLARE Cur1 CURSOR FOR SELECT mYWords FROM sometable
OPEN Cur1
FETCH NEXT FROM Cur1 INTO #str
WHILE ##FETCH_STATUS = 0
BEGIN
WHILE (#x <> 0)
BEGIN
SET #x = CHARINDEX(' ', #str, #Pos)
IF #x <> 0
BEGIN
SET #end = #x - #start
SET #word = SUBSTRING(#str,#start,#end)
IF NOT EXISTS (SELECT * FROM WordList WHERE Word = #Word)
INSERT INTO WordList(Word) SELECT #word
-- SELECT #Word, ##ROWCOUNT,##ERROR
-- SELECT #x, #Word, #start, #end, #str
SET #exitstart = #start + #end + 1
SET #Pos = #x + 1
SET #start = #x + 1
SET #Words = #Words + 1
END
IF #x = 0
BEGIN
SET #word = SUBSTRING(#str,#exitstart,LEN(#str)-#exitstart+1)
IF NOT EXISTS (SELECT * FROM WordList WHERE Word = #Word)
INSERT INTO WordList(Word) SELECT #word
-- SELECT #Word, ##ROWCOUNT,##ERROR
-- SELECT #x, #Word, #exitstart, LEN(#str)-#exitstart, #str
END
END
FETCH NEXT FROM Cur1 INTO #str
SELECT #Words = 0, #Pos = 1, #x = -1, #Word = '', #start = 1
END
CLOSE Cur1
DEALLOCATE Cur1
SET NOCOUNT OFF
RETURN #Words
END
GO
EXEC isp_INS_WORD_LIST
GO
SELECT * FROM WordList ORDER BY Word
GO
DROP PROC isp_INS_WORD_LIST
DROP TABLE WordList, sometable
GO