How to write select query for this? - sql

I have column COMPONENT_AMOUNT(money) ,MONTH_FOR(int), YEAR_FOR(int) and COMPONENT_TYPE(int). I want to find the sum of amount according to condition. I have written my query like this but it solve my purpose.
My purpose is that if one select Nov-2010 then it will sum the amount up to this selected month including all the month of 2009.
My query is given below ,please modify it:
SELECT SUM(Convert(Numeric(7,2), Round([COMPONENT_AMOUNT],2,1)))
FROM [TEAM_FUNDS_DETAILS]
WHERE YEAR_FOR <= 1 AND MONTH_FOR <= 1 AND [COMPONENT_TYPE] = 1

If You need only one result per query I think that this is code
declare #year int
declare #month int
set #year = 2010 --desire year
set #month = 8 --desire month
select sum(COMPONENT_AMOUNT)
from [TEAM_FUNDS_DETAILS]
WHERE
[COMPONENT_TYPE] = 1
and (
YEAR_FOR < #year
or (year_for=#year and month_for<=#month)
)

Related

Count Business Days Between Start Date and Current Date

I am trying to use a predefined INT value giving 1 or 0 as being a business day or not to count the rolling business days sequence. I have tried a lot of different code and checked out different posts here but none are specific enough to work with mine.
The predefined INT value is "business_day_flag_int". This comes from converting the calculations giving me "day_business_day_flag" which is a bit value. Currently Saturday/Sunday and Banking holidays trigger a 0 for "day_business_day_flag" and Mon-Fri being non holiday give it a 1 value.
How can I get this to work in an Update table that I can add to the rest of my table generation file? If more information is needed let me know.
I've tried a bunch of different alterations and variations of what I have here. If I remove date values it gives me an int value for all rows in the column of roughly 12600 business days. If I use with the date range it gives me
DECLARE #StartDate DATETIME = '01/01/2000' --Starting value of Date Range
DECLARE #EndDate DATETIME = '01/01/2050' --End Value of Date Range
DECLARE
#DayOfWeekInMonth INT,
#DayOfWeekInYear INT,
#DayOfQuarter INT,
#WeekOfMonth INT,
#CurrentYear INT,
#CurrentMonth INT,
#CurrentQuarter INT
DECLARE #CurrentDate AS DATETIME = #startDate
SET #CurrentMonth = DATEPART(MM, #CurrentDate)
SET #CurrentYear = DATEPART(YY, #CurrentDate)
SET #CurrentQuarter = DATEPART(QQ, #CurrentDate)
UPDATE [EDW_MDM].[dbo].[CALENDAR_DIM] SET
business_day_flag_int = Convert(INT, day_business_day_flag)
UPDATE [EDW_MDM].[dbo].[CALENDAR_DIM] SET
rolling_business_day_sequence = (SELECT count(business_day_flag_int) FROM [EDW_MDM].[dbo].[CALENDAR_DIM]
WHERE business_day_flag_int = 1 and
day_date between #StartDate and #CurrentDate)
I want the column "rolling_business_day_sequence" to count sequentially business days past. For example row 1 = 1, row 2 = 2, etc. Until the end of my calendar.
Update 1: Edited the line of code to
UPDATE [EDW_MDM].[dbo].[FCFCU_CALENDAR_DIM] SET
rolling_business_day_sequence = datediff(day,#StartDate,day_date) WHERE day_business_day_flag = 1
This gave me counting days and set rolling_business_day_sequence row values to null where not having day_busienss_day_flag = 1 and still counting them instead of not counting them. How can I make it not add the day?
Consider a window function sum on your WHERE conditions to cumulatively count all instances of business_day_flag_int = 1 within specified date range. However, to use window functions in UPDATE, a CTE or subquery is required.
WITH CTE AS
(
SELECT ID, SUM(CASE WHEN day_date BETWEEN #StartDate AND #CurrentDate
AND business_day_flag_int = 1
THEN 1
ELSE 0
END) OVER (ORDER BY day_date) AS running_sequence
FROM [EDW_MDM].[dbo].[CALENDAR_DIM]
)
UPDATE t
FROM [EDW_MDM].[dbo].[CALENDAR_DIM] t
JOIN CTE ON t.ID = CTE.ID
SET t.rolling_business_day_sequence = CTE.running_sequence

Stored Procedure with variable condition and error message

In my procedure, the variable #year should take two forms: 1: If #Year=1, Select all years. 2: #Year= the entered year.
Here's a sample of my code:
CREATE PROC spProcName (#Year)
AS
BEGIN
SELECT Year AS [YEAR], Item AS [ITEM]
FROM Sales
WHERE Year = #YEAR
I can make it work for #Year = 2013, but I don't know how to incorporate the #Year =1 to select all years. I'm guessing it would be with CASE.
I also have many other similar conditions with other variables, so I can't just create an IF statement.
Where Year = Case when #Year = 1 Then Year else #Year end
Alternative to John's answer, but quasi-equivalent:
WHERE (#year=1 OR year=#year)
In this case it is best to add OPTION(RECOMPILE) at the end of the query, otherwise the query won't be able to choose an index if it exists on the year column.
--If you give value 1 it will select all the records from table year wise else if you give year like 2016 it fetches all the record based on given year
ALTER PROC spProcName (#Year int)
AS
BEGIN
IF #Year = 1
BEGIN
SELECT
[Year] AS [YEAR],
Item AS [ITEM]
FROM Sales
ORDER BY [Year]
END
ELSE
SELECT
[Year] AS [YEAR],
Item AS [ITEM]
FROM Sales
WHERE DATEPART(YEAR, CAST([Year] AS date)) = #year
END

capture records 6 months prior to current month

I'm working off a query where the dates are declared as integers, it's meant for a revenue report that captures the last 6 months back from x month/year. So user inputs say 10 (oct), 2014. What I want is for it to go 6 months back (10-6) and show all of the records in this range. I would think it would be something like csr.csrdatepulled >= dateadd(mm,-6.#month) -- however I don't think this works since they're integers. Right now it will just capture that month, but not the in-between. Is there a way to accomplish this with month and year declared as ints? Thanks in advance, this is a slimmed down query-
declare
#Month int,
#Year int
Set #Month = 10
Set #Year = 2014
select csr.csrdatepulled
from CustomServicesForRevenue csr
where DatePart(MM,csr.CsrDatePulled) = #Month and DatePart(yyyy,csr.CsrDatePulled) = #Year
order by csr.CsrDAtepulled desc
Construct a complete date (the 1st of the month & year) deducting 6 months and fetch rows that are >= to it
WHERE
csr.CsrDatePulled >= DATEADD(MONTH, #MONTH - 1 - 6, DATEADD(YEAR, #YEAR - 1900, 0))

How to get database values by week

I just want to ask how can I achieve getting the records in a database by week in a month? using sql
What I really mean is when I input 1 it will get the records in 1st week of a month
I've done a lot of research today but it seems I can't find a good solution
Heres the code:
DECLARE #MONTH int
DECLARE #YEAR int
DECLARE #WEEK int
SET #MONTH = 9
SET #YEAR = 2013
SET #WEEK = 1
SELECT RH.RepairOrderNumber FROM dbo.RepairOrderHeader RH
WHERE MONTH(RH.DateReleased) = #MONTH AND YEAR(RH.DateReleased) = #YEAR AND WEEK(RH.DateReleased) = #WEEK
I just want to fetched the records according to month,year, and by week is there any way and precise code on how to do this?
DATEPART(WEEK,) gives you number of a week in an YEAR so you just need to calculate number of week in the month calculating difference between current date week number and the week number of the first day of the month:
WHERE MONTH(RH.DateReleased) = #MONTH
AND YEAR(RH.DateReleased) = #YEAR
AND DATEPART(WEEK,RH.DateReleased)
-DATEPART(WEEK,DATEADD(DAY,-DAY(RH.DateReleased)+1,RH.DateReleased))+1
= #WEEK
WEEK returns the week of the year, starting on a constant day of the week (i.e. each Sunday). You seem to want the week of the month, which I guess would always start on the 1st of each month.
so:
SELECT RH.RepairOrderNumber FROM dbo.RepairOrderHeader RH
WHERE MONTH(RH.DateReleased) = #MONTH AND
YEAR(RH.DateReleased) = #YEAR AND
DAY(RH.DateReleased) / 7 + 1 = #WEEK
Where possible avoid using functions on columns in the WHERE clause. You immediately lose the ability to take advantage of indices on these columns. The below solution gives the same results as the select answer, but performs much better:
DECLARE #MONTH INT = 9
DECLARE #YEAR INT = 2013
DECLARE #WEEK INT = 2
--1ST OF THE MONTH DECLARED
DECLARE #Date DATE = CAST(CAST(#Year AS VARCHAR(4)) +
RIGHT('0' + CAST(#Month AS VARCHAR(2)), 2) + '01' AS DATE)
SET #Date = DATEADD(WEEK, #Week - 1, DATEADD(DAY, 1 - DATEPART(WEEKDAY, #Date), #Date));
SELECT RH.RepairOrderNumber
FROM dbo.RepairOrderHeader RH
WHERE RH.DateReleased >= #Date
AND RH.DateReleased < DATEADD(WEEK, 1, #Date);
All this does is get the first of the month in question, then find the first day of the week that the first of the month falls in. Then adds the declared number of weeks to this date.
With an example table with 6 years of data in and 10 rows for each day (20,480 records, so not a lot) and an index on your date column the execution plans of this and the accepted answer are as follows (Accepted on top, using dates on the bottom):
Testing DDL and queries on SQL-Fiddle
This shows that when you use WEEK(DateColumn) = #Week that the index is not used at all, and the query cost is much higher. Depending on the distribution of data in your table this could make a massive difference, even in the small set of data in my example it is 800% more efficient.
I consider '2013-08-26' - '2013-09-01' the first week in september
DECLARE #MONTH int = 9
DECLARE #YEAR int = 2013
DECLARE #WEEK int = 1
DECLARE #from date= dateadd(day, datediff(day, -(#WEEK - 1)*7,
(dateadd(month, (#year-1900) * 12 + #month - 1 , 0)))/7*7 , 0)
SELECT RH.RepairOrderNumber
FROM dbo.RepairOrderHeader RH
WHERE RH.DateReleased >= #from
and RH.DateReleased < dateadd(week, 1, #from)

How to work out the month end date from the month - SQL

I've got a column that returns integers for months i.e. 7 for July. What I want to do is take this 7 and return the month end i.e. 31-july-2012, is there a function that allows me to do this in SQL?
Thanks
How about something like this:
DECLARE #Month int
DECLARE #Year int
set #Month = 7
set #Year = datepart(year,getdate())
select DATEADD(day,-1,DATEADD(month,#Month,DATEADD(year,#Year-1900,0)))
Results:
2012-07-31 00:00:00.000
Have a look at this;
http://blog.sqlauthority.com/2007/08/18/sql-server-find-last-day-of-any-month-current-previous-next/
this is the bit you're interested in;
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))