sql server - summing totals within a month/year - sql-server-2008-r2

I am doing a sql server report that shows running daily, monthly, and yearly totals at the bottom of the report.
I figured out how to do the daily report by taking the datediff of the "timestamp" field and a getdate() and returning rows that were = 0. That way I knew the difference in dates was 0 days and thus part of the daily total.
I am running into an issue as to a good way to do this with month and year. Here is the query I have for month calculation and it is giving me way more results than it should (I have another table which i'm using to double check my calculations. I should get about 300 as my total but the query below gives me about 7400 instead. Just a little off)
SELECT SUM(Rc0) AS Good,
SUM(Rc0 + Rc1 + Rc2 + Rc3 + Rc4 + Rc5 + Rc6 + Rc7 + Rc8 + Rc9 + Rc10 + Rc11 + Rc12 + Rc13 + Rc14 + Rc15 + Rc16 + Rc17 + Rc18 + Rc19 + Rc20 + Rc21 + Rc22 + Rc23
+ Rc24 + Rc25 + Rc26 + Rc27 + Rc28 + Rc29 + Rc30 + Rc31 + Rc32 + Rc33 + Rc34 + Rc35 + Rc36 + Rc37 + Rc38 + Rc39 + Rc40) AS Not_Good
FROM someTable WHERE (MONTH(timestamp) = MONTH(GETDATE())) and (YEAR(timestamp) = YEAR(GETDATE()))
edit: alternate form of query that is giving me same result
SELECT SUM(Rc0) AS Good,
SUM(Rc0 + Rc1 + Rc2 + Rc3 + Rc4 + Rc5 + Rc6 + Rc7 + Rc8 + Rc9 + Rc10 + Rc11 + Rc12 + Rc13 + Rc14 + Rc15 + Rc16 + Rc17 + Rc18 + Rc19 + Rc20 + Rc21 + Rc22 + Rc23
+ Rc24 + Rc25 + Rc26 + Rc27 + Rc28 + Rc29 + Rc30 + Rc31 + Rc32 + Rc33 + Rc34 + Rc35 + Rc36 + Rc37 + Rc38 + Rc39 + Rc40) AS Not_Good
FROM someTable
WHERE convert(varchar(7), timestamp, 126) = convert(varchar(7), getdate(), 126)

--As a generic sort of grouping including most spans.....
SELECT
'Year' = DATEPART(Yy, rowdate),
'Month' = DATEPART(Mm, rowdate),
'Week' = DATEPART(wk, rowdate),
'Total' = sum(yournumericfield)
FROM sometable
GROUP BY
DATEPART(Yy, rowdate),
DATEPART(Mm, rowdate),
DATEPART(wk, rowdate)
ORDER BY
DATEPART(Yy, rowdate),
DATEPART(Mm, rowdate),
DATEPART(wk, rowdate)

Related

Sum all odd digits in a number in PostgreSQL

Is there a built in function in PostgreSQL to sum the alternate digits starting from right hand side?
Input: 890400021003
Output:
3 + 0 + 2 + 0 + 4 + 9 = 18
0 + 1 + 0 + 0 + 0 + 8 = 9
Basically I want to print each alternate numbers and sum it up as above, please advice for any solution in Postgres
In Postres 9.4, you can do this easily with a string, using string_to_array() and unnest() with ordinality:
select ord % 2, sum(val::numeric)
from (select reverse('890400021003'::text) as x) x, lateral
unnest(string_to_array(x, NULL)) with ordinality u(val, ord)
group by ord % 2;
In 9.3 you can do this with a lateral join:
select i % 2, sum(substring(x.x, g.i, 1)::numeric)
from (select reverse('890400021003'::text) as x) x, lateral
generate_series(1, length(x.x)) g(i)
group by i % 2;
And you can apply the same idea using a subquery in earlier versions.

SQL Server 2008 R2 - convert all datetime parts (as ints) into a datetime column

I have a table that has the datetime pieces (year, month, day, hour, minute, second, millisecond) stored as integers. I'd like to concatenate them into a single datetime column.
I've tried various approaches but none work - there seems to be no simple way to put these items together?
You can convert each part to a varchar and concatenate them together in the format of an ISO datetime string. Then use Convert to convert the string to a DateTime.
Here is an example. You would need to replace each hard coded integer with the name of the column from your table.
SELECT CONVERT(DATETIME, CAST(2016 AS VARCHAR(4)) -- year
+ '-' + CAST('0' + CAST(8 AS VARCHAR(2)) AS VARCHAR(2)) -- month
+ '-' + RIGHT('0' + CAST(13 AS VARCHAR(2)), 2) -- day of month
+ 'T' + RIGHT('0' + CAST(16 AS VARCHAR(2)), 2) -- hours (I assume its military time (24 hours))
+ ':' + RIGHT('0' + CAST(32 AS VARCHAR(2)), 2) -- minutes
+ ':' + RIGHT('0' + CAST(07 AS VARCHAR(2)), 2) -- seconds
+ '.' + RIGHT('000' + CAST(64 AS VARCHAR(3)), 3)) AS MyDate -- milliseconds
FROM yourTable
Or with column names (assumed)
SELECT CONVERT(DATETIME, CAST(yt.Year AS VARCHAR(4)) -- year
+ '-' + CAST('0' + CAST(yt.Month AS VARCHAR(2)) AS VARCHAR(2)) -- month
+ '-' + RIGHT('0' + CAST(yt.Day AS VARCHAR(2)), 2) -- day of month
+ 'T' + RIGHT('0' + CAST(yt.Hours AS VARCHAR(2)), 2) -- hours (I assume its military time (24 hours))
+ ':' + RIGHT('0' + CAST(yt.Minutes AS VARCHAR(2)), 2) -- minutes
+ ':' + RIGHT('0' + CAST(yt.Seconds AS VARCHAR(2)), 2) -- seconds
+ '.' + RIGHT('000' + CAST(yt.Milliseconds AS VARCHAR(3)), 3)) AS MyDate -- milliseconds
FROM yourTable yt
One more note. Microsoft recommends that you use DateTime2 instead of DateTime to persist date time values starting with Sql Server 2008 (which you tagged in your question).
Prior to sql server 2012, you can use a series of nested DATEADD() functions to mimic DATETIMEFROMPARTS() function
Create and populate sample data (In your next question, please save us this step)
DECLARE #T as table
(
cYear int,
cMonth int,
cDay int,
cHour int,
cMinute int,
cSecond int,
cMillisecond int
)
INSERT INTO #T VALUES(2016, 6, 22, 16, 34, 25, 3)
The query:
SELECT *,
DATEADD(MILLISECOND, cMillisecond,
DATEADD(SECOND, cSecond,
DATEADD(MINUTE, cMinute,
DATEADD(HOUR, cHour,
DATEADD(DAY, cDay -1,
DATEADD(MONTH, cMonth - 1,
DATEADD(YEAR, cYear - 2000, '2000-01-01')
)
)
)
)
)
) As TheDate
FROM #T
Results:
cYear cMonth cDay cHour cMinute cSecond cMillisecond TheDate
----- ------ ---- ----- ------- ------- ------------- -----------------------
2016 6 22 16 34 25 3 2016-06-22 16:34:25.003
Note that the base date I'm using is January 1st 2000, therefor you need to subtract 2000 from the year, 1 from the month and 1 from the days.

Cumulative sum with conditions

I tried to get cumulative sums throught column week (and if is possible, then get result ordered by column Datum$ADTE) in my query:
select
A.Castka "Amount",
'Cashflow' as N,
A.Datum$DATE "Datum",
cast(A.Rok as varchar(4)) + '-' + cast(A.Tyden as varchar(4)) "Week"
from iGateCashflow A
where
1 = 1
and A.BusTransaction_ID = '1D00000101'
and A.Vyjasneno = 'A'
and cast(datepart(week ,convert(date, dbo.ib_DateToString(Napocteno$DATE, 'dd.mm.yyyy'), 104)) as varchar(4))
= 44
In where clause are conditions, whichs will be edited througt external form.
I would like to get result like this (better without Amount column)
week N Amount Result
44 Cashflow 150 150
45 Cashflow 200 350
46 Cashflow 300 650
47 Cashflow 350 1000
I tried something like this, but I can't achieve my expected result:
select
sum(y.Amount),
Y.N,
Y.Week
from (
select
A.Castka "Amount",
'Cashflow' as N,
A.Datum$DATE "Datum",
cast(A.Rok as varchar(4)) + '-' + cast(A.Tyden as varchar(4)) "Week"
from iGateCashflow A
where
1 = 1
and A.BusTransaction_ID = '1D00000101'
and A.Vyjasneno = 'A'
and cast(datepart(week ,convert(date, dbo.ib_DateToString(Napocteno$DATE, 'dd.mm.yyyy'), 104)) as varchar(4))
= 44
) X
join (
select
A.Castka "Amount",
'Cashflow' as N,
cast(A.Rok as varchar(4)) + '-' + cast(A.Tyden as varchar(4)) "Week"
from iGateCashflow A
where
1 = 1
and A.BusTransaction_ID = '1D00000101'
and A.Vyjasneno = 'A'
and cast(datepart(week ,convert(date, dbo.ib_DateToString(Napocteno$DATE, 'dd.mm.yyyy'), 104)) as varchar(4))
= 44
) Y on Y.Week <= X.Week
group by
Y.N,
Y.Week
order by
Y.Week
I think there's more your question than what you showed. But use this as an idea (you'll need to add in WHERE conditions, etc)
SELECT *,
SUM(Amount) OVER (ORDER BY [week])
FROM iGateCashflow
Better to use OVER Clause to get Sum partition by Week and order by Date, please refer to
Over Clause
Maybe try something like this
select
cast(A.Rok as varchar(4)) + '-' + cast(A.Tyden as varchar(4)) "Week",
sum(B.Castka) "Total amount"
from iGateCashflow A
inner join iGateCashflow B
on A.BusTransaction_ID = B.BusTransaction_ID
and A.Vyjasneno = B.Vyjasneno
and B.week <= A.week --> if week is a calculated field, include the calculation here for both 'week's
where
1 = 1
and A.BusTransaction_ID = '1D00000101'
and A.Vyjasneno = 'A'
and cast(datepart(week ,convert(date, dbo.ib_DateToString(Napocteno$DATE, 'dd.mm.yyyy'), 104)) as varchar(4))
= 44
group by cast(A.Rok as varchar(4)) + '-' + cast(A.Tyden as varchar(4)) "Week"

