How to add query result single column to different table? - sql-server

As you know with AS statement we can create a single column including query expressions. How can I add this single column to my table?
For example:
select
CAST(idwYear AS varchar(20)) + '-' +
CAST((right('00' + ltrim(str(idwMonth)), 2)) AS varchar(20)) + '-' +
CAST(right('00' + ltrim(str(idwDay)), 2) AS varchar(20)) AS finaldate
Now, how can I add final date to for example my_table?

That's the solution.
insert into finaldate
select
CAST(idwYear AS varchar(20)) + '-' +
CAST((right('00' + ltrim(str(idwMonth)), 2)) as varchar(20)) + '-' +
CAST(right('00' + ltrim(str(idwDay)), 2) AS varchar(20))
from
database.dbo.rawdata
why I cant do is I added values but no need to values statement

You can add finaldate as a computed column to the table using the DDL below:
ALTER TABLE dbo.my_table
ADD finaldate AS
CAST(idwYear AS varchar(20)) + '-'
+ CAST((right('00' + LTRIM(STR(idwMonth)), 2)) AS varchar(20)) + '-'
+ CAST(right('00' + LTRIM(STR(idwDay)), 2) AS varchar(20));

Related

how to get the row id on a MSSQL Server insert or update trigger

Here I have 2 triggers, they update a field after the values are inserted or update. my question is how can I make sure that I'm only updating the value on the row that has been inserted or update, my update does not include any WHERE clause
CREATE TRIGGER LocUpdated
ON [SqlDistance].[dbo].[DistantTest]
AFTER UPDATE
AS
IF ( UPDATE (Lat) OR UPDATE (Lon))
BEGIN
UPDATE [SqlDistance].[dbo].[DistantTest]
SET [Geography2] = geography::STGeomFromText('POINT(' + CAST([Lon] AS VARCHAR(20)) + ' ' +
CAST([lat] AS VARCHAR(20)) + ')', 4326)
END;
GO
CREATE TRIGGER LocInserted
ON [SqlDistance].[dbo].[DistantTest]
AFTER INSERT
AS
BEGIN
UPDATE [SqlDistance].[dbo].[DistantTest]
SET [Geography2] = geography::STGeomFromText('POINT(' + CAST([Lon] AS VARCHAR(20)) + ' ' +
CAST([lat] AS VARCHAR(20)) + ')', 4326)
END;
GO
You'll want to do a JOIN onto inserted. This is pseudo-sql, in the absence of table DDL, however, this should get you on the right track:
UPDATE D
SET [Geography2] = geography::STGeomFromText('POINT(' + CAST(i.[Lon] AS VARCHAR(20)) + ' ' +
CAST(i.[lat] AS VARCHAR(20)) + ')', 4326)
FROM [dbo].[DistantTest] D --no need to declare the database, we're already in it.
JOIN inserted i ON D.UniqueIdColumn = i.UniqueIdColumn;

Create table variable from pivot results

