Returning Data without Accesing a Table - sql

The Situation (Ignore this it is boring):
I have reports that I created using reporting services. Some of these reports take the parameter, "Month". They enter in an integer for the month they want. Example: December = 12.
In order to view the report, I am simply using the Report Viewer in visual studio. I need the month field to be a drop down box in order to select the month by name. There is a feature in in reporting services that allows you to bind the field to a stored procedure in order to create value/text pairs for the drop down list.
The Problem:
I don't want to create a "months" table in my database but I need to have a stored procedure that can return all the month/int pairs. I'm sure there is a very easy solution to this but I'm not sure what it is! My first thought was creating a temp table, but I am not sure how to add manually add each month/int pair to the table... All your suggestions are appreciated!
What I want is the following statement, except without the use of the Months Table:
SELECT MonthID, MonthName
FROM Months

How about:
CREATE PROCEDURE ListMonths
AS
SELECT 1 AS MonthId, 'January' AS MonthName
union all select 2, 'February'
union all select 3, 'March'
union all select 4, 'April'
union all select 5, 'May'
union all select 6, 'June'
union all select 7, 'July'
union all select 8, 'August'
union all select 9, 'September'
union all select 10, 'October'
union all select 11, 'November'
union all select 12, 'December'
GO
Call this and I believe it returns what you want.

Do you really need to create a table for this? You could just do the selects manually:
SELECT 1, 'January' UNION ALL
SELECT 2, 'February' UNION ALL
...
SELECT 12, 'December'

Sounds like what you need is a view, basically you write a custom query and it returns it as a table.
Also, a SP can just contain a Query and it will return a table, just create it as:
CREATE PROCEDURE [dbo].[mytable]
-- Add the parameters for the stored procedure here
#inputarg1 = 0
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT
.....
FROM
.....
WHERE
.....
END

in the stored proc, do the following
Declare #Months Table
(monthNo TinyInt Primary Key Not Null,
name varChar(10) Not Null,
Abbrev char(3) = Substring(name,1,3))
Insert #Months ( monthNo, name) Values (1, 'January')
Insert #Months ( monthNo, name) Values (2, 'February')
...
Insert #Months ( monthNo, name) Values (12, 'December')
or, if you need this table in more than one stored proc, write a UDF that dies the same thing and returns this table to the calling proc...

WITH months AS
(
SELECT CAST('2009.01.01' AS DATETIME) AS m, 1 AS num
UNION ALL
SELECT DATEADD(month, 1, m), num + 1
FROM months
WHERE num < 12
)
SELECT num, DATENAME(month, m)
FROM months

Related

Members within a specific age group within one calendar month