Loosing the battle - Datediff working but I want to apply a condition

I know I'm gonna 'kick myself' when I see the answer but right now I can't see it.
SELECT [faxdate]
,DATEDIFF(day,
CAST(SUBSTRING(RPT.FaxDate, 1, 4) + '-' + SUBSTRING(RPT.FaxDate, 5, 2) + '-' + SUBSTRING(RPT.FaxDate, 7, 2) AS DATE), getdate()) AS vDiff
faxdate vDiff 20130704 62 20130705 61
20130705 61 20130708 58
Works great, but I want to be able to test the number of days Eg. records over 60 days.
When I add this :
WHERE (DATEDIFF(day,
CAST(SUBSTRING(RPT.FaxDate, 1, 4) + '-' + SUBSTRING(RPT.FaxDate, 5, 2) + '-' + SUBSTRING(RPT.FaxDate, 7, 2) AS DATE), getdate()) >60)
I get: Conversion failed when converting date and/or time from character string.
I have also tried this sql as a derived table and then tested vDiff ....i'm obviously not doing it right
any help would be appreciated
ttfn
Martyn
(Cornwall England and it's not raining .. result !)
Try
SELECT [faxdate],DAY(DATEDIFF(CAST(SUBSTRING(RPT.FaxDate, 1, 4) + '-' +
SUBSTRING(RPT.FaxDate, 5, 2) + '-' + SUBSTRING(RPT.FaxDate, 7, 2) AS DATE),
getdate())) AS vDiff
instead of using where, use having like below
HAVING vDiff > 60

Currency Problem With Crystal Report

Hi i have developed crystal report in asp.net web site
i want to set currency format like 1,20,000 (Indian Currency) but right now currency take My Server Hosted Currency Format and i was working for indian company so i there any format to convert currency in indian format for crystal report//
-- You can use below said code to your report part;
CStr({#FieldName}, "##,##,##,###.##")
And you are working for Indian Company, you will needed in words also. To write in words, use below said code;
numbervar RmVal:=0;
numbervar Amt:=0;
numbervar pAmt:=0;
stringvar InWords :="Rupees ";
Amt := {#FieldName} ;
if Amt > 10000000 then RmVal := truncate(Amt/10000000);
if Amt = 10000000 then RmVal := 1;
if RmVal = 1 then
InWords := InWords + " " + towords(RmVal,0) + " crore"
else
if RmVal > 1 then InWords := InWords + " " + towords(RmVal,0) + " crores";
Amt := Amt - Rmval * 10000000;
if Amt > 100000 then RmVal := truncate(Amt/100000);
if Amt = 100000 then RmVal := 1;
if RmVal = 1 then
InWords := InWords + " " + towords(RmVal,0) + " lakhs"
Else
If RmVal > 1 then InWords := InWords + " " + ToWords(RmVal,0) + " Lakhs";
Amt := Amt - Rmval * 100000;
if Amt > 0 then InWords := InWords + " " + towords(truncate(Amt),0);
pAmt := (Amt - truncate(Amt)) * 100;
if pAmt > 0 then
InWords := InWords + " and " + towords(pAmt,0) + " paisa only"
else
InWords := InWords + " only";
ProperCase(InWords)