Build a string in an sql table and insert into another table - sql-server

Say I have a table Name_Address as follows:
CREATE TABLE [dbo].[Name_Address](
[First_Name] [nvarchar] (50) NULL,
[Last_Name] [nvarchar] (50) NULL,
[Address] [nvarchar] (50) NULL,
[City] [nvarchar] (50) NULL,
[State] [nvarchar] (50) NULL,
[Zip] [nvarchar] (50) NULL,
[Phone] [nvarchar] (50) NULL,
[Cell] [nvarchar] (50) NULL
) ON [PRIMARY]
Is there a way in SQL that I can build a string:
<First Name>John<Last Name>Smith<Address>1233 Your Street<City>Home Town<State>NY<Zip>123456-1234<Phone>111-111-1111<Cell>222-222-222
and insert it into another table?
Original post did not show the xml tags as part of the desired result: without code formatting the tags were interpreted literally and were not displayed.

You would just use the + to concatenate the values together.
INSERT INTO yourNewTable (newRecord)
SELECT First_Name + Last_Name + Address + City + State + Zip + Phone + Cell
FROM dbo.Name_Address
Or add spaces:
INSERT INTO yourNewTable (newRecord)
SELECT First_Name + ' ' + Last_Name + ' '
+ Address + ' ' + City + ' ' + State + ' ' + Zip
+ Phone + ' ' + Cell
FROM dbo.Name_Address
You can also use FOR XML PATH if you want this in XML format:
select *
from name_address
for xml path
see SQL Fiddle with Demo
Or you can hand-code the XML tags, if you want to insert the full record into another table you can use:
insert into yourNewTable (yourNewRecord)
select '<FirstName>'+[First_Name]
+ '<Last_Name>'+[Last_Name]
+'<Address>'+[Address]
+'<City>'+[City]
+'<State>'+[State]
+'<Zip>'+[Zip]
+'<Phone>'+[Phone]
+'<Cell>'+[Cell]
from name_address
see Sql Fiddle with Select Demo

INSERT INTO MyTable(MyString)
SELECT
'<FirstName>'+[First_Name] + '<Last_Name>'+[Last_Name] +'<Address>'+[Address] +<City>+[City] +<State>+[State] +'<Zip>'+[Zip] +'<Phone>'+[Phone] +'<Cell>'+[Cell]
FROM [dbo].[Name_Address]

You can concatenate fields together using ||:
select First_name||' '||Last_Name||' '+Address . . .
from NameAddress
To insert into another table, you can do something like:
insert into AnotherTable
select '<First Name>'||First_name||'<Last Name>'||Last_Name||'<Address>'+Address . . .
from NameAddress

Related

How to find average in pivot

