How to set a date variable with several days - sql

I need to get a list of dates data. So far I'm only selecting one date at a time but I need it to be multiple days.
declare #evalDate1 as Date
declare #evalDate [date];
set #evalDate1 = '2020-10-20'
I tried this:
declare #evalDate1 as Date
declare #evalDate [date];
set #evalDate1 = ('2020-10-20' or '2020-10-21')
But this doesn't work. Can anyone help? Thank you!

you either need to make temp table
create table #evalDate ( value date)
insert into #evalDate values ('2020-10-20'), ('2020-10-21')
or a table variable
create #evalDate table ( value date)
insert into #evalDate values ('2020-10-20'), ('2020-10-21')

Related

Convert datetime and divide into 2 column in SQL server

I'm working in a SQL table which contains a column called 'DATETIME' and it contains values like '201701011730'. The first 8 character is the date and last 4 characters is the time. Now I need to create a column called 'TIME' and also a column called 'DATE' to replace 'DATETIME'. The example has shown below:
DATETIME(201701011730)--> DATE(20170101) and TIME(1730)
I'm trying to work with a update statement with CONVERT function but it doesn't worked. Is there any suggestion to work with?
Assuming your combined column is called dattimCol you can do the following:
select convert(date, left(dattimCol,8)) [date],
convert(time, stuff(substring(dattimCol,9,4),3,0,':')) [time]
from yourTable;
It is important to insert the ':' into the time-string before converting it.
As an update statement this transforms to:
update yourTable SET
dateCol=convert(date, left(dattimCol,8)),
timeCol=convert(time, stuff(substring(dattimCol,9,4),3,0,':'));
OK, here are some short explanations, first substring():
substring(dattimCol,9,4)
(I could have used right(dattimCol,4) instead) will get us the 4 last digits of the datetime string representing the time of day ("1730"). I then "stuff" a colon (":") in the middle of that resultant string by using the stuff() function (available since at least SQL-server 2005)
stuff( sourceString, beginInsertionAtPosition, countOfCharsToDelete, insertionString )
Try as follows:
CREATE TABLE DATES(DATETIME VARCHAR(20))
INSERT INTO DATES VALUES('201701011730')
INSERT INTO DATES VALUES('201801011740')
SELECT * FROM DATES
ALTER TABLE DATES ADD [DATE] VARCHAR(8)
ALTER TABLE DATES ADD [TIME] VARCHAR(4)
DECLARE #DATETIME VARCHAR(MAX)
DECLARE C CURSOR FOR
SELECT DATETIME FROM DATES
OPEN C
FETCH NEXT FROM C INTO #DATETIME
WHILE ##FETCH_STATUS=0
BEGIN
UPDATE DATES SET DATE=(SELECT SUBSTRING(DATETIME,0,9) FROM DATES WHERE DATETIME=#DATETIME) WHERE DATETIME=#DATETIME
UPDATE DATES SET TIME=(SELECT SUBSTRING(DATETIME,9,LEN(DATETIME)) FROM DATES WHERE DATETIME=#DATETIME) WHERE DATETIME=#DATETIME
FETCH NEXT FROM C INTO #DATETIME
END
CLOSE C
DEALLOCATE C
SELECT * FROM DATES
I have used the below code for showing the example you can use the below code
Create Table #ABC(T1 NVARCHAR(500),date nvarchar(255),Time nvarchar(255))
Insert Into #ABC(T1) Values ('201701011730')
Update #ABC
SET date=SUBSTRING(T1,0,9), Time=SUBSTRING(T1,9,LEN(t1))
I think you are using string format rather then date and time format for more information you can go to the following links
http://www.w3schools.com/sql/func_convert.asp
https://msdn.microsoft.com/en-us/library/ms187928.aspx
-----Declare #datetime_str variable where set datetime in string format
Declare #datetime_str varchar(20);
set #datetime_str='201701011730';
select SUBSTRING(#datetime_str,0,9) as date, SUBSTRING(#datetime_str,9,12) as time
--------------------or-------------------
select SUBSTRING('201701011730',0,9) as date, SUBSTRING('201701011730',9,12) as time

writing from a SQL view to a Table

Hello I've got this SQL View (Namely Login_Monitor) that I've created using a number of table joins
What I'm wanting to do now is to use a few columns in this View to write to a seperate table that I've created.
But Im gettiing Null values written to table instead of actual data.
This is how I created my destination table
create table MS_Login_Monitor
(date date,
time time,
USERID char(15),
COMPANY_NAME char(65),
LOGIN_DATE_TIME datetime,
TIME_SINCE_LAST_ACTION int,
)
This is the query I used to write view data to destination table
declare #date date
declare #time time
declare #USERID char(20)
declare #COMPANY_NAME char(65)
declare #LOGIN_DATE_TIME datetime
declare #TIME_SINCE_LAST_ACTION nchar(7)
set #date = CURRENT_TIMESTAMP
set #time = CURRENT_TIMESTAMP
select * from Login_Monitor
INSERT INTO DYNAMICS..MS_Login_Monitor (date, time,USERID, COMPANY_NAME, LOGIN_DATE_TIME, TIME_SINCE_LAST_ACTION)
VALUES (#date, #time,#USERID,#COMPANY_NAME, #LOGIN_DATE_TIME, #TIME_SINCE_LAST_ACTION)
could someone explain please why I get NULL values written to table please or if there are errors in my SQL query.
Thanks
You can try something like this;
INSERT INTO DYNAMICS..MS_Login_Monitor (date, time,USERID, COMPANY_NAME, LOGIN_DATE_TIME, TIME_SINCE_LAST_ACTION)
select #date, #time, X, Y.....(use actual column names of view) from Login_Monitor
You dont need other parameters.

How to compare smalldatetime in stored procedure

I'm writing stored procedure to compare dates but it's not working properly. How can I make it so it compares only the dates but not the time? What I'm trying to do is compare the times and if the Id is null than insert a new entry with the same name but new time. I'm keeping multiple entries with same name but different test time.
ALTER PROCEDURE [dbo].[UL_TestData]
(
#Name varchar(30),
#Test_Time smalldatetime,
#ID INT output
)
AS
Declare #UpdateTime smalldatetime
SELECT #ID=ID FROM Info_User WHERE Name=#Name AND UpdateTime= #Test_Time
IF(#ID IS NULL)
BEGIN
INSERT INTO Info_User (Name, UpdateTime) VALUES (#Name, #UpdateTime)
END
there are a lot of solutions to this depending on what type of DBMS, however here is one:
SELECT #ID=ID FROM Info_User WHERE Name=#Name AND floor(cast(#UpdateTime as float))= floor(cast(#Test_Time as float))
this works because smalldatetime's date is stored a whole numbers, where the time is stored as decimals.
I would cast the dates to a plain date which makes this solution independent of implementation details
select #ID=ID
from info_user
where Name = #Name
and cast (UpdateTime as Date) = Cast(#TestTime as Date)
However, I would either add the date part of the UpdateTime as an additional (calculated) column or split the information into a date and a time part. This makes it much easier to query entries by the plain date.
As a rule of thumb: The type of columns (in general: the table layout) greatly depends on the type of query you usually run against your data.
Edit: As attila pointed out, the date datatype only exists in version 2008 and up

Use an SSRS multi-value parameter in a SQL query without using the IN operator

I have to pass multiple values (eg: Year1, year2, year3, etc.) to the same query, but I cannot use the IN condition as I'm using less than or equal to in most of the cases. Can I do this by passing multiple values through the same parameter without changing the query?
Is it possible to get multiple values from an SSRS parameter and pass them on to the query to get the output as:
Year1 Year2 Year3
Value(output) Value(output) Value(output)
You can pass the multi-value parameter as a comma separated string but your SQL query is going to need updating to handle that CSV string. In order to pass the multi-value parameter as a CSV string you would open the dataset properties and go to the parameters tab. Then set the value of your parameter to this expresssion:
=JOIN(Parameters!MultiValueYearParameter.Value,",")
This will join all of the values in the multivalue parameter together and use a comma as the delimiter. You can then process this using the split function below (or just modify it to work inline in your SQL if you either cannot or don't need to create a separate function to do this).
This blog post on a Split Function for T-SQL using FOR XML shows how to do this without using string parsing or a while loop. String parsing is prone to error and isn't scalable and while loops should just be avoided in SQL whenever possible.
Below I've modified the split function to return a table of DATE values that you can then use in an INNER JOIN to filter your query using whatever operators you like.
--this is the parameter passed from the report
--(the date strings may not be formatted this way. do not try to rely on that)
DECLARE #YearParameter VARCHAR(MAX) = '2014-01-01,2011-12-02,2015-10-22';
--use this to do the xml parsing
declare #xml xml = N'<root><r>' + replace(#YearParameter,',','</r><r>') + '</r></root>'
--create a table variable to store the date values
DECLARE #dateValues TABLE (val DATE);
--parse the xml/csv string and cast the results to a DATE and insert into the table var
INSERT INTO #dateValues
select CAST(r.value('.','varchar(max)') AS DATE) AS val
from #xml.nodes('//root/r') as records(r);
You can then use that table variable to filter your SQL query. I've given an example of how to use it below.
In the example I create a table of rows with a start and end date. Then I filter that table to show only rows where a parameter value is between the start and end date.
DECLARE #testTable TABLE (Descript VARCHAR(25), startDate DATE, endDate DATE);
INSERT INTO #testTable (Descript, startDate, endDate)
VALUES ('row1', '2014-05-01','2014-08-01'), ('row2', '2013-10-01','2014-01-10'), ('row3', '2015-10-01','2015-12-15'),('row4','2013-01-01','2015-01-01'),
--these rows won't appear in the result set
('row5','2010-01-01','2010-06-01'), ('row6','2013-12-25','2014-05-20');
-- get all rows from the test table where a selected parameter value
-- is between the start and end dates.
SELECT *
FROM #testTable AS tbl
WHERE EXISTS (
SELECT *
FROM #dateValues
WHERE val BETWEEN tbl.startDate AND tbl.endDate
);
In SSRS you can build tables and complex solutions.
In the Text Query of report builder here is an example of splitting apart a parameter to get three dates.
BEGIN
/* suppose the inbound pram is a string with 10 places per date '01/01/2010,11/12/2012,05/06/2013' */
/* you could also nip the string apart by each comma... */
DECLARE #YEAR1 DATETIME
DECLARE #YEAR2 DATETIME
DECLARE #YEAR3 DATETIME
SET #YEAR1 = CAST(SUBSTRING(#INBOUNDPARAM, 1, 10) AS DATETIME)
SET #YEAR2 = CAST(SUBSTRING(#INBOUNDPARAM, 12, 10) AS DATETIME)
SET #YEAR3 = CAST(SUBSTRING(#INBOUNDPARAM, 23, 10) AS DATETIME)
SELECT #YEAR1 AS Year1, #YEAR2 AS Year2, #YEAR3 AS Year3
END
Of course the Year of the date is just YEAR(#Year1) = 2010 for example...

SQL Server Include user function result into select query

I have this stored function
function GetPrevReading(
#utility int,
#asofdate datetime
) returns decimal(10,5)
This function returns the previous meter reading from the table with the following fieds:
utility - int
date - datetime
reading - numeric(18,4)
When I use select on this table I want to set a date as a parameter and get this from the table:
Utility Previous Reading
(distinct) GetPrevReading(utility from query, #date from parameter)
I want the function GetPrevReading to take parameter 'utility' from the current row.
Is it possible to accompish this with a query or should I make a stored procedure?
For example, this is the table:
Utility Date Reading
1 2013-10-1 105.6
1 2013-11-1 123.72
2 2013-10-1 226.1
2 2013-10-1 238.18
Now, if I set parameter #date to 2013-10-29 I should get this result:
Utility PreviousReading
1 105.6
2 226.1
Here, my function should get #utility=1 and #asofdate='2013-10-29' on the first row and #utility=2 and #asofdate='2013-10-29' on the second one.
Try this out. I fixed some inconsistencies in your data types, and assumed that your last line of sample data really should have had 2013-11-01 as the date. Also, the way that the function is written, it's not getting the previous reading, but the reading on that date.
CREATE TABLE MyTable (
Utility Int,
Date Date,
Reading Decimal(10,5)
);
INSERT INTO MyTable (Utility, Date, Reading)
VALUES
(1,'2013-10-01', 105.60),
(1,'2013-11-01', 123.72),
(2,'2013-10-01', 226.10),
(2,'2013-11-01', 238.18);
CREATE FUNCTION dbo.GetPrevReading(
#utility int,
#asofdate datetime
)
RETURNS Decimal(10,5)
AS
BEGIN
RETURN (
SELECT TOP 1 Reading
FROM MyTable
WHERE Utility = #Utility
AND Date = #asofdate
ORDER BY Date DESC
)
END;
SELECT
Utility
,Date
,dbo.GetPrevReading(Utility, Date)
FROM (
SELECT Utility, Max(Date) Date
FROM MyTable
WHERE Date < '2013-10-29'
GROUP BY Utility
) x;
Am I understanding the question; the function returns for this call
GetPrevReading( 1,2013-10-29)
Returns
1, 105.6
2, 226.1
And you want to join between the function and its results and the underlying table? You can do this in SQL 2005 + using the Apply join
Select
…
From tblUtilityReadings
Cross Apply GetPrevReading(tblUtilityReadings.utility, #date)