Is it possible to create table variable from pivot results?
My pivot query:
SELECT #QUERY = 'SELECT USER_KEY, ' + #COLDEPSUMMARY + '
FROM CAUSDE_TAS
PIVOT
(
SUM(USDE_HSU)
FOR DEPA_KEY IN (' + #COLDEPARTMENTS + ')
) PIVOT_LOCATIONS
WHERE USDE_DAT >= ''' + format(#dDateFrom, 'MM.dd.yyyy') + ''' AND USDE_DAT <= ''' + format(#dDateTo, 'MM.dd.yyyy') + '''
AND USER_KEY IN (' + #USERS_STR + ')
GROUP BY USER_KEY'
#COLDEPSUMMARY AND #COLDEPARTMENTS are dynamically generated and are looking like this (there is around 70 columns):
#COLDEPSUMMARY:
SUM([120000003]),SUM([120000002]),SUM([140000001]),SUM([120000005]), ...
#COLDEPARTMENTS:
[120000003],[120000002],[140000001],[120000005], ...
Main reason why I want to create table variable from pivot table is that number of columns in pivot is dynamic - it can vary and there are a lot of columns (around 70).
UPDATE
As Jeremy suggested I've included INTO #tmp in dynamic query, so it looks like this:
SELECT #QUERY = 'SELECT USER_KEY, ' + #COLDEPSUMMARY + '
INTO #tmp
FROM CAUSDE_TAS
PIVOT
(
SUM(USDE_HSU)
FOR DEPA_KEY IN (' + #COLDEPARTMENTS + ')
) PIVOT_LOCATIONS
WHERE USDE_DAT >= ''' + format(#dDateFrom, 'MM.dd.yyyy') + ''' AND USDE_DAT <= ''' + format(#dDateTo, 'MM.dd.yyyy') + '''
AND USER_KEY IN (' + #USERS_STR + ')
GROUP BY USER_KEY'
If I just run the query with EXECUTE(#query), report is saying that more than 200 rows are affected. But, query:
select * from #tmp
is returning:
Invalid object name '#tmp'.
If I extract dynamic query and run it manually, all is good - #tmp is created and I can query it. (I extracted query with SELECT #query. Than I've just copy-pasted that selection into another window).
Dynamic query after extraction looks like this:
SELECT USER_KEY, SUM([120000003]),SUM([120000002]),SUM([140000001])
INTO #tmp
FROM CAUSDE_TAS
PIVOT
(
SUM(USDE_HSU)
FOR DEPA_KEY IN ([120000003],[120000002],[140000001])
) PIVOT_LOCATIONS
WHERE USDE_DAT >= '09.19.2016' AND USDE_DAT <= '03.18.2017'
AND USER_KEY IN (100000002,100000004,100000006,100000008)
GROUP BY USER_KEY
I don't understand why #tmp is not created if I just run EXECUTE(#Query)?

Why correlated subquery doesn't allow two expressions - SQL Server

I have query like this:
select
objectid,
(select top 1 data_source, maxspeed
from SpeedLimitData3
where way_geometry.Filter(geography::STGeomFromText('POINT (' + cast(X as varchar(15)) + ' ' + cast(Y as varchar(15)) + ')', 4326)) = 1
order by way_geometry.STDistance(geography::STGeomFromText('POINT (' + cast(X as varchar(15)) + ' ' + cast(Y as varchar(15)) + ')', 4326))
)
from
testData
Why does the SQL Server throw this error?
Msg 116, Level 16, State 1, Line 8
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
I know that this means that I need to remove one of subquery's selected columns. But why when I have single row as subquery result and not several?
The syntax of a select clause in Transact-SQL allows a <select-list> made up of various entities. A correlated subquery used in a select clause is an expression and supplies the value for a single result column.
this will work, but will output same data in otr.* part of select.
You have to use related fields in testData and applied correlation
select objectid, otr.*
from testData
outer apply
(
select top 1 data_source, maxspeed
from SpeedLimitData3
where way_geometry.Filter(geography::STGeomFromText('POINT (' + cast(X as varchar(15)) + ' ' + cast(Y as varchar(15)) + ')', 4326)) = 1
order by way_geometry.STDistance(geography::STGeomFromText('POINT (' + convert(varchar(15),X) + ' ' + convert(varchar(15),Y) + ')', 4326))
) otr
If X & Y are fields in testData
select tD.objectid, otr.*
from testData tD
outer apply
(
select top 1 data_source, maxspeed
from SpeedLimitData3
where way_geometry.Filter(geography::STGeomFromText('POINT (' + convert(varchar(15),tD.X) + ' ' + convert(varchar(15),tD.Y) + ')', 4326)) = 1
order by way_geometry.STDistance(geography::STGeomFromText('POINT (' + convert(varchar(15),tD.X) + ' ' + convert(varchar(15),tD.Y) + ')', 4326))
) otr

SQL syntax error with dynamically constructed INSERT?

I get the below error
An explicit value for the identity column in table 'c365online_script1.dbo.tProperty' can only be specified when a column list is used and IDENTITY_INSERT is ON.
The problem is with the statement that is dynamically constructed inside the two nested cursors from what I gather it should look something like
INSERT INTO dbo.Table(col1, col2, ...., colN) VALUES(Val1, val2, ...., ValN)
I am however unsure how I would construct the BELOW INSERT statement to resemble the above?.
EXEC('INSERT INTO ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id)
SET #Counter = 1 -- set the counter to make sure we execute loop only once.
END
You need to specify the list of columns because you don't insert into all of them (you don't insert into identity column). I'm guessing you're inserting from a table with the same structure from a different database - you need to specify all the source columns too in this case.
Your query will be (edit the column names):
EXEC('INSERT INTO ' + #Destination_Database_Name + '.dbo.' + #tablename + '(col1, col2, col3) SELECT col1, col2, col3 FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id)

SQL Server varchar to datetime

I have a field varchar(14) = 20090226115644
I need convert it to -> 2009-02-26 11:56:44 (datetime format)
My idea. use cast and convert.. but I always have errors.
Conversion failed when converting
datetime from character string.
I made this, but don`t like it..
SELECT
SUBSTRING(move,1,4) + '-' + SUBSTRING(move,5,2) + '-' + SUBSTRING(move,7,2) + ' ' + SUBSTRING(move,9,2) + ':' + SUBSTRING(move,11,2) + ':'+SUBSTRING(move,13,2) as new --
FROM [Test].[dbo].[container_events]
where move IS not null
Result :2009-02-26 11:56:44
The CAST operator in SQL Server has a well-defined list of formats which are supported - see on MSDN SQL Server Books Online.
Your format doesn't seem to fit any of those defined formats -> you're on your own, you have to use some custom logic (as you do) to bring that varchar field into a format that CAST can understand.
So what is your question now??
your logic looks correct and works for the given data. however, I'll bet that you have some bad data out there.
try this:
DECLARE #container_events table (PK int, move varchar(14))
SET NOCOUNT ON
INSERT INTO #container_events VALUES (1,'20090226115644')
INSERT INTO #container_events VALUES (2,'20090226116644')
INSERT INTO #container_events VALUES (3,'20090227010203')
INSERT INTO #container_events VALUES (4,'20090228010203')
INSERT INTO #container_events VALUES (5,'20090229010203')
SET NOCOUNT OFF
---list all bad dates
SELECT
SUBSTRING(move,1,4) + '-' + SUBSTRING(move,5,2) + '-' + SUBSTRING(move,7,2) + ' ' + SUBSTRING(move,9,2) + ':' + SUBSTRING(move,11,2) + ':'+SUBSTRING(move,13,2) as BadDatesOnly, move
FROM #container_events
where ISDATE(SUBSTRING(move,1,4) + '-' + SUBSTRING(move,5,2) + '-' + SUBSTRING(move,7,2) + ' ' + SUBSTRING(move,9,2) + ':' + SUBSTRING(move,11,2) + ':'+SUBSTRING(move,13,2))=0
---list all bad dates
SELECT
CONVERT(datetime,SUBSTRING(move,1,4) + '-' + SUBSTRING(move,5,2) + '-' + SUBSTRING(move,7,2) + ' ' + SUBSTRING(move,9,2) + ':' + SUBSTRING(move,11,2) + ':'+SUBSTRING(move,13,2)) as GoodDatesOnly, move
FROM #container_events
where ISDATE(SUBSTRING(move,1,4) + '-' + SUBSTRING(move,5,2) + '-' + SUBSTRING(move,7,2) + ' ' + SUBSTRING(move,9,2) + ':' + SUBSTRING(move,11,2) + ':'+SUBSTRING(move,13,2))=1
OUTPUT:
BadDatesOnly move
------------------- --------------
2009-02-26 11:66:44 20090226116644
2009-02-29 01:02:03 20090229010203
(2 row(s) affected)
GoodDatesOnly move
----------------------- --------------
2009-02-26 11:56:44.000 20090226115644
2009-02-27 01:02:03.000 20090227010203
2009-02-28 01:02:03.000 20090228010203
(3 row(s) affected)
Using the ISDATE (Transact-SQL) function you can determine if the date is valid or not. AS a result you can filter out the bad rows in your query, or find the bad rows and fix them, etc. it is up to you what to do with the bad data.

Resources