I have Two Table in sql server 2008
TABLE [tblTagDescription](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[TopicID] [int] NULL,
[TagID] [int] NULL,
[FullTag] [nvarchar](50) NULL,
[ValDecimal] [nvarchar](50) NULL,
[ValBinary] [nvarchar](50) NULL,
[GroupName] [nvarchar](50) NULL,
[ReportTag] [nvarchar](50) NULL
)
And
TABLE [tblDataLog](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[TagDescID] [bigint] NULL,
[Value] [decimal](18, 2) NULL,
[Date] [datetime] NULL,
)
Here there might be same Group for multiple "Id" of tblDescription and "TagDescID" of tblDataLog.
Here 'Group1' has 10 ID as from 1 to 10. and there might be multiple record for these ID (from 1 to 10) in tbldatalog. I want these ID from 1 to as columns. I want Average of these ID (From 1 to 10).
For this I used pivot:
Declare #COls nvarchar(max)
Declare #SQL nvarchar(max)
DECLARE #COlsID NVARCHAR(MAX) = ''
DECLARE #COlsAlias NVARCHAR(MAX) = ''
IF OBJECT_ID('tempdb..##MYTABLE') IS NOT NULL DROP TABLE ##MYTABLE
IF OBJECT_ID('tempdb..#tt') IS NOT NULL DROP TABLE #tt
IF(#Group='A')
BEGIN
Select #COls=COALESCE(#Cols + '],[','') + z.ReportTag From
(Select Distinct T.ID, ReportTag From tblTagDescription T
Where isnull(ReportTag,'')<>'' AND T.GroupName=#Group Group BY T.ID,T.ReportTag --order by T.ID
)z
END
ELSE
BEGIN
SELECT
#COlsID = #ColsID + ',' + z.TagDescID,
#COlsAlias = #COlsAlias + ',' + z.TagDescID + ' AS ' + z.ReportTag
FROM
(select TagDescID,ReportTag from(SELECT DISTINCT TOP 50 QUOTENAME(CONVERT(NVARCHAR(25),
tblDataLog.TagDescID )) TagDescID,TagdescID TID,
QUOTENAME(tblTagDescription.ReportTag) ReportTag
FROM tblDataLog
INNER JOIN tblTagDescription ON tblDataLog.TagDescID = tblTagDescription.ID
where tblTagDescription.GroupName=#Group
ORDER BY tblDataLog.TagDescID )s
) z
END
SET #COlsID= STUFF(#COlsID,1,1,'')
SET #COlsAlias= STUFF(#COlsAlias,1,1,'')
SET #SQL='select [DATE],SHIFT, ' + #COlsAlias + ' into ##MYTABLE from ( select [Date], AVG(Value), TagDescID,
(CASE
WHEN ((DATEPART(hour,[DATE]))>6 and (DATEPART(hour,[DATE]))<14) THEN ''A''
WHEN ((DATEPART(hour,[DATE]))>=14 and (DATEPART(hour,[DATE]))<22) THEN ''B''
WHEN ((DATEPART(hour,[DATE]))>=22 or (DATEPART(hour,[DATE]))<6) THEN ''C''
END )AS SHIFT
from tblDataLog Group by [Date],[TagDescID] )d pivot(max(Value) for TagDescID in (' + #COlsID + ')) piv;'
EXEC (#SQL)
select * from ##MYTABLE
But the above query is giving error as :
Msg 8155, Level 16, State 2, Line 8
No column name was specified for column 2 of 'd'.
Msg 207, Level 16, State 1, Line 8
Invalid column name 'Value'.
Msg 208, Level 16, State 0, Procedure Select_DataViewer, Line 58
Invalid object name '##MYTABLE'.
How to solve this?

Create a view from a table from multiple rows to generate a JSON column group by specified column

I am using Azure sql:
SELECT SERVERPROPERTY('ProductVersion');
returns:
12.0.2000.8
I have a table like this:
CREATE TABLE [dbo].[UserProperty](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NOT NULL,
[Key] [nvarchar](256) NOT NULL,
[Value] [nvarchar](4000) NOT NULL,
) ON [PRIMARY]
GO
INSERT INTO [dbo].[UserProperty]([UserId], [Key], [Value])
VALUES(1, 'hello', 'world'),
(1, 'ja', 'va'),
(2, 'hello', 'world'),
(2, 'csh', 'arp'),
(2, 'machine', 'learning');
GO
And I want to create a view which as follow:
| UserId | JsonValue | <br>
|--------|--------|<br>
| 1 | {"hello":"world", "ja":"va"} | <br>
| 2 | {"hello":"world", "csh":"arp", "machine":"learning"} |
I want to get a view like this
You'd think that SQL Server's native JSON facilities would be more useful here, but not really -- some clumsy string concatenation required, and the only thing we really benefit from is native escaping for JSON. This is because there's not really any convenient way to map columns into key/value pairs; simple column-as-key mappings only.
SELECT [UserID], JsonValue =
'{' + STRING_AGG(
'"' + STRING_ESCAPE([key], 'json') + '"' + ':' +
'"' + STRING_ESCAPE([value], 'json') + '"',
','
) + '}'
FROM UserProperty
GROUP BY UserID
This requires SQL Server 2017+; it should also work on Azure since that's ahead of the curve.

How can I group by (like an Excel pivot table?) my minute bar data

I have a table created as follows:
CREATE TABLE [1M].[FLOWERS](
[utcDT] [datetime2](7) NOT NULL,
[Symbol] [nvarchar](50) NULL,
[Open] [float] NULL,
[High] [float] NULL,
[Low] [float] NULL,
[Close] [float] NULL
) ON [PRIMARY]
How can I create a table such that I get a column for each different [Symbol] and value in column is the [Close] grouped by [utcDT]
Assume there are 10 different symbols.
I want:
utcDT,Symbol1,Symbol2,...,Symbol10
10:23,1.1 ,1.2 ,...,1.07
10:24,1.3 ,1.2 ,...,1.09
10:25,1.2 ,1.3 ,...,1.10
In Excel this is easily done with a pivot table. How can I achieve this in SQL?
You can use this.
SELECT [utcDT], [1] Symbol1 ,[2] Symbol2,[3] Symbol3,[4] Symbol4,[5] Symbol5,[6] Symbol6,[7] Symbol7,[8] Symbol8,[9] Symbol9,[10] Symbol10 FROM (
SELECT CAST([utcDT] AS time) [utcDT] , [Close], [Symbol] FROM FLOWERS ) SRC
PIVOT( MAX( [Close]) FOR [Symbol] IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) PVT
If you want to make it dynamically you can use this.
DECLARE #ColNamesForPivot VARCHAR(MAX) = ''
DECLARE #ColNamesForSelect VARCHAR(MAX) = ''
SELECT
#ColNamesForPivot = #ColNamesForPivot + ', ' + QUOTENAME([Symbol])
,#ColNamesForSelect = #ColNamesForSelect + ', '+ QUOTENAME([Symbol]) + ' '+ QUOTENAME('Symbol' + CONVERT(VARCHAR,[Symbol]))
FROM FLOWERS
GROUP BY [Symbol]
DECLARE #SqlQ NVARCHAR(MAX) =
'SELECT [utcDT] ' + #ColNamesForSelect + ' FROM (
SELECT CAST([utcDT] AS time) [utcDT] , [Close], [Symbol] FROM FLOWERS ) SRC
PIVOT( MAX([Close]) FOR [Symbol] IN (' + STUFF(#ColNamesForPivot,1,1,'') + ')) PVT'
EXEC(#SqlQ)
You could use conditional aggregation:
SELECT utcDT
,MIN(CASE WHEN Symbol = 'Symbol1' THEN [Close] END) AS Symbol1
--,...
,MIN(CASE WHEN Symbol = 'Symbol10' THEN [Close] END) AS Symbol10
FROM tab
GROUP BY utcDT
ORDER BY utcDT;

SQL Server 2016 SP1 - Is this a bug?

I just installed SQL Server 2016 and SP1 and run this TSQL Script
CREATE TABLE [dbo].TEST(
[id] [INT] IDENTITY(1,1) NOT NULL,
[lat] [DECIMAL](9, 6) NULL,
[lng] [DECIMAL](9, 6) NULL,
[Location] AS ([geography]::STGeomFromText(((('POINT ('+[lng])+' ')+[lat])+')',(4326)))
PERSISTED
)
The table is created fine.
I then run the following (there is no records in the table)
Select * from TEST
This returns
Msg 8114, Level 16, State 5, Line 8
Error converting data type varchar to numeric.
It is related to the Location field.
Is this a bug in SQL Server 2016? I would not expect this behavior.
The following does not cause any issues
CREATE TABLE [dbo].TEST2(
[id] [INT] IDENTITY(1,1) NOT NULL,
[lat] [DECIMAL](9, 6) NULL,
[lng] [DECIMAL](9, 6) NULL,
[Location] AS [lng] PERSISTED
)
select * from TEST2
Change
[Location] AS ([geography]::STGeomFromText(((('POINT (' + [lng]) + ' ') + [lat]) + ')', (4326)))
to
[Location] AS ([geography]::STGeomFromText(((('POINT (' + CAST([lng] AS varchar)) + ' ') + CAST([lat] AS varchar)) + ')', (4326)))
The difference in these two are the usage of the CAST function like so:
CAST([lng] AS varchar)
CAST([lat] AS varchar)
Simply an issue of [lng] and [lat] being decimals concatenated to a varchar string. The reason for it not being a problem until you actually execute the query even with no data in the table is due to the [Location] field not being formed until the select query is executed.
Not a bug necessarily but something that SQL Management Studio should probably parse for prior to executing the CREATE TABLE query.
You need to CAST the lng and lat values to varchar so the + operator is treated as concatenation instead of addition. Example without the extraneous parenthesis:
CREATE TABLE [dbo].TEST(
[id] [INT] IDENTITY(1,1) NOT NULL,
[lat] [DECIMAL](9, 6) NULL,
[lng] [DECIMAL](9, 6) NULL,
[Location] AS [geography]::STGeomFromText('POINT ('+ CAST([lng] AS varchar(10)) + ' ' + CAST([lat] AS varchar(10)) + ')', 4326)
PERSISTED
);

SQL - Dynamic SQL inside OpenRowSet then Inserted into Temp Table

I am trying to utilize Dynamic SQL that will parse in the file directory into an OpenRowSet(#Database). Right now I have a hard coded directory for the Excel File. The end result will be me creating an application that will take the user's file and import into the SQL table. From there I'll be merging and Match/Not Matching (Which is working properly). This is the last piece of the puzzle. I don't know why the error message is looking for my file in "C:\WINDOWS\system32\ "
My current error messages are:
OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" returned message "The Microsoft Access database engine could not find the object 'C:\WINDOWS\system32\ C:\Users\GrimRieber\Desktop\isi test.xlsx'. Make sure the object exists and that you spell its name and the path name correctly. If 'C:\WINDOWS\system32\ C:\Users\GrimRieber\Desktop\isi test.xlsx' is not a local object, check your network connection or contact the server administrator.".
Msg 7303, Level 16, State 1, Line 1
Cannot initialize the data source object of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)".
Code:
declare #Database varchar(max)
select #Database = 'C:\Users\GrimRieber\Desktop\isi test.xlsx'
declare #sql varchar(Max)
select #sql = 'SELECT * FROM OPENROWSET(
''Microsoft.ACE.OLEDB.12.0'',
''Excel 12.0; Database= ' + #Database + '; HDR=YES; IMEX=1'',
''SELECT [Vendor],[VendorName],[Material],[MaterialName],[Supplier Stock Num],[01],[02],[03],[04],[05],[06],[07],[08],[09],[10],[11],[12],[Year]FROM [Data$]''
)'
IF OBJECT_ID('tempdb.dbo.#TempScorecardInventorySold', 'U') IS NOT NULL
DROP TABLE #TempScorecardInventorySold;
CREATE TABLE #TempScorecardInventorySold
(
[Vendor] [varchar](50) NULL,
[VendorName] [varchar](50) NULL,
[Material] [varchar](50) NULL,
[MaterialName] [varchar](50) NULL,
[Supplier Stock Num] [varchar](50) NULL,
[01] [nVarchar](50) NULL,
[02] [nVarchar](50) NULL,
[03] [nVarchar](50) NULL,
[04] [nVarchar](50) NULL,
[05] [nVarchar](50) NULL,
[06] [nVarchar](50) NULL,
[07] [nVarchar](50) NULL,
[08] [nVarchar](50) NULL,
[09] [nVarchar](50) NULL,
[10] [nVarchar](50) NULL,
[11] [nVarchar](50) NULL,
[12] [nVarchar](50) NULL,
[Year] [Int] Null
) ON [PRIMARY];
INSERT INTO [dbo].#TempScorecardInventorySold ([Vendor],[VendorName],[Material],[MaterialName],[Supplier Stock Num],[01],[02],[03],[04],[05],[06],[07],[08],[09],[10],[11],[12],[Year])
EXECUTE(#sql)
While I cannot recreate your file path issue (be sure to carefully check if file exists at the path and file extension), the OPENROWSET() in that setup should define fields in the SELECT clause at beginning. The last argument should be unquoted, pointing to worksheet range:
select #sql = 'SELECT [Vendor],[VendorName],[Material],[MaterialName],[Supplier Stock Num],
[01],[02],[03],[04],[05],[06],
[07],[08],[09],[10],[11],[12],[Year]
FROM OPENROWSET(''Microsoft.ACE.OLEDB.12.0'',
''Excel 12.0; Database= ' + #Database + '; HDR=YES; IMEX=1'', [Data$])';
Alternatively, consider OPENDATASOURCE:
select #sql = 'SELECT [Vendor],[VendorName],[Material],[MaterialName],[Supplier Stock Num],
[01],[02],[03],[04],[05],[06],
[07],[08],[09],[10],[11],[12],[Year]
FROM OPENDATASOURCE(''Microsoft.ACE.OLEDB.12.0'',
''Data Source=' + #Database + ';Extended Properties=Excel 12.0'')...Data$'
Or even a Driver version (fields can be in either of two SELECT clauses)
select #sql = 'SELECT [Vendor],[VendorName],[Material],[MaterialName],[Supplier Stock Num],
[01],[02],[03],[04],[05],[06],
[07],[08],[09],[10],[11],[12],[Year]
FROM OPENROWSET(''MSDASQL'',
''Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};
DBQ=' + #Database + ''', ''SELECT * FROM [DATA$]'');

Resources