Friday, January 15, 2010
Import from Excel Sheet into Sql Table with filtering
Monday, June 15, 2009
SQL FUNCTION ExtractNumbers
Tuesday, February 3, 2009
Convert an Integer/Number into words
=============================================
Description: Converts an integer into words,
viz., --
master.dbo.fnSpellInteger(10129) ==> "Ten Thousand One Hundred Twenty-Nine"
=============================================
USE MASTER
IF OBJECT_ID('dbo.fnSpellInteger') IS NOT NULL DROP FUNCTION fnSpellIntegerGO
CREATE FUNCTION dbo.fnSpellInteger ( @number int )RETURNS VARCHAR(100)ASBEGIN -- For debugging outside of the UDF: DECLARE @debug bit SET @debug = 0
DECLARE @result VARCHAR(100), @word VARCHAR(100), @group VARCHAR(100) DECLARE @i int, @j int, @m int, @digit VARCHAR(2), @cn VARCHAR(20)
IF @number = 0 RETURN 'Zero'
SELECT @result = '', @word = '', @group = '' SET @cn = @number SET @cn = REPLACE(@cn,',','') SET @m = LEN(@cn) % 3 IF @m > 0 SET @cn = REPLICATE('0',3-@m) + @cn -- Left pad with zeroes to a multiple of 3
SET @i = 1 SET @j = LEN(@cn)-@i+1 SET @m = @i % 3 WHILE @i <= LEN(@cn) BEGIN -- @i is 1 origin index into numeric string while @m = @i modulo 3 -- If the middle digit of each group of 3 is a '1' then this is a 'Ten' or a '...teen' IF @m = 2 AND SUBSTRING(@cn,@i,1) = '1' BEGIN SET @digit = SUBSTRING(@cn,@i,2) -- Skip rightmost digit of 3 if processing teens SET @i = @i + 1 END ELSE SET @digit = SUBSTRING(@cn,@i,1)
SET @word = CASE WHEN @m = 0 THEN -- Rightmost digit of group of 3 CASE @digit WHEN '0' THEN '' WHEN '1' THEN 'One' WHEN '2' THEN 'Two' WHEN '3' THEN 'Three' WHEN '4' THEN 'Four' WHEN '5' THEN 'Five' WHEN '6' THEN 'Six' WHEN '7' THEN 'Seven' WHEN '8' THEN 'Eight' WHEN '9' THEN 'Nine' END + CASE WHEN (@group <> '' OR @digit <> '0') AND (@j+2) / 3 = 2 THEN ' Thousand' WHEN (@group <> '' OR @digit <> '0') AND (@j+2) / 3 = 3 THEN ' Million' WHEN (@group <> '' OR @digit <> '0') AND (@j+2) / 3 = 4 THEN ' Billion' ELSE '' END WHEN LEN(@digit) = 2 THEN -- Special case when middle digit is a '1' CASE @digit WHEN '10' THEN 'Ten' WHEN '11' THEN 'Eleven' WHEN '12' THEN 'Twelve' WHEN '13' THEN 'Thirteen' WHEN '14' THEN 'Fourteen' WHEN '15' THEN 'Fifteen' WHEN '16' THEN 'Sixteen' WHEN '17' THEN 'Seventeen' WHEN '18' THEN 'Eighteen' WHEN '19' THEN 'Nineteen' END + CASE WHEN (@group <> '' OR @digit <> '00') AND (@j+2) / 3 = 2 THEN ' Thousand' WHEN (@group <> '' OR @digit <> '00') AND (@j+2) / 3 = 3 THEN ' Million' WHEN (@group <> '' OR @digit <> '00') AND (@j+2) / 3 = 4 THEN ' Billion' ELSE '' END WHEN @m = 2 THEN -- Middle digit of group of 3 CASE @digit WHEN '2' THEN 'Twenty' WHEN '3' THEN 'Thirty' WHEN '4' THEN 'Forty' WHEN '5' THEN 'Fifty' WHEN '6' THEN 'Sixty' WHEN '7' THEN 'Seventy' WHEN '8' THEN 'Eighty' WHEN '9' THEN 'Ninety' ELSE '' END WHEN @m = 1 THEN -- Leftmost digit of group of 3 CASE @digit WHEN '0' THEN '' WHEN '1' THEN 'One' WHEN '2' THEN 'Two' WHEN '3' THEN 'Three' WHEN '4' THEN 'Four' WHEN '5' THEN 'Five' WHEN '6' THEN 'Six' WHEN '7' THEN 'Seven' WHEN '8' THEN 'Eight' WHEN '9' THEN 'Nine' END + CASE WHEN @digit <> '0' THEN ' Hundred' ELSE '' END END
SET @group = @group + RTRIM(@word) -- Group value
IF @word <> '' BEGIN DECLARE @prefix VARCHAR(20) IF CHARINDEX(' ',@word) > 0 SET @prefix = LEFT(@word,CHARINDEX(' ',@word)) ELSE SET @prefix = @word IF RIGHT(@result,2) = 'ty' AND @prefix IN ('One','Two','Three','Four','Five','Six','Seven','Eight','Nine') SET @result = @result + '-' + LTRIM(@word) ELSE SET @result = @result + ' ' + LTRIM(@word) END -- The following needs to be outside of a UDF to work: --IF @debug = 1 SELECT @cn as 'Number', @i as '@i', @j as '@j', @m as '@m', @digit as '@digit', CAST(replace(@group,' ','`') AS CHAR(30)) as '@group', @word as '@word', @result as '@result' SET @i = @i + 1 SET @j = LEN(@cn)-@i+1 SET @m = @i % 3 IF @m = 1 SET @group = '' -- Clear group value when starting a new one
END
IF @result = '' SET @result = '0' RETURN LTRIM(@Result)
ENDGO
SET NOCOUNT ON
Description: Converts a string numeric expression into words,
viz., --
master.dbo.fnSpellNumber('15.99') ==> "Fifteen and Ninety-Nine Hundredths"-- Notes: Uses fnSpellInteger to convert an integer into words-- Example: fnSpellNumber can be used to generate pseudo-random test character data/* set nocount on declare @rand int, @i int set @rand = rand(131)*100 set @i = 0
while @i < 5 begin set @i = @i + 1 select 'insert(id,number,words) values(' + cast(@i as varchar(5)) + ',' + cast(@rand as varchar(5)) + ',''' + master.dbo.fnspellnumber(@rand) + ''')' set @rand = rand()*100 end*/-- =============================================
USE MASTER
IF OBJECT_ID('master.dbo.fnSpellNumber') IS NOT NULL DROP FUNCTION fnSpellNumberGO
CREATE FUNCTION dbo.fnSpellNumber ( @number varchar(20) )RETURNS VARCHAR(200)AS--For debugging: declare @number varchar(20) set @number = '192.1'BEGIN -- This is for use outside of a function: DECLARE @debug bit SET @debug = 0
DECLARE @result varchar(200), @word varchar(100) DECLARE @i int, @intpart varchar(20), @decpart varchar(20) SET @word = LTRIM(RTRIM(@number)) -- Check for a bad number, e.g., one with embedded spaces IF ISNUMERIC(@word) = 0 RETURN '<<>>'
SET @i = CHARINDEX('.', @word) -- Remove trailing zeroes for any decimal portion IF @i > 0 -- Number contains a decimal point BEGIN WHILE RIGHT(@word,1) = '0' SET @word = LEFT(@word,LEN(@word)-1) IF @word = '' SET @word = '0' END -- Insert a decimal point at the end if none was specified IF @i = 0 -- No decimal point BEGIN SET @word = @number + '.' SET @i = CHARINDEX('.', @word) END
SET @intpart = LEFT(@word,@i-1) -- Extract the integer part of the number if any IF LEN(@intpart) > 0 SET @result = master.dbo.fnSpellInteger(CAST(@intpart AS int)) ELSE SET @result = ''
-- Extract the decimal portion of the number SET @decpart = RIGHT(@word,LEN(@word)-@i) -- @i is position of decimal point
IF LEN(@decpart) > 0 BEGIN IF @result = 'Zero' SET @result = '' ELSE IF @result <> '' SET @result = @result + ' and '
SET @result = @result + master.dbo.fnSpellInteger(@decpart) + CASE LEN(@decpart) WHEN 0 THEN '' WHEN 1 THEN ' Tenths' WHEN 2 THEN ' Hundredths' WHEN 3 THEN ' One-Thousandths' WHEN 4 THEN ' Ten-Thousandths' WHEN 5 THEN ' One-Hundred-Thousandths' WHEN 6 THEN ' One-Millionths' WHEN 7 THEN ' Ten-Millionths' WHEN 8 THEN ' One-Hundred-Millionths' WHEN 9 THEN ' One-Billionths' END -- Check for a valid plural IF @decpart = 1 SET @result = LEFT(@result, LEN(@result)-1) -- Remove last "s" for just 1 END -- This is for use outside of a function: if @debug = 1 select @word as '@word', @i as '@i', @intpart as '@intpart', @decpart as '@decpart', @result as '@result' RETURN @result
ENDGO
Tuesday, January 27, 2009
How to increase the size of a database (Enterprise Manager)
How to Get Available space on Database
Tuesday, January 13, 2009
Finding the Last Occurrence of a Pattern in a String
When dealing with string data, one of the most useful Transact-SQL functions you can have in your toolbox is PATINDEX. Aside from it’s many creative uses (and there are quite a few), it allows you to search for an expression (including wildcard operators) within any valid SQL Server character type. It returns the position of the first occurrence of the pattern within the string, and returns zero (0) if the pattern is not found. As always, an example is worth 1000 bon mots:
SELECT PATINDEX('%c%', 'abcdefgabcdefga')
The above snippet returns 3, because the first instance of “c” within “abcdefgabcdefga” is at the third character.
On occasion, you may be required to find the last occurrence of the pattern rather than the first. This usually happens when you’re dealing with data from external systems, or when you’ve inherited custody of an inappropriately denormalized system (one where more than one “logical” data item has been stored in a single, concatenated field). I have the same requirement for my “mad science” series, so I developed a function to take care of it. Here it is:
CREATE FUNCTION dbo.REVERSEPATINDEX(@StringToFind nvarchar(max),
@StringToSearch nvarchar(max))
RETURNS bigint
AS
BEGIN
--LastIndex will store the "previous" index of the pattern
--while we search for the "next" index inside our string.
DECLARE @LastIndex bigint, @NextIndex bigint
--We will chop off the "searched" portion of our string
--After each search iteration
DECLARE @CurrentStringToSearch nvarchar(max)
--Assign the value of the input parameter to @CurrentStringToSearch
SET @CurrentStringToSearch = @StringToSearch
--Grab the first occurrence, if it exists, using PATINDEX
SET @NextIndex = PATINDEX(@StringToFind, @CurrentStringToSearch)
--If we've found the pattern within the string, continue and find
--subsequent occurrences until there are no more to find.
WHILE @NextIndex > 0
BEGIN
--Add @NextIndex to @LastIndex, effectively storing within
--@LastIndex the index of the occurence that we have just found,
--based upon the original (non-truncated) string.
SET @LastIndex = COALESCE(@LastIndex,0) + @NextIndex
--Truncate @CurrentStringToSearch, removing the portion of the
--string that we have already searched.
SET @CurrentStringToSearch
= RIGHT(@CurrentStringToSearch, LEN(@CurrentStringToSearch) - @NextIndex)
--Find the NEXT occurence of the pattern in the remaining portion of
--the string to search.
SET @NextIndex = PATINDEX(@StringToFind, @CurrentStringToSearch)
END
--We will COALESCE @LastIndex and @NextIndex; @LastIndex will be NULL
--if the pattern does not exist in the string (as the loop above will
--never have been executed).
RETURN COALESCE(@LastIndex, @NextIndex)
END
GO
And to test:
SELECT dbo.REVERSEPATINDEX('%c%', 'abcdefgabcdefga')
Returns 10 – the correct answer, given that the last occurrence of “c” in “abcdefgabcdefga” is at the tenth character.
Monday, January 12, 2009
How do you find out all the IDENTITY columns of all the tables in a given database?
Differences Between SQL Server 2000 and 2005
Feature | SQL Server 2000 | SQL Server 2005 |
Server Programming Extensions | Limited to extended stored procedures, which are difficult to write and can impact the server stability. | The incorporation of the CLR into the relational engine allows managed code written in .NET languages to run. Different levels of security can protect the server from poorly written code. |
T-SQL Error Handling | Limited to checking @@error, no much flexibility. | Addition of TRY/CATCH allows more mature error handling. More error_xx functions can gather additional information about errors. |
T-SQL Language | SQL Language enhanced from previous versions providing strong data manipulation capabilities. | All the power of SQL Server 2000 with the addition of CTEs for complex, recursive problems, enhanced TOP capabilities, PIVOT/APPLY/Ranking functions, and ROW_NUMBER |
Auditing | Limited support using triggers to audit changes. | Robust event handling with EVENT NOTIFICATIONS, the OUTPUT clauses, and DDL triggers. |
Large Data Types | Limited to 8k for normal data without moving to TEXT datatypes. TEXT is hard to work with in programming environments. | Includes the new varchar(max) types that can store up to 2GB of data in a single column/row. |
XML | Limited to transforming relational data into XML with SELECT statements, and some simple query work with transformed documents. | Native XML datatype, support for schemas and full XPATH/XQUERY querying of data. |
ADO.NET | v1.1 of ADO.NET included enhancements for client development. | v2 has more features, including automatic failover for database mirroring, support for multiple active result sets (MARS), tracing of calls, statistics, new isolation levels and more. |
Messaging | No messaging built into SQL Server. | Includes Service Broker, a full-featured asynchronous messaging system that has evolved from Microsoft Message Queue (MSMQ), which is integrated into Windows. |
Reporting Services | An extremely powerful reporting environment, but a 1.0 product. | Numerous enhancements, run-time sorting, direct printing, viewer controls and an enhanced developer experience. |
ETL | DTS is a very easy to use and intuitive tool. Limited capabilities for sources and transformations. Some constructs, such as loops, were very difficult to implement. | Integration Services is a true programming environment allowing almost any source of data to be used and many more types of transformations to occur. Very complex environment that is difficult for non-DBAs to use. Requires programming skills. |
Full-Text Search | Workable solution, but limited in its capabilities. Cumbersome to work with in many situations. | More open architecture, allowing integration and plug-ins of third party extensions. Much more flexible in search capabilities. |
Sql Split function
CREATE FUNCTION Split
(
@StringToSplit varchar(2048),
@Separator varchar(128)
)
RETURNS TABLE AS RETURN
WITH CTE AS
(
SELECT 0 StartIndex, 1 EndIndex
UNION ALL
SELECT EndIndex, CHARINDEX(@Separator, @StringToSplit, EndIndex) + LEN(@Separator)
FROM CTE
WHERE EndIndex > StartIndex
)
SELECT
SUBSTRING(@StringToSplit
, StartIndex
, CASE WHEN EndIndex > LEN(@Separator)
THEN EndIndex-StartIndex-LEN(@Separator)
ELSE LEN(@StringToSplit) - StartIndex + 1
END) String
,StartIndex StartIndex
FROM CTE
WHERE StartIndex > 0
Import Data from Excel File to sql datatable
Import Data from Excel File to sql datatableTo Export Data Form an Excel file, there is one drawback lying behind them. The Sheet1 from the query actually is the name of the spreadsheet in your excel file. What if there is no Sheet1 inside the excel file? What if you don’t even know the sheet name?
Yes. I found this error when I tried to upload an excel file with different sheet name. And here is the solution for that.
To get the sheet name in your excel file, firstly, Microsoft DAO 3.5 Library is needed. Go to Project -> Reference -> Add Reference, select Microsoft DOA 3.5 Library from the list and add to your project. Here is the example code of how to get the first sheet in the excel file.
Dim strConn As String
Dim da As OleDbDataAdapter
Dim ds As New DataSet
Dim dao_dbE As dao.DBEngine
Dim dao_DB As DAO.Database
Dim strSheet As String
dao_dbE = New dao.DBEngine
dao_DB = dao_dbE.OpenDatabase("C:\test.xls", False, True, "Excel 8.0;")
strSheet = dao_DB.TableDefs(0).Name
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\test.xls;Extended Properties=""Excel 8.0;"""
da = New OleDbDataAdapter("SELECT * FROM [" & _
strSheet & "]", strConn)
da.TableMappings.Add("Table", "Excel")
da.Fill(ds)
Import Data from Excel File to sql datatable
Import Data from Excel File to sql datatable
As I has stated in my previous post regarding to Export Data Form an Excel file, there is one drawback lying behind them. The Sheet1 from the query actually is the name of the spreadsheet in your excel file. What if there is no Sheet1 inside the excel file? What if you don’t even know the sheet name?
Yes. I found this error when I tried to upload an excel file with different sheet name. And here is the solution for that.
To get the sheet name in your excel file, firstly, Microsoft DAO 3.5 Library is needed. Go to Project -> Reference -> Add Reference, select Microsoft DOA 3.5 Library from the list and add to your project. Here is the example code of how to get the first sheet in the excel file.
Dim strConn As String
Dim da As OleDbDataAdapter
Dim ds As New DataSet
Dim dao_dbE As dao.DBEngine
Dim dao_DB As DAO.Database
Dim strSheet As String
dao_dbE = New dao.DBEngine
dao_DB = dao_dbE.OpenDatabase("C:\test.xls", False, True, "Excel 8.0;")
strSheet = dao_DB.TableDefs(0).Name
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\test.xls;Extended Properties=""Excel 8.0;"""
da = New OleDbDataAdapter("SELECT * FROM [" & _
strSheet & "]", strConn)
da.TableMappings.Add("Table", "Excel")
da.Fill(ds)
Export Datatable to Excel
Export Datatable to Excel(Not HTML Tables)
Recently I working with export data to an excel file, but had faced a lot of problems. The main problem of it: The exported file is saved as HTML tables with XLS extension, not the actual XLS format. In this way, I can’t re-import the data using the OleDbConnection.
I have been searching around the net, but no exact solution that suit my situation. Finally, I had found another way to export data into the actual XLS format, by using Excel.Application.
First thing that you need to do is to add Excel dll (Microsoft Excel 11.0 Object Library) as a reference.
Here are the codes.
Private Function ExportToExcel(ByVal dt As System.Data.DataTable)
Dim xlsApp As New Excel.Application
Dim xlsWorkbook As Excel.Workbook
Dim xlsWorksheets As Excel.Worksheets
Dim xlsWorksheet As Excel.Worksheet
Dim strhdr As String
Dim row As Integer
Dim drow As DataRow
Dim strFile As String = "test.xls"
Dim filename As String = Server.MapPath("Doc") & "\" & strFile
If dt.Rows.Count > 0 Then
'Create new workbook
xlsWorkbook =
xlsApp.Workbooks.Add
'Get the first worksheet
xlsWorksheet = CType(xlsWorkbook.Worksheets(1), Excel.Worksheet)
'Activate current worksheet
xlsWorksheet.Activate()
'Set header row to row 1
row = 1
'Add table headers to worksheet
xlsWorksheet.Cells(row,1).Value = "NAME"
xlsWorksheet.Cells(row, 2).Value = "JOB POSITION"
xlsWorksheet.Cells(row, 3).Value = "ORIGIN"
'Format header row (bold, extra row height, autofit
width)
With xlsWorksheet.Range("A" & row, "C" & row)
.Font.Bold = True
.Rows(row).RowHeight = 1.5 * xlsWorksheet.StandardHeight
.EntireRow.AutoFit()
End With
'Freeze the column headers
With xlsWorksheet.Range("A" & row + 1, "C" & row + 1).Select
xlsApp.ActiveWindow.FreezePanes = True
End With
'Write data to Excel worksheet
For Each drow In dt.Rows
row += 1
If Not IsDBNull(dr.Item("NAME")) Then xlsWorksheet.Cells(row, 1).Value = dr.Item("NAME")
If Not IsDBNull(dr.Item("JOB POSITION")) Then xlsWorksheet.Cells(row, 2).Value = dr.Item("JOB POSITION")
If Not IsDBNull(dr.Item("ORIGIN")) Then xlsWorksheet.Cells(row, 3).Value =
dr.Item("ORIGIN")
Next
'Format data rows (align to top, autofit width and height)
With xlsWorksheet.Range("A2", "C" & row)
.VerticalAlignment = CType(XlVAlign.xlVAlignCenter, Excel.XlVAlign)
.HorizontalAlignment = CType(XlHAlign.xlHAlignLeft, Excel.XlHAlign)
.EntireColumn.AutoFit()
.EntireRow.AutoFit()
End With
'Make excel workbook visible to user after all data has been added to worksheet
xlsApp.DisplayAlerts = False
xlsWorkbook.Close(True, filename)
'Export data to client machine
strhdr = "attachment;filename=" & strFile
With Response
.Clear()
.ContentType = "application/vnd.ms-excel"
.ContentEncoding = System.Text.Encoding.Default
.AppendHeader("Content-Disposition", strhdr)
.WriteFile(filename)
.Flush()
.Clear()
.Close()
End With
End If
End Function
Wednesday, December 3, 2008
SQL2005 String functions
Tuesday, November 18, 2008
sql2000 delete rows having duplicate (identical) records
Monday, November 3, 2008
Export SQL table to excel
Dim wBook As Excel.Workbook
Dim wSheet As Excel.Worksheet
wBook = excel.Workbooks.Add()
wSheet = wBook.ActiveSheet()
Dim dt As DataGridView = TblJobMethodsDataGridView.DataSource.Tables(0)
Dim dc As System.Data.DataColumn
Dim dr As System.Data.DataRow
Dim colIndex As Integer = 0
Dim rowIndex As Integer = 0
For Each dc In dt.Columns
colIndex = colIndex + 1
excel.Cells(1, colIndex) = dc.ColumnName
Next
For Each dr In dt.Rows
rowIndex = rowIndex + 1
colIndex = 0
For Each dc In dt.Columns
colIndex = colIndex + 1
excel.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName)
Next
Next
wSheet.Columns.AutoFit()
Dim strFileName As String = "D:\ss.xls"
Dim blnFileOpen As Boolean = False
Try
Dim fileTemp As System.IO.FileStream = System.IO.File.OpenWrite(strFileName)
fileTemp.Close()
Catch ex As Exception
blnFileOpen = False
End Try
If System.IO.File.Exists(strFileName) Then
System.IO.File.Delete(strFileName)
End If
wBook.SaveAs(strFileName)
excel.Workbooks.Open(strFileName)
excel.Visible = True
Sunday, July 20, 2008
SQL Server: Calculating Running Totals, Subtotals and Grand Total Without a Cursor
- Sample Data Used by Examples
create table Orders
(
OrderID int identity,
OrderAmt Decimal(8,2),
OrderDate SmallDatetime
)
Select command gives the following output:
OrderID OrderAmt OrderDate
----------- ---------- --------------------
1 10.50 2003-10-11 08:00:00
2 11.50 2003-10-11 10:00:00
3 1.25 2003-10-11 12:00:00
4 100.57 2003-10-12 09:00:00
5 19.99 2003-10-12 11:00:00
6 47.14 2003-10-13 10:00:00
7 10.08 2003-10-13 12:00:00
8 7.50 2003-10-13 19:00:00
9 9.50 2003-10-13 21:00:00
All my examples will be using this table to produce the running totals, sub totals, and grand total reports shown below. Basically this table contains a number of different orders that where created over time. Each order has an ID (OrderID) which uniquely identifies each record, an order amount (OrderAmt) that holds a decimal amount for the order, and a timestamp (OrderDate) that identifies when the order was placed.
- Running Total On Each Record
This first example will display a simple method of calculating the running total of the OrderAmt. The calculated running total will be displayed along with each record in the Orders table. The "Running Total" column will be created with a simple SELECT statement and a correlated sub query. The correlated sub query is the part of the statement that does the heavy lifting to produce the running total.
select OrderId, OrderDate, O.OrderAmt,
(select sum(OrderAmt) from Orders where OrderID <= O.OrderID) as 'Running-Total' from Orders O
On running the above query, the following rows are listed :
OrderId OrderDate OrderAmt Running-Total
----------- -------------------- ---------- -------------
1 2003-10-11 08:00:00 10.50 10.50
2 2003-10-11 10:00:00 11.50 22.00
3 2003-10-11 12:00:00 1.25 23.25
4 2003-10-12 09:00:00 100.57 123.82
5 2003-10-12 11:00:00 19.99 143.81
6 2003-10-13 10:00:00 47.14 190.95
7 2003-10-13 12:00:00 10.08 201.03
8 2003-10-13 19:00:00 7.50 208.53
9 2003-10-13 21:00:00 9.50 218.03
As you can see, there is a "Running Total" column that displays the running total along with the other column information associated with each Orders table record. This running total column is calculated, by summing up the OrderAmt for all Orders where the OrderID is less than or equal to the OrderID of the current ID being displayed.
- Running Totals With Subtotals and Grand totals
In this example, I will calculate a single sub totals for all Orders that were created on the same day and a Grand Total for all Orders. This will be done using a CASE clause in the SELECT statement. Here is my example.
select O.OrderID,convert(char(10),O.OrderDate,101) 'Order Date',O.OrderAmt,
case when OrderID = (select top 1 OrderId from Orders
where convert(char(10),OrderDate,101)
= convert(char(10),O.OrderDate,101)
order by OrderID desc)
then (select cast(sum(OrderAmt) as char(10))
from Orders
where OrderID <= O.OrderID and convert(char(10),OrderDate,101) = convert(char(10),O.OrderDate,101)) else ' ' end as 'Sub Total', case when OrderID = (select top 1 OrderId from Orders order by OrderDate desc) then (select cast(sum(OrderAmt) as char(10)) from Orders) else ' ' end as 'Grand Total' from Orders O order by OrderID
Output from the SELECT statement looks like this:
OrderID Order Date OrderAmt Sub Total Grand Total
----------- ---------- ---------- ---------- -----------
1 10/11/2003 10.50
2 10/11/2003 11.50
3 10/11/2003 1.25 23.25
4 10/12/2003 100.57
5 10/12/2003 19.99 120.56
6 10/13/2003 47.14
7 10/13/2003 10.08
8 10/13/2003 7.50
9 10/13/2003 9.50 74.22 218.03
In this example the first CASE statement controls the printing of the "Sub Total' column. As you can see, the sub total is printed only on the last order of the day, which is determined by using a correlated sub query. The second CASE statement prints the "Grand Total", which is only printed along with the very last order. Each of these CASE statements uses the TOP clause to determine which OrderID is the correct order for which to print out the "Grand Total".