I need to find anyone who was >=6 or <18 per month in 2022.
so for example...even if someone was five on 1/15/2022 and then turned 6 on 1/16/2022 will be counted. or if someone was 17 on 1/20/22 and then turned 18 on 1/21/2022 will still be counted.
im relatively new to sql so any help would be appreciated.
The dates are german format, but you should adapt the logic:
DECLARE #table Table
(kd_id int , birthdate DATE)
INSERT INTO #table
(
kd_id,
birthdate
)
SELECT 1, '01.10.2016'
UNION
SELECT 2, '09.10.2016'
UNION
SELECT 3, '10.10.2016'
UNION
SELECT 4, '11.10.2016'
UNION
SELECT 5, '17.10.2016'
UNION
SELECT 6, '01.10.2004'
UNION
SELECT 7, '09.10.2004'
UNION
SELECT 8, '10.10.2004'
UNION
SELECT 9, '11.10.2004'
UNION
SELECT 10, '17.10.2004'
UNION
SELECT 11, '01.01.2016'
UNION
SELECT 12, '01.01.2004'
UNION
SELECT 13, '01.01.2017'
UNION
SELECT 14, '31.12.2003'
UNION
SELECT 15, '31.12.2003'
UNION
SELECT 16, '31.10.2004'
UNION
SELECT 17, '30.09.2004'
UNION
SELECT 18, '01.11.2016'
--Query
DECLARE #month NVARCHAR(2) = '10' --October
,#year NVARCHAR(4) = '2022'
,#month_begin NVARCHAR(10)
,#month_end NVARCHAR(10)
SET #month_begin = '01.' + #month + '.2022'
SET #month_end = EOMONTH(#month_begin) --EOMONTH() = Last date of a month
SELECT kd_id
,birthdate
FROM #table
WHERE DATEDIFF(hour,birthdate,#month_begin)/8766 BETWEEN 6 AND 17
OR DATEDIFF(hour,birthdate,#month_end)/8766 BETWEEN 6 AND 17

Converting a string value into number of days

I have data in a column with values such as 4w4d, 1w0d, 2w5d, 0w6d.
How could I use this data to get the number of days out?
Create Table #temp
(
Data char(4),
ExpectedResult int
)
insert into #temp
(
Data,
ExpectedResult
)
select '4w4d','32'
union all
select '1w0d','7'
union all
select '2w5d','19'
union all
select '0w6d','6'
union all
select '0w5d','5'
union all
select '0w1d','1'
union all
select '0w3d','3'
union all
select '1w6d','13'
You need to parse out the week component and the day component and then convert into the number of days. The following is one way to do this:
-- Find the weeks, multiple by 7
convert(int, substring([Data], 1, charindex('w',[Data])-1))*7
-- Find the days and add on
+ convert(int, substring([Data], charindex('w',[Data])+1, charindex('d',[Data])-charindex('w',[Data])-1))
You can parse the string using string operations:
select convert(int, left(data, 1)) * 7 + convert(int, substring(data, 3, 1))
Here is a db<>fiddle with your sample data.

Return records less than date

I have a table where 2 columns are called Month and Year and are both INT. I need to return all the records that are less than the date provided.
So if I pass the following parameters #Month = 8 and #Year = 2017, I would like to return all records before August 2017. What is the best way to achieve this?
SELECT * FROM testTable
WHERE year <= #Year AND
month < #Month
is my current SQL. This won't work if I need to display the record that is November 2014
Compare them as dates. Like this:
SELECT * FROM testTable
WHERE DATEFROMPARTS(year, month, 1) <= DATEFROMPARTS(#Year, #Month, 1)
Pass The Parameter as Date. Like
DECLARE #MyDate DATE = '08-01-2014'
Now you can go for either of the below
SELECT
*
FROM YourTable
WHERE CAST(ConCAT([Monnth],'-01-',[Year]) AS DATE) = #MyDate
Or
SELECT
*
FROM YourTable
WHERE [Year] = YEAR(#MyDate)
AND [Month] = MONTH(#MyDate)
You can use DATEPART function of SQL Server
SELECT * FROM testTable
WHERE YEAR<= DATEPART(yy,yourdate) AND
MONTH < DATEPART(mm,yourdate)
It would be better to convert data types and query further.
DECLARE #testtable TABLE (id INT identity(1, 1), name VARCHAR(100), year INT, month INT)
INSERT INTO #testtable (name, year, month)
SELECT 'me', '2014', 10
UNION
SELECT 'you', '2017', 08
UNION
SELECT 'us', '2015', 10
UNION
SELECT 'Him', '2017', 10
UNION
SELECT 'Her', '2018', 1
SELECT *
FROM #testtable
WHERE CONCAT (year, '-', right('00' + cast(Month AS VARCHAR(2)), 2), '-', '01')
< = '2017-08-01'

converting varchar to date/Using isdate()

I have a flat file that I am importing into a SQL Server 2005 staging table as character data.
I need to convert the birthday field to datetime format when copying it to the final destination table. I was doing so using the following:
BIRTHDAY = case when isdate(DOB)=1 then convert(datetime, '19'+right(DOB, 2)+left(DOB, 2)+substring(DOB,3,2)) else null end
The problem is only 100+ of the birthdays from the 32k+ file are identified as dates.
I cannot see a difference between the ones that are dates and the ones that aren't. I have included a sampling below.
good date bad date
41129 100465
10531 122467
10429 20252
81030 62661
31231 20959
11028 91965
80928 60665
Looks like the raw data is in MMDDYY, but the months are not 0-padded.
Building on this assumption, you can parse the date parts like below and rebuild a datetime:
declare #raw table (dob varchar(100));
insert into #raw
select '41129' union all
select '10531' union all
select '10429' union all
select '81030' union all
select '31231' union all
select '11028' union all
select '80928' union all
select '100465' union all
select '122467' union all
select '20252' union all
select '62661' union all
select '20959' union all
select '91965' union all
select '60665'
select *,
[asDate] = dateadd(day, dd - 1, dateadd(month, mm - 1, dateadd(year, ('19' + yy)-1900, 0)))
from ( select dob,
substring(right('0' + dob, 6), 1, 2),
substring(right('0' + dob, 6), 3, 2),
substring(right('0' + dob, 6), 5, 2)
from #raw
) as stage (string, mm, dd, yy);

How can I get the most recent date in SQL?

I want to make a SQL query that gets todays date and the most recent date from a date column. So if I have three records in my database that have the following dates:
March 8, 2012
March 2, 2012
December 8, 2011
I want the SQL query to return all records for March 8, 2012 and March 2, 2012 (most recent date). How can I do this?
I can date today's date using:
CONVERT( varchar(100), DATEADD( DAY, 0, getdate() ), 111)
Thank You
Edit:
Thanks everyone. I just have one more question. I have created two views:
create view with top dates
CREATE VIEW topDates AS
select DISTINCT TOP 3 replace(CONVERT(VARCHAR(20),date,111),'-','/') AS dates from CSAResults.dbo.Details
create view dateTwo
select *
from (select ROW_NUMBER() over (order by dates desc) as srNo, dates
from topDates)
AS employee
WHERE srNo=2
And now I want to select * from my DB where a column is equal to the 'dates' column from the view 'dateTwo'
select buildNumber
from CSAResults.dbo.Details
where buildNumber LIKE '%Main '+ (SELECT dates FROM dateTwo) + '%'
But this returns nothing.
Thanks
You can do the following:
select date
from yourtable
where
(
date = Convert(varchar(10), getdate(), 101)
OR
date IN (SELECT Max(date)
FROM yourtable
WHERE date!= Convert(varchar(10), getdate(), 101))
)
Here is an example script that does what you are asking. It uses a sub-query to select all records with MAX on the date. You would just add an OR to also select items for the current date.
DECLARE #A TABLE
(
part_no VARCHAR(5),
rev CHAR,
on_hand TINYINT,
safety_stock TINYINT,
so_no VARCHAR(5),
so_date DATETIME
)
INSERT #A
SELECT '12345', 'A', 10, 15, 'S1234', '12/14/2009' UNION ALL
SELECT '12345', 'A', 10, 15, 'S1233', '10/01/2009' UNION ALL
SELECT '12345', 'A', 10, 15, 'S1232', '08/02/2009' UNION ALL
SELECT '12346', '', 5, 0, 'S1231', '08/01/2009' UNION ALL
SELECT '12347', '-', 0, 0, 'S1230', '10/20/2009' UNION ALL
SELECT '12347', '-', 0, 0, 'S1229', '07/15/2009'
SELECT * FROM #A AS A
WHERE so_date =
(
SELECT MAX(so_date)
FROM #A AS B
WHERE B.part_no = A.part_no AND B.Rev = A.Rev
)
SELECT *
INTO #TEMP
FROM
(
SELECT GETDATE() DATE_FIELD, 'Blah1...' OTHER_FIELDS
UNION SELECT GETDATE() DATE_FIELD, 'Blah2...' OTHER_FIELDS
UNION SELECT DATEADD(d,-1,GETDATE()) DATE_FIELD, 'Blah3...' OTHER_FIELDS
UNION SELECT DATEADD(d,-1,GETDATE()) DATE_FIELD, 'Blah4...' OTHER_FIELDS
UNION SELECT DATEADD(d,-3,GETDATE()) DATE_FIELD, 'Blah5...' OTHER_FIELDS
) A
SELECT * FROM #TEMP
SELECT * FROM
(
SELECT DATE_FIELD, OTHER_FIELDS,
DENSE_RANK() OVER (ORDER BY DATE_FIELD DESC) _RANK
FROM #TEMP
) A
WHERE A._RANK < 3
For your second question:
select buildNumber
from CSAResults.dbo.Details
inner join dateTwo
on buildNumber LIKE '%Main '+ dateTwo.dates + '%'