I am currently working on Microsoft SQL Server 2008. My question is: I have 5 conditions represented by parameters #rep, #name, #work, #year, #seg. How do I write a query that will display the result if I only fill up certain conditions=? And then I have a query that will count total number of visit. For example,
DECLARE #Rep varchar(100)
DECLARE #Name varchar(100)
DECLARE #Work varchar (100)
DECLARE #Year int
DECLARE #Seg int
SET #RepCode = ''
SET #Name = 'SYED'
SET #Work = ''
SET #Year = '2014'
SET #Seg = ''
I want the result to display the result for syed with year 2014 and the rep, work, and his seg. I tried this but it didn't work out.
if #Rep IS NOT NULL
SELECT Id, Name, Work, YEAR, Rep
FROM #SalesRepVisit
WHERE Rep = #Rep
ELSE
if #Name IS NOT NULL
SELECT Id, Name, Work, YEAR, Rep
FROM #SalesRepVisit
WHERE Name = #Name
ELSE
if #Work IS NOT NULL
SELECT Id, Name, Work, YEAR, Rep
FROM #SalesRepVisit
WHERE Work = #Work
ELSE
if #Year IS NOT NULL
SELECT Id, Name, Work, YEAR, Rep
FROM #SalesRepVisit
WHERE YEAR = #Year
ELSE
if #Seg IS NOT NULL
SELECT Id, Name, Work, YEAR, Rep
FROM #SalesRepVisit
WHERE Seg = #Seg
To count the total number of visit I have this query.
SELECT DISTINCT
Id as Id,
Name as Customername,
Rep As Repcode,
(Select COUNT(*) from #SalesRepVisit where Month = 1 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'January',
(Select COUNT(*) from #SalesRepVisit where Month = 2 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'February',
(Select COUNT(*) from #SalesRepVisit where Month = 3 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'March' ,
(Select COUNT(*) from #SalesRepVisit where Month = 4 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'April',
(Select COUNT(*) from #SalesRepVisit where Month = 5 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'May',
(Select COUNT(*) from #SalesRepVisit where Month = 6 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'June',
(Select COUNT(*) from #SalesRepVisit where Month = 7 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'July',
(Select COUNT(*) from #SalesRepVisit where Month = 8 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'August',
(Select COUNT(*) from #SalesRepVisit where Month = 9 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'September',
(Select COUNT(*) from #SalesRepVisit where Month = 10 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'October',
(Select COUNT(*) from #SalesRepVisit where Month = 11 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'November',
(Select COUNT(*) from #SalesRepVisit where Month = 12 and Rep = #Rep and Name = #Name AND Work = #Work and YEAR = #Year)as 'December',
Work as Work,
YEAR as Year
FROM #SalesRepVisit
WHERE
Rep = #Rep and Name = #Name AND Work = #Work AND YEAR = #Year
The query doesn't display anything. I want the query to display the results of 'syed' with his name, rep, work, seg, and year.
Improved Answer of #Radar
In the Where condition we can use Case statement
SELECT Id,
Name,
SUM ( CASE WHEN Month =1 THEN 1 ELSE 0 END ) as 'January',
SUM ( CASE WHEN Month =2 THEN 1 ELSE 0 END ) as 'February',
...
...
FROM #SalesRepVisit
where ( Rep = Case When IsNull(#RepCode,'') ='' then Rep else #RepCode end)
AND ( Name = Case When IsNull(#Name,'')='' then Name else #Name end)
AND ( Work = Case When IsNull(#Work,'') ='' then Work else #Work end)
AND ( YEAR = Case When IsNull(#Year,'') ='' then YEAR else #Year end)
GROUP BY Id, Name
you are setting default value to empty string and comparing with NOT NULL as empty string is NOT NULL, search is done for empty string.
First part to get results when only filters condition is met
SELECT Id,Name,Work,YEAR,Rep from #SalesRepVisit
WHERE ( #RepCode ='' OR Rep = #RepCode )
AND ( #Name ='' OR Name = #Name )
AND ( #Work ='' OR Work = #Work )
AND ( #Year ='' OR YEAR = #Year )
To count the number of visits in each Month based on the filter criteria, you can use case based aggregation
SELECT Id,
Name,
SUM ( CASE WHEN Month =1 THEN 1 ELSE 0 END ) as 'January',
SUM ( CASE WHEN Month =2 THEN 1 ELSE 0 END ) as 'February',
...
...
FROM #SalesRepVisit
where ( #RepCode ='' OR Rep = #RepCode )
AND ( #Name='' OR Name = #Name )
AND ( #Work ='' OR Work = #Work )
AND ( #Year ='' OR YEAR = #Year )
GROUP BY Id, Name
Related
I have data in a row as below in SQL (2012) table
ID Value StartDate EndDate
123 5000 14/04/2017 15/12/2017
I would like to Split the row into each individual month as below:
ID Value StartDate EndDate
123 5000 14/04/2017 30/04/2017
123 5000 01/05/2017 31/05/2017
123 5000 01/06/2017 30/06/2017
123 5000 01/07/2017 31/07/2017
123 5000 01/08/2017 30/08/2017
123 5000 01/09/2017 31/09/2017
123 5000 01/10/2017 31/10/2017
123 5000 01/11/2017 30/11/2017
123 5000 01/12/2017 15/12/2017
Appreciate help in this matter.
You can do it like this:
WITH tally
AS (SELECT TOP (1000)
ROW_NUMBER() OVER (ORDER BY t1.object_id) AS N
FROM master.sys.all_columns t1
CROSS JOIN master.sys.all_columns t2),
rowset
AS (SELECT ID,
Value,
DATEADD(m, N - 1, StartDate) AS StartDate,
Enddate,
N
FROM tally, MyDates
WHERE DATEFROMPARTS(YEAR(DATEADD(m, N - 1, StartDate)),
MONTH(DATEADD(m, N - 1, StartDate)), 1) <= EndDate)
SELECT Id,
Value,
CASE
WHEN N = 1 THEN
StartDate
ELSE
DATEFROMPARTS(YEAR(StartDate), MONTH(StartDate), 1)
END AS StartDate,
CASE
WHEN DATEADD(d, -DAY(DATEADD(m, 1, StartDate)), DATEADD(m, 1, StartDate)) <= EndDate THEN
DATEADD(d, -DAY(DATEADD(m, 1, StartDate)), DATEADD(m, 1, StartDate))
ELSE
Enddate
END AS EndDate
FROM rowset
ORDER BY ID, StartDate;
Use below query to get the result
DECLARE #Temp TABLE
(
ID INT
,Value NUMERIC(10,2)
,StartDate DATE
,EndDate DATE
)
DECLARE #NewTable TABLE
(
id INT IDENTITY(1,1)
,item INT
,Value NUMERIC(10,2)
,StartDate DATE
,EndDate DATE
)
INSERT INTO #Temp
SELECT 123,5000 ,'2017-04-14','2018-12-15'
DECLARE #SDate date
DECLARE #EDate date
declare #LastDay INT =0
SELECT top 1 #SDate=StartDate,#EDate=EndDate FROM #Temp
declare #Year int = 0
declare #Month int = 0
declare #Index INT =1
DECLARE #Lenght int =DATEDIFF(MONTH,#SDate,#EDate) +1
WHILE #Index<=#Lenght
BEGIN
IF #Index=1 BEGIN
-- first record
SELECT #Year= YEAR(#SDate)
SELECT #Month = MONTH(#SDate)
-- get last day of the date
SELECT #LastDay = day(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#SDate)+1,0)))
SELECT #EDate= CONVERT(VARCHAR(10),#Year)+'-'+CONVERT(VARCHAR(10),#Month)+'-
'+CONVERT(VARCHAR(10),#LastDay)
INSERT INTO #NewTable
SELECT 123,5000,#SDate, #EDate
END ELSE IF #Index = #Lenght BEGIN
SELECT #Month = #Month+1
IF #Month>12 BEGIN
SELECT #Month =1
SELECT #Year =#Year +1
END ELSE BEGIN
SELECT #Year= YEAR(#EDate)
END
SELECT #SDate =CONVERT(VARCHAR(10),#Year)+'-'+CONVERT(VARCHAR(10),#Month)+ '-01'
INSERT INTO #NewTable
SELECT 123,5000 ,#SDate,#EDate
END ELSE BEGIN
SELECT #Month = #Month+1
if #Month>12 BEGIN
SELECT #Month =1
SELECT #Year =#Year +1
END
SELECT #SDate =CONVERT(VARCHAR(10),#Year)+'-'+CONVERT(VARCHAR(10),#Month)+ '-01'
SELECT #LastDay = day(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#SDate)+1,0)))
SELECT #EDate= CONVERT(VARCHAR(10),#Year)+'-'+CONVERT(VARCHAR(10),#Month)+'-'+CONVERT(VARCHAR(10),#LastDay)
INSERT INTO #NewTable
SELECT 123,5000 ,#SDate,#EDate
END
SELECT #Index=#Index+1
end
SELECT * from #NewTable
--select day(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,getdate())+1,0)))
I have temp table data in sql. I need modify data in that table.
Please find snapshot attached
I need to have a col having month data like for 01-03 jan-mar
this is code I have written. It's not working:
DECLARE #month VARCHAR(50) -- month
DECLARE #year VARCHAR(256) -- year
DECLARE #monthf VARCHAR(256) -- year
DECLARE #months VARCHAR(256) -- year
DECLARE db_cursor CURSOR FOR
SELECT months,[year] FROM #temp where len(months)>4
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #month,#year
WHILE ##FETCH_STATUS = 0
BEGIN
IF SUBSTRING(#month,0,3) = '01'
set #monthf='Jan'
ELSE IF SUBSTRING(#month,0,3) = '02'
set #monthf='Feb'
ELSE IF SUBSTRING(#month,0,3) = '03'
set #monthf='Mar'
ELSE IF SUBSTRING(#month,0,3) = '04'
set #monthf='Apr'
ELSE IF SUBSTRING(#month,0,3) = '05'
set #monthf='May'
ELSE IF SUBSTRING(#month,0,3) = '06'
set #monthf='Jun'
ELSE IF SUBSTRING(#month,0,3) = '07'
set #monthf='Jul'
ELSE IF SUBSTRING(#month,0,3) = '08'
set #monthf='Aug'
ELSE IF SUBSTRING(#month,0,3) = '09'
set #monthf='Sep'
ELSE IF SUBSTRING(#month,0,3) = '10'
set #monthf='Oct'
ELSE IF SUBSTRING(#month,0,3) = '11'
set #monthf='Nov'
ELSE IF SUBSTRING(#month,0,3) = '12'
set #monthf='Dec'
IF SUBSTRING(#month,4,2) = '01'
set #months='Jan'
ELSE IF SUBSTRING(#month,4,2) = '02'
set #months='Feb'
ELSE IF SUBSTRING(#month,4,2) = '03'
set #months='Mar'
ELSE IF SUBSTRING(#month,4,2) = '04'
set #months='Apr'
ELSE IF SUBSTRING(#month,4,2) = '05'
set #months='May'
ELSE IF SUBSTRING(#month,4,2) = '06'
set #months='Jun'
ELSE IF SUBSTRING(#month,4,2) = '07'
set #months='Jul'
ELSE IF SUBSTRING(#month,4,2) = '08'
set #months='Aug'
ELSE IF SUBSTRING(#month,4,2) = '09'
set #months='Sep'
ELSE IF SUBSTRING(#month,4,2) = '10'
set #months='Oct'
ELSE IF SUBSTRING(#month,4,2) = '11'
set #months='Nov'
ELSE IF SUBSTRING(#month,4,2) = '12'
set #months='Dec'
update #temp set [Month]= where months=
Delete from #temp where months=SUBSTRING(#month,0,3) and [Year]=#year
Delete from #temp where months=SUBSTRING(#month,4,2) and [Year]=#year
FETCH NEXT FROM db_cursor INTO #month,#year
END
CLOSE db_cursor
DEALLOCATE db_cursor
I need another column with month names like: for 01-03 it should give jan-mar
Can you please help me out? I need a separate column for month string data.
You don't need a cursor at all.
IF OBJECT_ID('tempdb..#Data') IS NOT NULL
DROP TABLE #Data
CREATE TABLE #Data (
Month VARCHAR(100),
ResultMonthText VARCHAR(100))
INSERT INTO #Data (
Month)
VALUES
('01-03'),
('07'),
('03'),
('03-05'),
('05-09'),
('02')
;WITH ParsedMonths AS
(
SELECT
D.Month,
D.ResultMonthText,
First = CONVERT(INT, SUBSTRING(D.Month, 1, 2)),
Second = CONVERT(INT, NULLIF(SUBSTRING(D.Month, 4, 2), ''))
FROM
#Data AS D
),
MonthNames AS
(
SELECT
D.Month,
D.ResultMonthText,
FirstAsName = SUBSTRING(
DATENAME(
MONTH,
DATEADD(MONTH, D.First, 0) - 1 ),
1,
3),
SecondAsName = SUBSTRING(
DATENAME(
MONTH,
DATEADD(MONTH, D.Second, 0) - 1 ),
1,
3)
FROM
ParsedMonths AS D
)
UPDATE D SET
ResultMonthText = D.FirstAsName + ISNULL('-' + D.SecondAsName, '')
FROM
MonthNames AS D
SELECT
*
FROM
#Data AS D
/*
Result:
Month ResultMonthText
------- ------------
01-03 Jan-Mar
07 Jul
03 Mar
03-05 Mar-May
05-09 May-Sep
02 Feb
*/
EDIT: Do this if you still want to keep your cursor (although I strongly suggest you stop using them whenever you can):
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #month,#year
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #FirstMonthNumber INT = CONVERT(INT, SUBSTRING(#month, 1, 2))
DECLARE #SecondMonthNumber INT = CONVERT(INT, NULLIF(SUBSTRING(#month, 4, 2), ''))
DECLARE #FirstMonthText VARCHAR(10) = SUBSTRING(
DATENAME(
MONTH,
DATEADD(MONTH, #FirstMonthNumber, 0) - 1 ),
1,
3)
DECLARE #SecondMonthText VARCHAR(10) = SUBSTRING(
DATENAME(
MONTH,
DATEADD(MONTH, #SecondMonthNumber, 0) - 1 ),
1,
3)
update #temp set
YourNewMonthColumn = #FirstMonthText + ISNULL('-' + #SecondMonthText, '')
WHERE
months = #month
FETCH NEXT FROM db_cursor INTO #month,#year
END
I don't know why you update the column and then delete the row also.
Maybe
update #temp set [Month] = #monthf where months = #months
We have a table showing amounts (CHGCNT) for 3 dates (5-9-2016, 5-10-2016, 5-11-2016) for each store & Depts.
I want to be able to see the records in a table like this:
I already applied the following query
declare #dt as datetime
declare #dt1 as varchar(10)
declare #dt2 as varchar(10)
declare #dt3 as varchar(10)
select distinct #dt = min(effdt) from [HQExtract].[dbo].[FSM_PRICE_TAGCOUNT]
-- print CONVERT(CHAR(10), #dt, 110) + ' ---- ' + CONVERT(CHAR(10), #dt+1 , 110)
set #dt1 = CONVERT(CHAR(10), #dt, 110)
set #dt2 = CONVERT(CHAR(10), #dt +1 , 110)
set #dt3 = CONVERT(CHAR(10), #dt + 2 , 110)
--print #dt1 + ' ---- ' + #dt2 + '-----' + #dt3
SELECT DEPTNM, DEPT, [#dt1] , [#dt2] , [#dt3]
FROM [HQExtract].[dbo].[FSM_PRICE_TAGCOUNT]
PIVOT
(
SUM(CHGCNT)
FOR effdt IN ( [#dt1] , [#dt2] , [#dt3])
) AS P
but it is returning dates
I like the SUM-CASE approach:
SELECT deptnm,
SUM(CASE WHEN effdt = '2016-05-09' THEN chgcnt ELSE 0 END) "2016-05-09",
SUM(CASE WHEN effdt = '2016-05-10' THEN chgcnt ELSE 0 END) "2016-05-10",
SUM(CASE WHEN effdt = '2016-05-11' THEN chgcnt ELSE 0 END) "2016-05-11",
SUM(effdt) Total
FROM [HQExtract].[dbo].[FSM_PRICE_TAGCOUNT]
GROUP BY deptnm;
I have a table with year and month wise values at column level.
Table Structure
----------------
Franchise Year Month1 Month2 Month3 Month4 ....Month12
Need to fetch values of last six month values from current month through SQL. Can anybody help?
Eg. If I need last six months, It should be current year record with month2 and month1 values as well as 2013 record with Month12, Month11, Month10, Month9 values.
DECLARE #MonthStart date
DECLARE #yyyy char(4)
DECLARE #mmm char(3)
DECLARE #monthColumn varchar(7)
DECLARE #SQL nvarchar(max)
set #MonthStart = DATEADD(day,1-DAY(getdate()), getdate())
set #MonthStart = DATEADD(month,-6,#MonthStart )
SET #SQL = 'SELECT Franchise'
WHILE DATEDIFF(month,#MonthStart,GETDATE() )>0
BEGIN
SET #yyyy = DATENAME(yyyy,#MonthStart )
SET #mmm = DATENAME(mm,#MonthStart )
SET #monthColumn = 'Month'+convert(varchar(2),DATEpart(m,#MonthStart ))
SET #SQL = #SQL +',
SUM(CASE WHEN Year = '+#yyyy+' THEN ['+#monthColumn +'] ELSE NULL END) AS ['+#mmm+' '+#yyyy +']'
set #MonthStart = DATEADD(month,1,#MonthStart )
END
/*Substitute with the name of the table*/
SET #SQL = #SQL +'
FROM [TableName] '
/*For demonstration purposes show the SQL to be executes*/
PRINT #SQL
/*Try to Execute it */
EXEC (#SQL)
This will generate and execute a statement along the lines of
SELECT Franchise,
SUM(CASE WHEN Year = 2013 THEN [Month8] ELSE NULL END) AS [Aug 2013],
SUM(CASE WHEN Year = 2013 THEN [Month9] ELSE NULL END) AS [Sep 2013],
SUM(CASE WHEN Year = 2013 THEN [Month10] ELSE NULL END) AS [Oct 2013],
SUM(CASE WHEN Year = 2013 THEN [Month11] ELSE NULL END) AS [Nov 2013],
SUM(CASE WHEN Year = 2013 THEN [Month12] ELSE NULL END) AS [Dec 2013],
SUM(CASE WHEN Year = 2014 THEN [Month1] ELSE NULL END) AS [Jan 2014]
FROM [TableName]
I have a stored procedure that looks something like this :
CREATE PROCEDURE [dbo].[spRS_Get]
#Year Varchar(20),
#Month Varchar(20)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Paramdate datetime;
DECLARE #ParamYear varchar(4);
DECLARE #ParamMonth varchar(2);
DECLARE #Concatt varchar(10);
SET #ParamYear = #Year;
SET #ParamMonth = #Month;
SET #Concatt = #ParamMonth + '-' + '01' + '-' + #ParamYear;
SET #Paramdate = CONVERT(datetime, #Concatt);
SELECT Item
,SUM(CASE WHEN [MONTH] = month(#ParamDate) THEN Sales END) AS month(#ParamDate)
,SUM(CASE WHEN [MONTH] = month(#ParamDate) - 1 THEN Sales END) AS month(#ParamDate) - 1,
,SUM(CASE WHEN [MONTH] = month(#ParamDate) THEN Sales END) - SUM(CASE WHEN [MONTH] = month(#ParamDate) - 1 THEN Sales END) AS month(#ParamDate) - month(#ParamDate) - 1
FROM ABC
GROUP BY Item
In the above query , the part after the AS causes the error.
I want to use the parameter name as the name of the column , but it gives me an error. Is there a way I can use
the parameter name as the name of the month ?
You can only do that by building the select statement as a string and then executing it using the sp_executesql command.
So you'd get something like this:
declare #month0 varchar(2) = cast(month(#paramdate) as varchar(2));
declare #month1 varchar(2) = cast((month(#ParamDate) - 1) as varchar(2));
declare #month2 varchar(2) =
cast((month(#ParamDate) - month(#ParamDate) - 1) as varchar(2));
declare s nvarchar(1024) =
'SELECT Item
, SUM(CASE WHEN [MONTH] = month(#d) THEN Sales END)
AS ''' + #month0 +
''' , SUM(CASE WHEN [MONTH] = month(#d) - 1 THEN Sales END)
AS ''' + #month1 +
''' , SUM(CASE WHEN [MONTH] = month(#d) THEN Sales END) -
SUM(CASE WHEN [MONTH] = month(#d) - 1 THEN Sales END)
AS ''' + #month2 +
''' FROM ABC GROUP BY Item';
EXEC sp_executesql #s, N'#d DATETIME', #ParamDate;