Ssrs SQL Tutorial
Ssrs SQL Tutorial
Ssrs SQL Tutorial
SSRS or SQL server Reporting Services which is also called Microsoft SQL reporting, is a
component of the Microsoft BI stack.
The Microsoft Business Intelligence Stack mainly consists of SQL Database Engine,
SSRS, SSAS, SSIS and other tools
SSRS is a set of readymade tools, that helps you to create, deploy and manage reports.
You can extend reporting functionality using C# and VB as programming languages.
Microsoft SSRS or Business Intelligence SSRS, lets you create very rich reports
(Tabular/Graphical/Interactive/free-form) from various datasources with rich data
visualization (Charts, Maps, sparklines).
All these reports can be viewed via a web browsers.
SSRS allows are reports to be exported in various formats (Excel, PDF, word etc)
SSRS allows reports to be delivered via emails or dropped to a share location in an
automated fashion.
SSRS provides a host of security features, in order to control, who sees which reports
etc.
You can download some samples from here.
Next, lets look at how to install SSRS and get you started.
Step 4: In case you get a pop-up saying "This program has compatibility issues", click Run Program.
Step 7 : Select installation on right hand tab and click on "New SQL server stand -alone installation"
Step 13 : In feature selection, make sure you select 'Database Engine Services' and 'Reporting
Services'
Step 14 : Next, select Named Instance and give it any name (you can also choose Default
instance)
Step 15 : Click next
Step 16 : Select Mixed Mode --> enter in any password --> and specify SQL server admins.
Step 17 : Click next, and select 'Install, but do not configure under Reporting Services configuration.
Your installation is almost complete. In order to start using SSRS, you need to perform a few more
steps.
Step 23: Click Start --> All programs --> Microsoft SQL 2008 --> Configuration Tools --> Reporting
Services Configuration --> select your instance
Step 24 : Click web service URL on the left hand side and click the apply button.
Step 25 : Click database on the left hand side, select change database --> create a new report
server database and complete the steps.
Step 26 : Click report manager URL and click apply (Note down the URL displayed. It should be of
the form http://machinename/reports)
Step 27: open IE and hit the noted down URL
Step 28 : You should get a screen like this.
That's all. We are all set. Let's install some sample databases and get started learning SSRS 2008
Step 2: After installation, open SSMS --> your instance name, then check if the below databases are
visible.
Step 3: You can also install some sample reports from here
This video, gives a brief demo :
http://www.youtube.com/watch?feature=player_embedded&v=Z79S2AGinkU
Now that you are all set with installing SSRS 2008 and some SQL server adventure works database,
Let us proceed with creating our first SSRS report, deploying the same and viewing in the web
browser. For report development , we will use Microsoft Business Intelligence Development studio.
Quite often people ask me, how to install Business intelligence Development studio. Installing
Step 3: Once you click OK, you will be presented with the following screen.
Step 4 : Click Next. Now configure your connection string. I have chosen the type as 'Microsoft SQL
server'
Step 5 : In this step, you need to enter the query for the data, that you need the SSRS report to be
populated with. You can also use the query builder.
Step 6 : Click on query builder, and click on the right most top icon, to add tables
Step 7: Select the necessary table, and verify your query, then click the (!) icon to see the result of
the query after execution.
Step 15 : You can preview the report in Business Intelligence Development Studio.
Step 17 : After successfully deploying the project, open up IE, and hit http://machinename/reports
Alright, now we have published our first simple SSRS report using the Reporting Wizard. We
deployed the report, and viewed it via a web browser. Next, we will understand, how to develop
reports, without the custom report creation wizard. This will give much better control, over
developing custom reports. (Eg. you need to add custom calculations, embed maps etc.
When you fire up, Microsoft Business Intelligence Development studio - it looks like this.
The Left side portion, is where you set up your data connections, what parameters your report
should use, the queries, that return data for your report etc.
The middle portion, is where you actually develop the report. Eg. Setup tabular reports, matrix
reports or embed maps, graphics etc
The Right side portion, is called the solution explorer. It lists down all reports (also called RDL's or
report definition language) to be displayed. Report definition languages are pure XML file.
Here you see a number of tools, that aid you in your report development. You simply need to drag
and drop the tools, that you need in your report, and then configure it accordingly.
We will have a look at some of them in the coming lessons.
Step 3: right click on the "Data sources" folder and add a new data source.
Set the connection string to point to your new adventure works database.
Step 4: Once that is done, right click on the datasets folder, to add a dataset.
This is basically the place, where you will configure your query that returns some data, that you want
to be displayed in the report.
Select the datasource, that you just created and type in a query.
You could also use the "Query Designer" if you want.
Step 6: From the "Report Data", drag and drop the columns defined in the dataset, that you want in
the report.
Step 7: That's it, click on the preview tab and congratulations, you have made your first Microsoft
SQL server report using a non-wizard method.
Step 2: Once you click OK, go to the parameters folder in "Report Data" - you will find that
@postalcode automatically appears in the "Parameters" Fields.
Step 3: Lets explore more about the parameter. Double click on @postalcode.
This is place, where you configure, how your parameter should behave - should it allow blank values
or null values etc.
You can configure the visibility, data-types, default values etc.
Lets leave it as it is for now.
Step 4: Click preview, and enter in a postal code (91370 for example)
Step 1: Create a report server project and connect to Adventure Works Database.
Step 2: Add the SalesOrderDetail table with a couple of columns to the Report.
Step 5: Now lets write some expressions. We will display anything in LineTotal cell as Green, if the
number is above 2000, else we will display in Red.
Right click on the cell , and select text-box properties.
Step 9: Click on the preview tab, you should get the below output.
I have demonstrated a very simple use of expressions. However , you can write very complex
expressions depending on your business needs. For instance, you can write expressions, to
calculate the standard deviation of so and so , and manipulate results accordingly.
Many time, you need to write expressions to deal with Dates and times
For information on: http://msdn.microsoft.com/en-us/library/ms157328.aspx
Step 5: Now drag and drop a table control from the tool box (Left hand pane)
In the table control, drag and drop some fields from your dataset.
Once done, your Design pane should look something like this.
Step 6: Click on the preview tab, and you should be able to see a very basic tabular report.
Step 7: You could also add some totals to your report.
In order to add totals, right click on the cell where you would like to add the totals, click on 'Add
Total'.
Click preview and you should be able to see a tabular report with totals.
SELECT
TOP (100) *
FROM
Sales.SalesOrderDetail
Step 5: Once you create a report, using the above query, your report would look something like this.
Step 6: Now lets play around with some Currency formatting and date formatting.
Right click on the unit price cell.
Step 8: After choosing your money and date format, click preview and report should look something
like this.
5. DimCustomer.
If you run the below query in SQL Server, you will get the following:
Query:
Step 2:
Now lets Add a product name, and lets put the customer Name, order number and Sales Amount
under it.
Right click on the grouping area --> Add group --> Parent Group --> Group by 'Product Name' (Also
Add a group header)
all
a
Mainly
1.
2.
are
2
Using
Lets
there
functionality
of
reporting
XML
web
service
provides
Report
Report
ways
to
services
through
and
has
a
2
use
the
Microsoft.NET
SSRS
Using
look
at
an
example
to
use
SSRS
web
services
using
Web
service.
SOAP
API.
endpoints:
execution
Management
web
services:
Framework
RS.exe
Microsoft
C#.
Step
1:
Create a Visual studio 2010 console application (you can use any Visual Studio version)
I
am
calling
the
application
MyFirstSSRSWebService.
Step
Next click add service reference:
2:
Step
3:
Click advanced--> add web reference -- url - http://localhost/reportserver/reportservice2005.asmx
(replace
localhost
with
your
report
server
name).
Then click add reference
Step
You should be seeing the SSRS webservice that you just added, in the solution explorer:
4:
Step
5
I have created a report called MyFirstReport in my local, and given it a small description.
Step
Now
lets
Copy
try
to programmatically display
paste
this
the
report
name
following
using
using
and
the
c#
6:
description
code:
System;
MyFirstSSRSWebService.myPC;
namespace
{
MyFirstSSRSWebService
class
rs.Url
Program
{
static
void
Main(string[]
args)
{
ReportingService2005
rs
=
new
ReportingService2005();
rs.Credentials
=
System.Net.CredentialCache.DefaultCredentials;
= "http://localhost/reportserver_SSRSexpress/reportservice2005.asmx";
Property
Property
Property[]
name
=
name.Name
description
description.Name
properties
=
properties[0]
properties[1]
new
=
Property();
"Name";
new
Property();
"Description";
=
new
=
=
Property[2];
name;
description;
try
{
Property[]
foreach
returnProperties
=
rs.GetProperties(
"/HelloWorld/MyFirstReport",
properties);
(Property
Console.WriteLine(p.Name
catch
in
+
returnProperties)
{
":
"
+
p.Value);
}
Console.ReadKey();
}
(Exception
e)
{
Console.WriteLine(e.Message);
Console.ReadKey();
}
}
}
Step 7: Run the code, you should be seeing the following output
Likewise, I would encourage you to explore other methods of this web service as well.
One common activity people do, is to programmatically render a report in excel/pdf etc
Step 3: if the credentials are not stored, you will get the following error message.
Click OK
The report should be available in your inbox, at your specified time.
Step 4: Drag and drop the Matrix control from the ToolBox.
Step 5: Drag and drop the territory to the rows and Year to the column:
Step 6: ON clicking Preview, you should be able to get something like this:
Step 7: However the report, does not have any aggregated data.
So lets drag and drop the TotalDue field to the 'Data' area in the report.
Step 8: On clicking preview, you should be able to see the aggregated report as below:
Lets add some child groupings to this report, and explore some visibility toggling features.
Step 1: Right click on the Territory field and add a child group:
Step 6: In the visibility pane, check 'Hide' for 'When the report is initially run'
Also, check the 'display can be toggled by this report item' for Territory
look
at
an
example
of
sub-report.
We
are
going
to
create
a
main
report
with
1
parameter.
As soon as someone selects a parameter, relevant data is displayed + the sub report is also filtered
and
displayed
in
the
main
report
itself.
Step 1: Create a main report (Steps to create a basic report can be found in the previous tutorials)
I
have
the
following
dataset:
SELECT
[TerritoryID]
,[Name]
,[CountryRegionCode]
,[Group]
,[SalesYTD]
,[SalesLastYear]
,[CostYTD]
,[CostLastYear]
,[rowguid]
,[ModifiedDate]
[AdventureWorks].[Sales].[SalesTerritory]
FROM
Where
Step
2:
CountryRegionCode
Create
parameter
@CRC
called
CRC.
pass
in
the
same
parameter
to
it.
Step 6: Lets us the previous tablix report that we created as our sub-report.
Step
Choose the parameters tab, and configure the parameters
7:
Step
8:
click
OK
You should be able to see the main and the sub-report.
and
hit
preview.
If you need to grant all users of your domain access, then you may need to add
'Domain\DomainUSERS' and assign appropriate roles.
There are mainly 5 types of roles, that you can assign to an user or a group.
These roles are:
a. Browser
b. Content Manager
c. My Reports
d. Publisher
e. Report Builder.
Descriptions for each of these roles are provided in the UI itself.
If you wish to add just a particular user of your domain for your report, type the username and select
the appropriate role for the same.
Click OK, and your security is set
Example:
Example:
B int
)
GO
Stored procedures are group of SQL statements that are created previously and stored.
Stored procedures can accept parameters, and also have output parameters.
Permisions can be modifed for stored procedures.
Example:
Example: http://www.youtube.com/watch?v=jx63oKvU8Iw
6. Give an example for Stored Procedures with parameters and output parameters.
Example:
http://www.youtube.com/watch?v=OO-AnA_52Og
data as files on the file system. Transact-SQL statements can insert, update, query, search, and back up
FILESTREAM data.
Example: http://www.youtube.com/watch?v=ONYjKN21aIw
9.Explain stored procedure, function and the difference between them?
Stored procedures are group of SQL statements that are created previously and stored.
User defined function is a database object which has one or more sql statements , which can accept zero
or more parameters and return
either a value or table.
Difference:
1. Stored Procedure can have output parameters UDF s cannot.
2. Stored Procedures return integers UDFs can return scalar or tables.
3. Stored procedures can have Insert/Delete/update Statement UDFs cannot
4. Stored Procedures are compiled at compile time UDFs are compiled at runtime.
5. Stored procedure cannot be used in the select/where/having clause UDFs can be
Example:
Stored procedures: https://www.youtube.com/watch?v=jx63oKvU8Iw
User Defined Functions: https://www.youtube.com/watch?v=vBg216_AODA
10. When do we use a having clause and when do we use a where clause?
Having Clause applies to groups hence used with groupby clause.
Where is applied row by row
Example:
SELECT A, AVG(B)
FROM some_table
GROUP BY A
HAVING AVG(B) >10
11.Explain user defined functions and the difference forms of UDF
https://www.youtube.com/watch?v=vBg216_AODA
Types of triggers:
DDL trigger
DML trigger (instead of/after trigger)
Example:
CREATE TRIGGER T1
ON TABLE_NAME
AFTER INSERT
AS
BEGIN
ROLLBACK TRANSACTION
END
GO
16.Explain linked server with an example.
A Linked Server is a connection to an external data source. The remote data source can be DB2, Oracle, Access or any other data source
that uses an OLE DB provider.
Example:
Collation controls the way string values are sorted. The default collation sorts alphabetically
using the standard Latin character set. Other collations will sort in different orders Collation sensitivity:
Width sensitivity:When
Accent sensitivity:
Case sensitivity:
If A and a, B and b, etc. are treated in the same way then it is case-insensitive. SQL
Kana Sensitivity: When Japanese kana characters Hiragana and Katakana are treated differently, it is called Kana sensitive
Primary key: The key of a relational table that uniquely identifies each record in the table. Primary Key doesnt allow NULLS
Unique Key: Unique Key enforces uniqueness of the column on which they are defined. Unique Key allows one NULL value
19.Explain 1:1, 1:m, m:m relationships1:1 -In a one-to-one relationship, a row in table A can have no more than one matching
row in table B, and vice versa. A one-to-one relationship is created if both of the related columns are primary keys or have unique
constraints.
1:many In 1:many type of relationship, a row in table A can have many matching rows in table B, but a row in table B can have only one
matching row in table A.
many:many: In a many-to-many relationship, a row in table A can have many matching rows in table B, and vice versa. 20.Explain
delete and truncate statement and the differenceDelete: The DELETE Statement is used to delete rows
from a table.
DELETE is a logged operation on a per row basis
Example:
Truncate: The TRUNCATE command is used to delete all the rows from the table and free the space containing the table
An index can be created in a table to find data more quickly and efficiently. it is a structure within SQL that is used to quickly locate specific
rows within a table.
CLUSTERED INDEX: Clustered indexes define the logical order of the table. The leaf level of the clustered index has the actual data pages
of the table. Because of this there can only be one clustered index per table.
NON-CLUSTERED INDEX: Here, the leaf level of a nonclustered index has a pointer as part of each
index row. That pointer is either the clustered index key in the cases where the base table has a clustered
index or the Row Identifier in the cases where the table is a heap
23.Difference between char and nvarchar / char and varchar data-type?
char [ ( n ) ] : Fixed-length, non-Unicode string data. n defines the string length and must be a value from
1 through 8,000. The storage size is n bytes.
varchar [ ( n | max ) ] : Variable-length, non-Unicode string data. n defines the string length and can be a
value from 1 through 8,000. max indicates that the maximum storage size is 2^31-1 bytes (2 GB).
nvarchar [ ( n | max ) ] : Variable-length Unicode string data. n defines the string length and can be a
value from 1 through 4,000. max indicates that the maximum storage size is 2^31-1 bytes (2 GB).
24.What are joins? What are the different types of joins?
Joins are used to query data from more than 2 tables, based on a relationship between columns in these tables.
JOIN: Return rows when there is at least one match in both tables.
LEFT JOIN: Return all rows from the left table, even if there are no matches in the right table
RIGHT JOIN: Return all rows from the right table, even if there are no matches in the left table
FULL JOIN: Return rows when there is a match in one of the tables
Step 2:
Now lets drag and drop a chart control from the toolbox.
As soon as you do that , you get a pop-up, displaying various image shapes for the chart control.
Step 3: These are the set of shapes provided by SSRS for visualization purposes.
Let's choose the first shape.
You should be getting something like this on your scree:
Step 5: In the above example, i have changed the chart title to 'My First Chart'
Now drag and drop TotalDue to the summation of values, CountryRegionCode to the
CategoryGroups and year to the series Groups.
Something like this...
Step 7: Try these steps, with a number of other shapes and graphs/Sparklines/Indicators.
Your design view after creating the report should look something like this.
Now hit preview, and you should be ale to see the follow SSRS 2008 R2 report with a document
map:
Select any one Territory in the document map, and the report will jump to the appropriate page.
In this article, we will cover how to use the deployed SSRS Report on to the ASP.NET Web application. In our
earlier articles we have seen the steps to create and deploy the report to the Reporting Server and administer
the deployed reports. In real time, we have seen requirements on accessing the reports from different clients.
Let us now move ahead for the step-by-step process on accessing the SSRS report in ASP.NET web pages
dynamically.
Steps
Before starting the steps to show the SSRS Report in ASP.NET Page, we should just have a look around on the
previous articles to get some fair idea on how to design the report and deploy it to the Report Server.
First, open visual studio 2010 IDE and create a new ASP.NET Project as shown in the screen below. In this
example we are going to use the report which we deployed in the Part 2 of this series of articles on SSRS.
Now in the ASPX Page, drag and drop a Scriptmanager tool, a button and a report viewer control from the
toolbox as shown in the screen below.
Double click on the button. This will open a button event as shown in the screen below.
In the button click event we need to write our custom code to access the report from the SSRS Server as shown
in the screen below.
Code:
1.reportViewerSam.ProcessingMode =
Microsoft.Reporting.WebForms.ProcessingMode.Remote;
2.reportViewerSam.ServerReport.ReportServerUrl = new
Uri("http://sp2010/ReportServer");
3.reportViewerSam.ServerReport.ReportPath = "/Part2Sample/Report1";
4.reportViewerSam.ServerReport.Refresh();
In the above code, we can have the Report Server URL http://sp2010/ReportServer which we need to
change as per the server URL. The report path on which the report is deployed is /Part2Sample/Report1. Also,
since we are accessing the server directly we need to provide the processing mode as Remote. Once we are
done with the above code, execute the project by clicking the Runbutton or press F5 (functional key) as shown
in the screen below.
Once the project is build successfully, we can see only the button as shown in the screen below.
Now click on Get Reports to access the report directly from the SSRS server. Clicking on Get Report will
load the report and we can see the report generating as shown in the screen below.
Once the report is generated completely, we can see the report with the well formatted structure that has been
deployed to the sever as shown in the screen below.
Conclusion
So, in this article we have seen how to show the deployed SSRS Report in the asp.net web application with
ease without doing any formatting or any design.
Report Designer can create reports of any complexity that Reporting Services supports, but requires you to
understand the structure of your data and to be able to navigate the Visual Studio user interface.
Report Builder provides a simpler user interface for creating ad hoc reports, directed primarily at business
users rather than developers. Report Builder requires a developer or administrator to set up a data model before
end users can create reports.
We'll start our tour of Reporting Services with Report Designer. Report Designer runs inside the Business
Intelligence Development Studio shell, and offers several ways to create reports. You can either use the Report
Wizard to quickly create a report, or you can use a set of design tools to build a report from scratch. You can
also use the design tools to modify a report created with the wizard.
Try It!
To create a simple report using the Report Wizard, follow these steps:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
The Datasets window shows the data that is available to the report.
The main design window lets you view the report itself. You can see a preview of the report, work with the
report in a layout designer, or work with the query that returns the data for the report.
The Solution Explorer, Output, and Properties windows are the standard Visual Studio windows.
Modifying a Report
Now that you've created a report with the Report Wizard, you can modify it with the Report Designer. If
you've used any sort of visual report design tool in the past, you should have no problem making changes here.
Among the possibilities here:
You can change the available data or the sort order for the report by modifying the query on the Data tab.
You can resize or rearrange controls on the Layout tab.
You can use the Properties window to change properties of individual controls including their font, alignment,
colors, and so on.
Try It!
To modify the report that you just created, follow these steps:
1.
2.
3.
4.
5. Click OK.
6. Click in the textbox at the top of the report, where the report name is displayed.
7. Click a second time in the textbox to put it in edit mode and change the value of this control to Products By
Color.
8. Click on the header for the Product column.
9. Place the cursor between the column selectors above the Name and Product Number columns to display a
double-headed arrow. Hold down the mouse button and drag the cursor to the right to widen the Name column.
10. Place the cursor between the column selectors above the Product Number and ListPrice columns to display a
double-headed arrow. Hold down the mouse button and drag the cursor to the right to widen the Product
Number column.
11. Click on the Preview tab to view the modified report, as shown in Figure 17-5.
Designing a Report From Scratch
You can also use Report Designer to build your own reports starting from scratch. In general, you'll follow
these steps to create a report:
1.
2.
3.
4.
Create a Report project in Business Intelligence Design Studio or open an existing Report project.
Add a report to the project.
Create one or more datasets for the report.
Build the report layout.
Try It!
To create a fresh report in Report Designer, follow these steps:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29. Drag the Name field and drop it in the first column of the table control on the design tab.
30. Drag the CostRate field from the Report Data window and drop it in the second column of the table control.
31. Place the cursor between the column selectors above the Name and CostRate columns to display a doubleheaded arrow. Hold down the mouse button and drag the cursor to the right to widen the Name column.
32. Figure 17-6 shows the report in Design view.
Figure 17-6: Designing a report from scratch
33. Select the Preview tab to see the report with data.
SSRS 2008 Tutorial: Publishing a Report
Creating reports in Business Intelligence Development Studio is good for developers, but it doesn't help users
at all. In order for the reports you build to be available to others, you must publish them to your Reporting
Services server. To publish a report, you can use the Build and Deploy menu items in Business Intelligence
Development Studio. Before you do this, you need to check the project's configuration to make sure that
you've selected an appropriate server for the deployment.
Try It!
You can publish any report, but the first report you created is probably more visually interesting at this point.
To publish the first report, follow these steps:
1.
2.
3.
4.
Select File > Recent Projects and choose your ProductReport1 project.
Select Project ProductReport1 Properties.
Click the Configuration Manager button.
Fill in the Target Server URL for your Report Server. If you're developing on the same computer where
Reporting Services is installed, and you installed in the default configuration, this will be
http://localhost/ReportServer. Figure 17-7 shows the completed Property Pages.
5. Click OK.
6. Select Build > Deploy ProductReport1. The Output Window will track the progress of BIDS in deploying your
report, as shown in Figure 17-8. Depending on the speed of your computer, building the report may take some
time.
7. Launch a web browser and enter the address http://localhost/reports.
8. It may take several minutes for the web page to display; Reporting Services goes to sleep when it hasn't been
used for a while and can take a while to spin up to speed. Figure 17-9 shows the result.
9. Click the link for the ProductReport1 folder.
10. Click the link for the ProductReport1 report.
SSRS 2008 Tutorial: Using Report Builder
Report Designer gives you one way to create reports for Reporting Services, but it's not the only way. SQL
Server 2005 also includes a tool directed at end users named Report Builder. Unlike Report Designer, which is
aimed at Developers, Report Builder presents a simplified view of the report-building process and is intended
for business analysts and other end users.
Building a Data Model
Report Builder doesn't let end users explore all of a SQL Server database. Instead, it depends on a data model:
a preselected group of tables and relationships that a developer has identified as suitable for end-user reporting.
To build a data model, you use Business Intelligence Development Studio. Data models contain three things:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
Try It!
1. Open a browser window and navigate to http://localhost/Reports (or to the appropriate Report Server URL if
you're not working on the report server).
2. Click the Report Builder link.
3. Depending on your operating system, you may have to confirm that you want to run the application.
4. After Report Builder is loaded, select the AdventureWorks2008 report model and the table report layout. Click
OK. Figure 17-12 shows the new blank report that Report Builder will create.
Figure 18-12: New report in Report Builder
The Explorer window to the left of the design surface shows all of the tables in
the report model. Beneath that, the Fields window shows the attributes in the
currently-selected entity. Note that not everything in this window is a column in
the table: the report model also contains aggregate entities such as Total Safety
Stock Level and automatically calculated fields.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Export Format
Handles
XML
CSV
MHTML
EXCEL
TIFF
Word
8.
9.
10.
11.
12.
Expand the Total Order Qty field in the Fields window to show the alternative fields beneath it.
Drag the Min Order Qty field and drop it to the right of the Name field.
Drag the Max Order Qty field and drop it to the right of the Min Order Qty field.
Click where it says Click to Add Title and type Sales Performance.
Click the Run Report button to produce the report shown in Figure 17-15.
1) The Report Manager web application, where you can browse and view reports, will require
Windows to authenticate all clients.
2) The only users authorized to use the Report Manager application will be members of the servers
Administrators group (BUILTIN\Administrators). If you want to get your reporting project off the
ground and allow other people in your organization to view reports, youll need to add additional
groups and users into roles. In this article, we will highlight some basic features of Reporting
Services role-based security. Reporting Services Roles Reporting Services ships with 6 built-in
roles: System Administrator, System User, Browser, Content Manager, My Reports, and Publisher.
Placing a Windows user into one of these roles will give the user authorization to perform specific
actions with the report manager. For example, a user in the role of Browser can view folders and
reports, but not publish new reports. A user in the role of Publisher can create, view, and delete
reports, but cannot create new roles. These are the default settings of Reporting Services, which a
user in the System Administrator role can modify.
System Administrators
As mentioned earlier, the Reporting Services setup will place the local machines Administrators
group into the System Administrators role. Since this role is an all-powerful role, youll want take care
with any modifications you make. A true system administrator will probably also need admin
privileges on the server to take care of tasks such as starting and stopping services, so consider
adding the person or group into the local administrators group of the server (but think of the
ramifications first). If you want to add additional users or groups to the System Administrators role
without adding to the local administrators group, youll need to go into the System Role Assignments
page. To do this interactively you can navigate to the report manager (http://reportserver/reports, for
instance) and click Site Settings in the upper right hand of the screen. Towards the bottom of the
Site Settings screen youll find three links under a security heading.
From here you can enter a username, or a group name into the textbox. For machines in a domain,
you can prefix the name with the domain name, (DOMAIN\scott, for example). Reporting Services
will verify the entry, so dont worry about spelling mistakes. Select the checkboxes for the role you
want to assign. Notice you can also create a new system role, though we will not cover the topic in
this article.
Click New role assignment, and enter a group or user name into the textbox shown below:
You can select from the built-in roles shown above, or create a new role. Using the UI you can view
the tasks each role has permissions to perform. The security settings you set will flow downwards,
that is any folders and reports underneath the SampleReports folder will inherit these settings, so
you do not need to repeat this step for each report in the folder. You can break the inheritance by
defining a new security policy for a child item.
Conclusion
I hope that this article will give you a jumpstart on managing roles for Reporting Services. I
recommend you go to the official documentation for additional reading, as this article serves as only
a brief introduction to role-based security in Reporting Services.
Learn how to configure and access SQL Server Reporting Services reports when you get The
permissions granted to user 'domain\username' are insufficient for performing this operation.
(rsAccessDenied)
If you are getting the following error while trying to access or deploy a SQL Services Reporting
Services (ssrs) report server on your localhost:
The permissions granted to user 'domain\username' are insufficient for
performing this operation. (rsAccessDenied)
3.
4.
5.
6.
7.
8.
9.
NOTE: If you don't see the 'Site Settings' link in the top left corner while at http://localhost/reports it is
probably because you aren't running IE as an Administator or you haven't assigned your computers
'domain\username' to the reporting services roles, see how to do this in the next few steps.
Then go to: http://localhost/reports (you may have to login with your Computer's username and password)
You should now be directed to the Home page of SQL Server Reporting Services
here:http://localhost/Reports/Pages/Folder.aspx
From the Home page, click the Properties tab, then click New Role Assignment
In the Group or user name textbox, add the 'domain\username' which was in the error message (in my case, I
added:DOUGDELL3-PC\DOUGDELL3 for the 'domain\username', in your case you can find the
domain\username for your computer in the rsAccessDenied error message).
Now check all the checkboxes; Browser, Content Manager, My Reports, Publisher, Report Builder, and then
click OK.
You're domain\username should now be assigned to the Roles that will give you access to deploy your
reports to the Report Server. If you're using Visual Studio or SQL Server Business Intelligence
Development Studio to deploy your reports to your local reports server, you should now be able to.
Hopefully, that helps you solve your Reports Server rsAccessDenied error message...
Just to let you know this tutorial was done on a Windows 7 computer with SQL Server Reporting Services
2008.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using Microsoft.Reporting.WebForms;
using System.Security.Principal;
using System.Net;
namespace SSRS_integareted
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//SummaryReportTypeDisplay();
}
MyReportViewer.ProcessingMode = ProcessingMode.Remote;
MyReportViewer.ServerReport.ReportServerUrl = new Uri("");//reportserverurl
from reportmanager//
MyReportViewer.ProcessingMode =
Microsoft.Reporting.WebForms.ProcessingMode.Remote;
MyReportViewer.ToolBarItemBorderColor = System.Drawing.Color.PowderBlue;
MyReportViewer.ToolBarItemBorderStyle = BorderStyle.Double;
string strUserName = "Reportserver";
string strPassword = "";//system password
string strDomain = "";//Domain Name
MyReportViewer.ServerReport.ReportServerCredentials = new
ReportServerCredentials(strUserName, strPassword, strDomain);
MyReportViewer.ServerReport.ReportPath = "Reportpath";
MyReportViewer.ServerReport.Refresh();
ReportParameter[] reportParameterCollection1 = new ReportParameter[5];
//Array
size describes the number of paramaters.
reportParameterCollection1[0] = new ReportParameter();
reportParameterCollection1[0].Name = "p1";
//Give Your Parameter
Name
reportParameterCollection1[0].Values.Add("Reports");
reportParameterCollection1[1] = new ReportParameter();
reportParameterCollection1[1].Name = "pID";
//Give Your
Parameter Name
reportParameterCollection1[1].Values.Add("1");
reportParameterCollection1[2] = new ReportParameter();
reportParameterCollection1[2].Name = "pFromDate";
//Give Your
Parameter Name
reportParameterCollection1[2].Values.Add("2013-04-03");
reportParameterCollection1[3] = new ReportParameter();
reportParameterCollection1[3].Name = "pToDate";
//Give Your
Parameter Name
reportParameterCollection1[3].Values.Add("2013-05-30");
reportParameterCollection1[4] = new ReportParameter();
reportParameterCollection1[4].Name = "pName";
//Give Your
Parameter Name
reportParameterCollection1[4].Values.Add("SSRS");
MyReportViewer.ServerReport.SetParameters(reportParameterCollection1);
MyReportViewer.ServerReport.Refresh();
}
Database: southwind
Table: products
productID
INT
productCode
CHAR(3)
name
VARCHAR(30)
quantity
INT
price
DECIMAL(10,2)
1001
PEN
Pen Red
5000
1.23
1002
PEN
Pen Blue
8000
1.25
1003
PEN
Pen Black
2000
1.25
1004
PEC
Pencil 2B
10000
0.48
1005
PEC
Pencil 2H
8000
0.49
2.1 Creating
and
Deleting
DATABASE and DROP DATABASE
Database
- CREATE
IMPORTANT: Use SQL DROP (and DELETE) commands with extreme care, as the deleted entities are
irrecoverable. THERE IS NO UNDO!!!
DATABASE commands
You can create a new table in the default database using command "CREATE TABLE tableName" and
"DROP TABLE tableName". You can also apply condition "IF EXISTS" or "IF NOT EXISTS". To create
a table, you need to define all its columns, by providing the columns' name, type, and attributes.
Let's create the table "products" for our database "southwind".
-- Remove the database "southwind", if it exists.
-- Beware that DROP (and DELETE) actions are irreversible and not recoverable!
mysql> DROP DATABASE IF EXISTS southwind;
Query OK, 1 rows affected (0.31 sec)
Explanations
We define 5 columns in the table products: productID, productCode, name, quantity and price.
The data types are:
a
variable-length
string
of
up
to
30
characters.
We use fixed-length string for productCode, as we assume that the productCode contains
exactly 3 characters. On the other hand, we use variable-length string for name, as its length
varies - VARCHAR is more efficient than CHAR.
quantity is also INT.
price is DECIMAL(10,2) a
decimal
number
with
2
decimal
places.
DECIMAL is precise (represented as integer with a fix decimal point). On the other
hand, FLOAT and DOUBLE (real numbers) are not precise and are approximated. DECIMAL type is
recommended for currency.
The attribute "NOT NULL" specifies that the column cannot contain the NULL value. NULL is a special
name is VARCHAR(30) -
value indicating "no value", "unknown value" or "missing value". We also set the default values of all
the columns. The column will take on its default value, if no value is specified during the record
creation.
We set the column productID as the so-called primary key. Values of the primary-key column must
be unique. Every table shall contain a primary key. This ensures that every row can be distinguished
from other rows. You can specify a single column or a set of columns as the primary key. An index is
build automatically on the primary-key column to facilitate fast search. Primary key is also used as
reference for other tables.
We set the column productID to AUTO_INCREMENT. with default starting value of 1. When you insert
a NULL (recommended) (or 0, or a missing value), into an AUTO_INCREMENT column, the maximum
value of that column plus 1 would be inserted. You can also insert a valid value to
an AUTO_INCREMENT column, bypassing the auto-increment.
+-----------+-------------+-----------+----------+------------+
|
1001 | PEN
| Pen Red
|
5000 |
1.23 |
|
1002 | PEN
| Pen Blue |
8000 |
1.25 |
|
1003 | PEN
| Pen Black |
2000 |
1.25 |
|
1004 | PEC
| Pencil 2B |
10000 |
0.48 |
|
1005 | PEC
| Pencil 2H |
8000 |
0.49 |
|
1006 | PEC
| Pencil HB |
0 | 9999999.99 |
+-----------+-------------+-----------+----------+------------+
6 rows in set (0.02 sec)
-- Remove the last row
mysql> DELETE FROM products WHERE productID = 1006;
Syntex
We can use the INSERT INTO statement to insert a new row with all the column values, using the
following syntax:
INSERT INTO tableName VALUES (firstColumnValue, ..., lastColumnValue)
-- All columns
You need to list the values in the same order in which the columns are defined in the CREATE TABLE,
separated by commas. For columns of string data type (CHAR, VARCHAR), enclosed the value with a
pair of single quotes (or double quotes). For
(INT, DECIMAL, FLOAT, DOUBLE), simply place the number.
columns
of
numeric
data
type
You can also insert multiple rows in one INSERT INTO statement:
INSERT INTO tableName VALUES
(row1FirstColumnValue, ..., row1lastColumnValue),
(row2FirstColumnValue, ..., row2lastColumnValue),
...
The remaining columns will receive their default value, such as AUTO_INCREMENT, default, or NULL.
For examples,
-- List all rows for the specified columns
mysql> SELECT name, price FROM products;
+-----------+-------+
| name
| price |
+-----------+-------+
| Pen Red
| 1.23 |
| Pen Blue | 1.25 |
| Pen Black | 1.25 |
| Pencil 2B | 0.48 |
| Pencil 2H | 0.49 |
+-----------+-------+
5 rows in set (0.00 sec)
-- List all rows of ALL the columns. The wildcard * denotes ALL columns
mysql> SELECT * FROM products;
+-----------+-------------+-----------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+-----------+----------+-------+
|
1001 | PEN
| Pen Red
|
5000 | 1.23 |
|
1002 | PEN
| Pen Blue |
8000 | 1.25 |
|
1003 | PEN
| Pen Black |
2000 | 1.25 |
|
1004 | PEC
| Pencil 2B |
10000 | 0.48 |
|
1005 | PEC
| Pencil 2H |
8000 | 0.49 |
+-----------+-------------+-----------+----------+-------+
5 rows in set (0.00 sec)
+-----+
|
2 |
+-----+
1 row in set (0.00 sec)
mysql> SELECT NOW();
+---------------------+
| NOW()
|
+---------------------+
| 2012-10-24 22:13:29 |
+---------------------+
1 row in set (0.00 sec)
// Multiple columns
mysql> SELECT 1+1, NOW();
+-----+---------------------+
| 1+1 | NOW()
|
+-----+---------------------+
|
2 | 2012-10-24 22:16:34 |
+-----+---------------------+
1 row in set (0.00 sec)
Comparison Operators
For numbers (INT, DECIMAL, FLOAT), you could use comparison operators: '=' (equal
to), '<>' or '!=' (not equal to), '>' (greater than), '<' (less than), '>=' (greater than or equal
to), '<='(less than or equal to), to compare two numbers. For example, price > 1.0, quantity <=
500.
mysql> SELECT name, price FROM products WHERE price < 1.0;
+-----------+-------+
| name
| price |
+-----------+-------+
| Pencil 2B | 0.48 |
| Pencil 2H | 0.49 |
+-----------+-------+
2 rows in set (0.00 sec)
mysql> SELECT name, quantity FROM products WHERE quantity <= 2000;
+-----------+----------+
| name
| quantity |
+-----------+----------+
| Pen Black |
2000 |
+-----------+----------+
1 row in set (0.00 sec)
CAUTION: Do not compare FLOATs (real numbers) for equality ('=' or '<>'), as they are not precise.
On the other hand, DECIMAL are precise.
For strings, you could also use '=', '<>', '>', '<', '>=', '<=' to compare two strings
(e.g., productCode = 'PEC'). The ordering of string depends on the so-called collation chosen. For
example,
mysql> SELECT name, price FROM products WHERE productCode = 'PEN';
-- String values are quoted
+-----------+-------+
| name
| price |
+-----------+-------+
| Pen Red
| 1.23 |
| Pen Blue | 1.25 |
| Pen Black | 1.25 |
+-----------+-------+
3 rows in set (0.00 sec)
'a_b%' matches strings beginning with 'a', followed by any single character, followed by 'b',
MySQL also support regular expression matching via the REGEXE operator.
Arithmetic Operators
You can perform arithmetic operations on numeric fields using arithmetic operators, as tabulated
below:
Operator
Description
Addition
Subtraction
Multiplication
Division
DIV
%
Integer Division
Modulus (Remainder)
+-----------+-------------+-----------+----------+-------+
IN, NOT IN
You can select from members of a set with IN (or NOT IN) operator. This is easier and clearer than the
equivalent AND-OR expression.
mysql> SELECT * FROM products WHERE name IN ('Pen Red', 'Pen Black');
+-----------+-------------+-----------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+-----------+----------+-------+
|
1001 | PEN
| Pen Red
|
5000 | 1.23 |
|
1003 | PEN
| Pen Black |
2000 | 1.25 |
+-----------+-------------+-----------+----------+-------+
Using comparison operator (such as = or <>) to check for NULL is a mistake - a very common mistake.
For example,
SELECT * FROM products WHERE productCode = NULL;
-- This is a common mistake. NULL cannot be compared.
ORDER BY Clause
You can order the rows selected using ORDER BY clause, with the following syntax:
SELECT ... FROM tableName
WHERE criteria
ORDER BY columnA ASC|DESC, columnB ASC|DESC, ...
The selected row will be ordered according to the values in columnA, in either ascending (ASC)
(default) or descending (DESC) order. If several rows have the same value in columnA, it will be
ordered according to columnB, and so on. For strings, the ordering could be case-sensitive or caseinsensitive, depending on the so-called character collating sequence used. For examples,
-- Order the results by price in descending order
mysql> SELECT * FROM products WHERE name LIKE 'Pen %' ORDER BY price DESC;
+-----------+-------------+-----------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+-----------+----------+-------+
|
1002 | PEN
| Pen Blue |
8000 | 1.25 |
|
1003 | PEN
| Pen Black |
2000 | 1.25 |
|
1001 | PEN
| Pen Red
|
5000 | 1.23 |
+-----------+-------------+-----------+----------+-------+
-- Order by price in descending order, followed by quantity in ascending (default)
order
mysql> SELECT * FROM products WHERE name LIKE 'Pen %' ORDER BY price DESC, quantity;
+-----------+-------------+-----------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+-----------+----------+-------+
|
1003 | PEN
| Pen Black |
2000 | 1.25 |
|
1002 | PEN
| Pen Blue |
8000 | 1.25 |
|
1001 | PEN
| Pen Red
|
5000 | 1.23 |
+-----------+-------------+-----------+----------+-------+
You can randomize the returned records via function RAND(), e.g.,
mysql> SELECT * FROM products ORDER BY RAND();
LIMIT Clause
A SELECT query on a large database may produce many rows. You could use the LIMIT clause to
limit the number of rows displayed, e.g.,
-- Display the first two rows
mysql> SELECT * FROM products ORDER BY price LIMIT 2;
+-----------+-------------+-----------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+-----------+----------+-------+
|
1004 | PEC
| Pencil 2B |
10000 | 0.48 |
|
1005 | PEC
| Pencil 2H |
8000 | 0.49 |
+-----------+-------------+-----------+----------+-------+
To continue to the following records , you could specify the number of rows to be skipped, followed
by the number of rows to be displayed in the LIMIT clause, as follows:
-- Skip the first two rows and display the next 1 row
mysql> SELECT * FROM products ORDER BY price LIMIT 2, 1;
+-----------+-------------+---------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+---------+----------+-------+
|
1001 | PEN
| Pen Red |
5000 | 1.23 |
+-----------+-------------+---------+----------+-------+
AS - Alias
You could use the keyword AS to define an alias for an identifier (such as column name, table name).
The alias will be used in displaying the name. It can also be used as reference. For example,
mysql> SELECT productID AS ID, productCode AS Code, name AS Description, price AS
`Unit Price`
-- Define aliases to be used as display names
FROM products
ORDER BY ID;
-- Use alias ID as reference
+------+------+-------------+------------+
| ID
| Code | Description | Unit Price |
+------+------+-------------+------------+
| 1001 | PEN | Pen Red
|
1.23 |
| 1002 | PEN | Pen Blue
|
1.25 |
| 1003 | PEN | Pen Black
|
1.25 |
| 1004 | PEC | Pencil 2B
|
0.48 |
| 1005 | PEC | Pencil 2H
|
0.49 |
+------+------+-------------+------------+
Take note that the identifier "Unit Price" contains a blank and must be back-quoted.
Function CONCAT()
You can also concatenate a few columns as one (e.g., joining the last name and first name) using
function CONCAT(). For example,
mysql> SELECT CONCAT(productCode, ' - ', name) AS `Product Description`, price FROM
products;
+---------------------+-------+
| Product Description | price |
+---------------------+-------+
| PEN - Pen Red
| 1.23 |
| PEN - Pen Blue
| 1.25 |
| PEN - Pen Black
| 1.25 |
| PEC - Pencil 2B
| 0.48 |
| PEC - Pencil 2H
| 0.49 |
+---------------------+-------+
DISTINCT
A column may have duplicate values, we could use keyword DISTINCT to select only distinct values.
We can also apply DISTINCT to several columns to select distinct combinations of these columns. For
examples,
-- Without DISTINCT
mysql> SELECT price FROM products;
+-------+
| price |
+-------+
| 1.23 |
| 1.25 |
| 1.25 |
| 0.48 |
| 0.49 |
+-------+
-- With DISTINCT on price
mysql> SELECT DISTINCT price AS `Distinct Price` FROM products;
+----------------+
| Distinct Price |
+----------------+
|
1.23 |
|
1.25 |
|
0.48 |
|
0.49 |
+----------------+
-- DISTINCT combination of price and name
mysql> SELECT DISTINCT price, name FROM products;
+-------+-----------+
| price | name
|
+-------+-----------+
| 1.23 | Pen Red
|
| 1.25 | Pen Blue |
| 1.25 | Pen Black |
| 0.48 | Pencil 2B |
| 0.49 | Pencil 2H |
+-------+-----------+
GROUP BY Clause
The GROUP BY clause allows you to collapse multiple records with a common value into groups. For
example,
mysql> SELECT * FROM products ORDER BY productCode, productID;
+-----------+-------------+-----------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+-----------+----------+-------+
|
1004 | PEC
| Pencil 2B |
10000 | 0.48 |
|
1005 | PEC
| Pencil 2H |
8000 | 0.49 |
|
1001 | PEN
| Pen Red
|
5000 | 1.23 |
|
1002 | PEN
| Pen Blue |
8000 | 1.25 |
|
1003 | PEN
| Pen Black |
2000 | 1.25 |
+-----------+-------------+-----------+----------+-------+
GROUP BY Aggregate Functions: COUNT, MAX, MIN, AVG, SUM, STD, GROUP_CONCAT
We can apply GROUP BY Aggregate functions to each group to produce group summary report.
The function COUNT(*) returns the rows selected; COUNT(columnName) counts only the nonNULL values of the given column. For example,
-- Function COUNT(*) returns the number of rows selected
mysql> SELECT COUNT(*) AS `Count` FROM products;
-- All rows without GROUP BY clause
+-------+
| Count |
+-------+
|
5 |
+-------+
mysql> SELECT productCode, COUNT(*) FROM products GROUP BY productCode;
+-------------+----------+
| productCode | COUNT(*) |
+-------------+----------+
| PEC
|
2 |
| PEN
|
3 |
+-------------+----------+
-- Order by COUNT - need to define an alias to be used as reference
mysql> SELECT productCode, COUNT(*) AS count
FROM products
GROUP BY productCode
ORDER BY count DESC;
+-------------+-------+
| productCode | count |
+-------------+-------+
| PEN
|
3 |
| PEC
|
2 |
+-------------+-------+
Besides COUNT(),
there
are
many
other GROUP
as AVG(), MAX(), MIN() and SUM(). For example,
BY aggregate
functions
such
HAVING clause
HAVING is
operate
on
the GROUP
mysql> SELECT
productCode AS `Product Code`,
COUNT(*) AS `Count`,
CAST(AVG(price) AS DECIMAL(7,2)) AS `Average`
FROM products
GROUP BY productCode
HAVING Count >=3;
BY aggregate
functions;
WITH ROLLUP
The WITH ROLLUP clause shows the summary of group summary, e.g.,
mysql> SELECT
productCode,
MAX(price),
MIN(price),
CAST(AVG(price) AS DECIMAL(7,2)) AS `Average`,
SUM(quantity)
FROM products
GROUP BY productCode
WITH ROLLUP;
-- Apply aggregate functions to all groups
+-------------+------------+------------+---------+---------------+
| productCode | MAX(price) | MIN(price) | Average | SUM(quantity) |
+-------------+------------+------------+---------+---------------+
| PEC
|
0.49 |
0.48 |
0.49 |
18000 |
| PEN
|
1.25 |
1.23 |
1.24 |
15000 |
| NULL
|
1.25 |
0.48 |
0.94 |
33000 |
+-------------+------------+------------+---------+---------------+
For example,
-- Increase the price by 10% for all products
mysql> UPDATE products SET price = price * 1.1;
mysql> SELECT * FROM products;
+-----------+-------------+-----------+----------+------------+
| productID | productCode | name
| quantity | price
|
+-----------+-------------+-----------+----------+------------+
|
1001 | PEN
| Pen Red
|
5000 |
1.35 |
|
1002 | PEN
| Pen Blue |
8000 |
1.38 |
|
1003 | PEN
| Pen Black |
2000 |
1.38 |
|
1004 | PEC
| Pencil 2B |
10000 |
0.53 |
|
1005 | PEC
| Pencil 2H |
0 | 9999999.99 |
+-----------+-------------+-----------+----------+------------+
-- Modify selected rows
mysql> UPDATE products SET quantity = quantity - 100 WHERE name = 'Pen Red';
mysql> SELECT * FROM products WHERE name = 'Pen Red';
+-----------+-------------+---------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+---------+----------+-------+
|
1001 | PEN
| Pen Red |
4900 | 1.35 |
+-----------+-------------+---------+----------+-------+
-- You can modify more than one values
mysql> UPDATE products SET quantity = quantity + 50, price = 1.23 WHERE name = 'Pen
Red';
mysql> SELECT * FROM products WHERE name = 'Pen Red';
+-----------+-------------+---------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+---------+----------+-------+
|
1001 | PEN
| Pen Red |
4950 | 1.23 |
+-----------+-------------+---------+----------+-------+
CAUTION: If the WHERE clause is omitted in the UPDATE command, ALL ROWS will be updated. Hence,
it is a good practice to issue a SELECT query, using the same criteria, to check the result set before
issuing the UPDATE. This also applies to the DELETE statement in the following section.
extreme
For example,
mysql> DELETE FROM products WHERE name LIKE 'Pencil%';
Query OK, 2 row affected (0.00 sec)
mysql> SELECT * FROM products;
+-----------+-------------+-----------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+-----------+----------+-------+
|
1001 | PEN
| Pen Red
|
4950 | 1.23 |
|
1002 | PEN
| Pen Blue |
8000 | 1.38 |
|
1003 | PEN
| Pen Black |
2000 | 1.38 |
+-----------+-------------+-----------+----------+-------+
care!
Records
are
NOT
-- Use this with extreme care, as the deleted records are irrecoverable!
mysql> DELETE FROM products;
Query OK, 3 rows affected (0.00 sec)
mysql> SELECT * FROM products;
Empty set (0.00 sec)
Beware that "DELETE FROM tableName" without a WHERE clause deletes ALL records from the table.
Even with a WHERE clause, you might have deleted some records unintentionally. It is always advisable
to issue a SELECT command with the same WHERE clause to check the result set before issuing
the DELETE (and UPDATE).
You can load the raw data into the products table as follows:
mysql> LOAD DATA LOCAL INFILE 'd:/path-to/products_in.csv' INTO TABLE products
COLUMNS TERMINATED BY ','
LINES TERMINATED BY '\r\n';
Query OK, 4 rows affected (0.00 sec)
Records: 4 Deleted: 0 Skipped: 0 Warnings: 0
mysql> SELECT * FROM products;
+-----------+-------------+-----------+----------+-------+
| productID | productCode | name
| quantity | price |
+-----------+-------------+-----------+----------+-------+
|
1005 | PEC
| Pencil 3B |
500 | 0.52 |
|
1006 | PEC
| Pencil 4B |
200 | 0.62 |
|
1007 | PEC
| Pencil 5B |
100 | 0.73 |
|
1008 | PEC
| Pencil 6B |
500 | 0.47 |
+-----------+-------------+-----------+----------+-------+
Notes:
You need to provide the path (absolute or relative) and the filename. Use Unix-style forwardslash '/' as the directory separator, instead of Windows-style back-slash '\'.
The default line delimiter (or end-of-line) is '\n' (Unix-style). If the text file is prepared in
Windows, you need to include LINES TERMINATED BY '\r\n'. For Mac, use LINES TERMINATED
BY '\r'.
The default column delimiter is "tab" (in a so-called TSV file - Tab-Separated Values). If you use
another delimiter, e.g. ',', include COLUMNS TERMINATED BY ','.
You must use \N (back-slash + uppercase 'N') for NULL.
mysqlimport Utility
You can also use the mysqlimport utility to load data from a text file. For example,
-- Syntax
> mysqlimport -u username -p --local databaseName tableName.tsv
-- The raw data must be kept in a TSV file of filename the same as tablename
> mysqlimport --help
-- Example
> mysqlimport -u username -p --local southwind d:/myproject/products_in.tsv
DATA command,
you
can
use SELECT
...
OUTFILE fileName FROM tableName to export data from a table to a text file. For example,
INTO
in
an
interactive
client.
For
example,
to
restore
7. via the "batch mode" of the mysql client program, by re-directing the input from the script:
> mysql -u username -p southwind < d:\myproject\load_products.sql
Database: southwind
Table: suppliers
supplierID
INT
name
VARCHAR(3)
phone
CHAR(8)
501
ABC Traders
88881111
502
XYZ Company
88882222
503
QQ Corp
88883333
Database: southwind
Table: products
productID
INT
productCode
CHAR(3)
name
VARCHAR(30)
quantity
INT
price
DECIMAL(10,2)
sup
(Fore
2001
PEC
Pencil 3B
500
0.52
501
2002
PEC
Pencil 4B
200
0.62
501
2003
PEC
Pencil 5B
100
0.73
501
2004
PEC
Pencil 6B
500
0.47
502
We need to first create the suppliers table, because the products table references
the suppliers table. The suppliers table is known as the parent table; while the products table is
known as the child table in this relationship.
mysql> USE southwind;
mysql> DROP TABLE IF EXISTS suppliers;
mysql> CREATE TABLE suppliers (
supplierID INT UNSIGNED
name
VARCHAR(30)
phone
CHAR(8)
PRIMARY KEY (supplierID)
);
ALTER TABLE
Instead of deleting and re-creating the products table, we shall use the statement "ALTER TABLE" to
add a new column supplierID into the products table.
mysql> ALTER TABLE products
ADD COLUMN supplierID INT UNSIGNED NOT NULL;
Query OK, 4 rows affected (0.13 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> DESCRIBE products;
+-------------+------------------+------+-----+------------+----------------+
| Field
| Type
| Null | Key | Default
| Extra
|
+-------------+------------------+------+-----+------------+----------------+
| productID
| int(10) unsigned | NO
| PRI | NULL
| auto_increment |
| productCode | char(3)
| NO
|
|
|
|
| name
| varchar(30)
| NO
|
|
|
|
| quantity
| int(10) unsigned | NO
|
| 0
|
|
| price
| decimal(10,2)
| NO
|
| 9999999.99 |
|
| supplierID | int(10) unsigned | NO
|
| NULL
|
|
+-------------+------------------+------+-----+------------+----------------+
Next, we shall add a foreign key constraint on the supplierID columns of the products child table to
the suppliers parent table, to ensure that every supplierID in the products table always refers to
a valid supplierID in the suppliers table - this is called referential integrity.
Before we can add the foreign key, we need to set the supplierID of the existing records in
the products table to a valid supplierID in the suppliers table (say supplierID=501).
-- Set the supplierID of the existing records to a valid supplierID of supplier table
mysql> UPDATE products SET supplierID = 501;
-- Add a foreign key constrain
mysql> ALTER TABLE products
ADD FOREIGN KEY (supplierID) REFERENCES suppliers (supplierID);
Query OK, 4 rows affected (0.26 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> DESCRIBE products;
+-------------+------------------+------+-----+------------+----------------+
| Field
| Type
| Null | Key | Default
| Extra
|
+-------------+------------------+------+-----+------------+----------------+
......
| supplierID | int(10) unsigned | NO
| MUL |
|
|
+-------------+------------------+------+-----+------------+----------------+
mysql> UPDATE products SET supplierID = 502 WHERE productID
= 2004;
product's name (in products table) and supplier's name (in suppliers table), we could join the two
table via the two common supplierID columns:
-- ANSI style: JOIN ... ON ...
mysql> SELECT products.name, price, suppliers.name
FROM products
JOIN suppliers ON products.supplierID = suppliers.supplierID
WHERE price < 0.6;
+-----------+-------+-------------+
| name
| price | name
|
+-----------+-------+-------------+
| Pencil 3B | 0.52 | ABC Traders |
| Pencil 6B | 0.47 | XYZ Company |
+-----------+-------+-------------+
-- Need to use products.name and suppliers.name to differentiate the two "names"
-- Join via WHERE clause (lagacy and not recommended)
mysql> SELECT products.name, price, suppliers.name
FROM products, suppliers
WHERE products.supplierID = suppliers.supplierID
AND price < 0.6;
+-----------+-------+-------------+
| name
| price | name
|
+-----------+-------+-------------+
| Pencil 3B | 0.52 | ABC Traders |
| Pencil 6B | 0.47 | XYZ Company |
+-----------+-------+-------------+
In the above query result, two of the columns have the same heading " name". We could
create aliases for headings.
-- Use aliases for column names for display
mysql> SELECT products.name AS `Product Name`, price, suppliers.name AS `Supplier
Name`
FROM products
JOIN suppliers ON products.supplierID = suppliers.supplierID
WHERE price < 0.6;
+--------------+-------+---------------+
| Product Name | price | Supplier Name |
+--------------+-------+---------------+
| Pencil 3B
| 0.52 | ABC Traders
|
| Pencil 6B
| 0.47 | XYZ Company
|
+--------------+-------+---------------+
-- Use aliases for table names too
mysql> SELECT p.name AS `Product Name`, p.price, s.name AS `Supplier Name`
FROM products AS p
JOIN suppliers AS s ON p.supplierID = s.supplierID
WHERE p.price < 0.6;
include
the productID in
To resolve this problem, you need to create a new table, known as a junction table (or joint table), to
provide the linkage. Let's call the junction table products_suppliers, as illustrated.
Database: southwind
Table: products_suppliers
productID
INT
(Foreign Key)
supplierID
INT
(Foreign Key)
2001
501
2002
501
2003
501
2004
502
2001
503
Database: southwind
Table: suppliers
supplierID
INT
name
VARCHAR(30)
phone
CHAR(8)
501
ABC Traders
88881111
502
XYZ Company
88882222
503
QQ Corp
88883333
Database: southwind
Table: products
productID
INT
productCode
CHAR(3)
name
VARCHAR(30)
quantity
INT
price
DECIMAL(10,2)
2001
PEC
Pencil 3B
500
0.52
2002
PEC
Pencil 4B
200
0.62
2003
PEC
Pencil 5B
100
0.73
2004
PEC
Pencil 6B
500
0.47
Let's create the products_suppliers table. The primary key of the table consists of two
columns: productID and supplierID, as their combination uniquely identifies each rows. This
primary key is defined to ensure uniqueness. Two foreign keys are defined to set the constraint to
the two parent tables.
mysql> CREATE TABLE products_suppliers (
productID
INT UNSIGNED NOT NULL,
supplierID INT UNSIGNED NOT NULL,
-- Same data types as the parent tables
PRIMARY KEY (productID, supplierID),
-- uniqueness
FOREIGN KEY (productID) REFERENCES products (productID),
FOREIGN KEY (supplierID) REFERENCES suppliers (supplierID)
);
Next, remove the supplierID column from the products table. (This column was added to establish
the one-to-many relationship. It is no longer needed in the many-to-many relationship.)
Before this column can be removed, you need to remove the foreign key that builds on this column.
To remove a key in MySQL, you need to know its constraint name, which was generated by the
system. To find the constraint name, issue a "SHOW CREATE TABLE products" and take note of the
foreign key's constraint name in the clause "CONSTRAINT constraint_name FOREIGN KEY .... ". You
can then drop the foreign key using "ALTER
TABLE
products
DROP
FOREIGN
KEY constraint_name"
mysql> SHOW CREATE TABLE products \G
Create Table: CREATE TABLE `products` (
`productID`
int(10) unsigned NOT NULL AUTO_INCREMENT,
`productCode` char(3)
NOT NULL DEFAULT '',
`name`
varchar(30)
NOT NULL DEFAULT '',
`quantity`
int(10) unsigned NOT NULL DEFAULT '0',
`price`
decimal(7,2)
NOT NULL DEFAULT '99999.99',
`supplierID` int(10) unsigned
NOT NULL DEFAULT '501',
PRIMARY KEY (`productID`),
KEY `supplierID` (`supplierID`),
CONSTRAINT `products_ibfk_1` FOREIGN KEY (`supplierID`)
REFERENCES `suppliers` (`supplierID`)
) ENGINE=InnoDB AUTO_INCREMENT=1006 DEFAULT CHARSET=latin1
Querying
Similarly, we can use SELECT with JOIN to query data from the 3 tables, for examples,
mysql> SELECT products.name AS `Product Name`, price, suppliers.name AS `Supplier
Name`
FROM products_suppliers
JOIN products ON products_suppliers.productID = products.productID
JOIN suppliers ON products_suppliers.supplierID = suppliers.supplierID
WHERE price < 0.6;
+--------------+-------+---------------+
| Product Name | price | Supplier Name |
+--------------+-------+---------------+
| Pencil 3B
| 0.52 | ABC Traders
|
| Pencil 3B
| 0.52 | QQ Corp
|
| Pencil 6B
| 0.47 | XYZ Company
|
+--------------+-------+---------------+
-- Define aliases for tablenames too
mysql> SELECT p.name AS `Product Name`, s.name AS `Supplier Name`
FROM products_suppliers AS ps
JOIN products AS p ON ps.productID = p.productID
JOIN suppliers AS s ON ps.supplierID = s.supplierID
WHERE p.name = 'Pencil 3B';
+--------------+---------------+
| Product Name | Supplier Name |
+--------------+---------------+
| Pencil 3B
| ABC Traders
|
| Pencil 3B
| QQ Corp
|
+--------------+---------------+
-- Using WHERE clause to join (lagacy and not recommended)
mysql> SELECT p.name AS `Product Name`, s.name AS `Supplier Name`
FROM products AS p, products_suppliers AS ps, suppliers AS s
WHERE p.productID = ps.productID
AND ps.supplierID = s.supplierID
AND s.name = 'ABC Traders';
+--------------+---------------+
| Product Name | Supplier Name |
+--------------+---------------+
| Pencil 3B
| ABC Traders
|
| Pencil 4B
| ABC Traders
|
| Pencil 5B
| ABC Traders
|
+--------------+---------------+
The database diagram is as follows. Both products and suppliers tables exhibit a one-to-many
relationship to the junction table. The many-to-many relationship is supported via the junction table.
Study the output file, which contains CREATE DATABASE, CREATE TABLE and INSERT statements to recreate the tables dumped.
The syntax for the mysqldump program is as follows:
-- Dump selected databases with --databases option
> mysqldump -u username -p --databases database1Name [database2Name ...] >
backupFile.sql
-- Dump all databases in the server with --all-databases option, except mysql.user
table (for security)
> mysqldump -u root -p --all-databases --ignore-table=mysql.user > backupServer.sql
-- Dump all the tables of a particular database
> mysqldump -u username -p databaseName > backupFile.sql
-- Dump selected tables of a particular database
> mysqldump -u username -p databaseName table1Name [table2Name ...] > backupFile.sql
Restore: The
SQL
script
(consisting
of CREATE
TABLE and INSERT commands to re-create the tables and loading their data). You can restore from
in
an
interactive
client.
For
example,
to
restore
7. via the "batch mode" of the mysql client program by re-directing the input from the script:
> mysql -u username -p southwind < d:\myproject\backup_southwind.sql
You can specify the reference action for UPDATE and DELETE via the optional ON UPDATE and ON
DELETE clauses:
1. RESTRICT (default): disallow DELETE or UPDATE of the parent's row, if there are matching rows
in child table.
2. CASCADE: cascade the DELETE or UPDATE action to the matching rows in the child table.
3. SET NULL: set the foreign key value in the child table to NULL (if NULL is allowed).
4. NO ACTION: a SQL term which means no action on the parent's row. Same as RESTRICT in
MySQL, which disallows DELETE or UPDATE (do nothing).
Try
deleting
a
record
in
the suppliers (parent)
table
that
is
referenced
by products_suppliers (child) table, e.g.,
mysql> SELECT * FROM products_suppliers;
+-----------+------------+
| productID | supplierID |
+-----------+------------+
|
2001 |
501 |
|
2002 |
501 |
|
2003 |
501 |
|
2004 |
502 |
|
2001 |
503 |
+-----------+------------+
-- Try deleting a row from parent table with matching rows in the child table
mysql> DELETE FROM suppliers WHERE supplierID = 501;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint
fails
(`southwind`.`products_suppliers`, CONSTRAINT `products_suppliers_ibfk_2`
FOREIGN KEY (`supplierID`) REFERENCES `suppliers` (`supplierID`))
The record cannot be deleted as the default "ON DELETE RESTRICT" constraint was imposed.
Example
mysql> CREATE TABLE employees (
emp_no
INT UNSIGNED
NOT
name
VARCHAR(50)
NOT
gender
ENUM ('M','F') NOT
birth_date DATE
NOT
hire_date
DATE
NOT
PRIMARY KEY (emp_no) -- Index
);
NULL AUTO_INCREMENT,
NULL,
NULL,
NULL,
NULL,
built automatically on primary-key column
+-----------+-------------+------+-----+---------+-------+
mysql> SHOW INDEX FROM departments \G
*************************** 1. row ***************************
Table: departments
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: dept_no
.......
*************************** 2. row ***************************
Table: departments
Non_unique: 0
Key_name: dept_name
Seq_in_index: 1
Column_name: dept_name
.......
-- Many-to-many junction table between employees and departments
mysql> CREATE TABLE dept_emp (
emp_no
INT UNSIGNED NOT NULL,
dept_no
CHAR(4)
NOT NULL,
from_date DATE
NOT NULL,
to_date
DATE
NOT NULL,
INDEX
(emp_no),
-- Build INDEX on this non-unique-value
column
INDEX
(dept_no),
-- Build INDEX on this non-unique-value
column
FOREIGN KEY (emp_no) REFERENCES employees (emp_no)
ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (dept_no) REFERENCES departments (dept_no)
ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (emp_no, dept_no) -- Index built automatically
);
mysql> DESCRIBE dept_emp;
+-----------+------------------+------+-----+---------+-------+
| Field
| Type
| Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+-------+
| emp_no
| int(10) unsigned | NO
| PRI | NULL
|
|
| dept_no
| char(4)
| NO
| PRI | NULL
|
|
| from_date | date
| NO
|
| NULL
|
|
| to_date
| date
| NO
|
| NULL
|
|
+-----------+------------------+------+-----+---------+-------+
mysql> SHOW INDEX FROM dept_emp \G
*************************** 1. row ***************************
Table: dept_emp
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: emp_no
........
*************************** 2. row ***************************
Table: dept_emp
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 2
Column_name: dept_no
........
*************************** 3. row ***************************
Table: dept_emp
Non_unique: 1
Key_name: emp_no
Seq_in_index: 1
Column_name: emp_no
........
*************************** 4. row ***************************
Table: dept_emp
Non_unique: 1
Key_name: dept_no
Seq_in_index: 1
Column_name: dept_no
........
5. More SQL
5.1 Sub-Query
Results of one query can be used in another SQL statement. Subquery is useful if more than one
tables are involved.
Date By Example
Let's begin with Date (without Time) with the following example. Take note that date value must be
written as a string in the format of 'yyyy-mm-dd', e.g., '2012-01-31'.
-- Create a table 'patients' of a clinic
mysql> CREATE TABLE patients (
patientID
INT UNSIGNED NOT NULL AUTO_INCREMENT,
name
VARCHAR(30)
NOT NULL DEFAULT '',
dateOfBirth
DATE
NOT NULL,
lastVisitDate DATE
NOT NULL,
nextVisitDate DATE
NULL,
-- The 'Date' type contains a date value in 'yyyy-mm-dd'
PRIMARY KEY (patientID)
);
mysql> INSERT INTO patients VALUES
(1001, 'Ah Teck', '1991-12-31', '2012-01-20', NULL),
(NULL, 'Kumar', '2011-10-29', '2012-09-20', NULL),
(NULL, 'Ali', '2011-01-30', CURDATE(), NULL);
-- Date must be written as 'yyyy-mm-dd'
-- Function CURDATE() returns today's date
mysql> SELECT * FROM patients;
+-----------+---------+-------------+---------------+---------------+
| patientID | name
| dateOfBirth | lastVisitDate | nextVisitDate |
+-----------+---------+-------------+---------------+---------------+
|
1001 | Ah Teck | 1991-12-31 | 2012-01-20
| NULL
|
|
1002 | Kumar
| 2011-10-29 | 2012-09-20
| NULL
|
|
1003 | Ali
| 2011-01-30 | 2012-10-21
| NULL
|
+-----------+---------+-------------+---------------+---------------+
-- Select patients who last visited on a particular range of date
mysql> SELECT * FROM patients
WHERE lastVisitDate BETWEEN '2012-09-15' AND CURDATE()
ORDER BY lastVisitDate;
+-----------+-------+-------------+---------------+---------------+
| patientID | name | dateOfBirth | lastVisitDate | nextVisitDate |
+-----------+-------+-------------+---------------+---------------+
|
1002 | Kumar | 2011-10-29 | 2012-09-20
| NULL
|
|
1003 | Ali
| 2011-01-30 | 2012-10-21
| NULL
|
+-----------+-------+-------------+---------------+---------------+
-- Select patients who were born in a particular year and sort by birth-month
-- Function YEAR(date), MONTH(date), DAY(date) returns
-the year, month, day part of the given date
mysql> SELECT * FROM patients
WHERE YEAR(dateOfBirth) = 2011
ORDER BY MONTH(dateOfBirth), DAY(dateOfBirth);
+-----------+-------+-------------+---------------+---------------+
| patientID | name | dateOfBirth | lastVisitDate | nextVisitDate |
+-----------+-------+-------------+---------------+---------------+
|
1003 | Ali
| 2011-01-30 | 2012-10-21
| NULL
|
|
1002 | Kumar | 2011-10-29 | 2012-09-20
| NULL
|
+-----------+-------+-------------+---------------+---------------+
-- Select patients whose birthday is today
mysql> SELECT * FROM patients
WHERE MONTH(dateOfBirth) = MONTH(CURDATE())
AND DAY(dateOfBirth) = DAY(CURDATE());
-- List the age of patients
-- Function TIMESTAMPDIFF(unit, start, end) returns the difference in the unit
specified
mysql> SELECT name, dateOfBirth, TIMESTAMPDIFF(YEAR, dateOfBirth, CURDATE()) AS age
FROM patients
ORDER BY age, dateOfBirth;
+---------+-------------+------+
| name
| dateOfBirth | age |
+---------+-------------+------+
| Kumar
| 2011-10-29 |
0 |
| Ali
| 2011-01-30 |
1 |
| Ah Teck | 1991-12-31 |
20 |
+---------+-------------+------+
Date/Time Functions
MySQL provides these built-in functions for getting the current date, time and datetime:
NOW(): returns the current date and time in the format of 'YYYY-MM-DD HH:MM:SS'.
CURDATE() (or CURRENT_DATE(), or CURRENT_DATE): returns the current date in the format
of 'YYYY-MM-DD'.
CURTIME() (or CURRENT_TIME(), or CURRENT_TIME): returns the current time in the format
of 'HH:MM:SS'.
For examples,
mysql> select now(), curdate(), curtime();
+---------------------+------------+-----------+
| now()
| curdate() | curtime() |
+---------------------+------------+-----------+
| 2012-10-19 19:53:20 | 2012-10-19 | 19:53:20 |
+---------------------+------------+-----------+
DATETIME: stores both date and time in the format of 'YYYY-MM-DD HH:MM:SS'. The valid range
is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'. You can set a value using the valid
format (e.g., '2011-08-15 00:00:00'). You could also apply functions NOW() or CURDATE() (time
TIME: stores time only in the format of 'HH:MM:SS'. You could apply CURTIME() or NOW() (the
YEAR(4|2): in 'YYYY' or 'YY'. The range of years is 1901 to 2155. Use DATE type for year
outside this range. You could apply CURDATE() to this field (month and day discarded).
TIMESTAMP: similar to DATETIME but stored the number of seconds since January 1, 1970 UTC
(Unix-style).
The
range
is '1970-01-01
00:00:00' to '2037-12-31
23:59:59'.
The differences between DATETIME and TIMESTAMP are:
1. the range,
2. support for time zone,
3. TIMESTAMP column could be declared with DEFAULT CURRENT_TIMESTAMP to set the
default value to the current date/time. (All other data types' default, including DATETIME,
must be a constant and not a function return value). You can also declare
a TIMESTAMP column with "ON UPDATE CURRENT_TIMESTAMP" to capture the timestamp of
the last update.
The
date/time
value
can
be
entered
manually
as
string
literal
(e.g., '2010-12-31
23:59:59' for DATAETIME). MySQL will issue a warning and insert all zeros (e.g., '0000-00-00
00:00:00'for DATAETIME), if the value of date/time to be inserted is invalid or out-of-range. '000000-00' is called a "dummy" date.
Extracting part of a date/time: YEAR(), MONTH(), DAY(), HOUR(), MINUTE(), SECOND(), e.g.,
+-------------+--------------+------------+-------------+---------------+--------------+
| YEAR(NOW()) |
SECOND(NOW()) |
+-------------+--------------+------------+-------------+---------------+--------------+
|
|
2012 |
MONTH(NOW())
10 |
DAY(NOW())
24 |
HOUR(NOW())
11 |
MINUTE(NOW())
54 |
45
+-------------+--------------+------------+-------------+---------------+--------------+
Extracting
infomation: DAYNAME() (e.g., 'Monday'), MONTHNAME() (e.g., 'March'), DAYOFWEEK() (1=Sunday,
, 7=Saturday), DAYOFYEAR() (1-366), ...
mysql>
SELECT
DAYNAME(NOW()),
MONTHNAME(NOW()),
DAYOFWEEK(NOW()),
DAYOFYEAR(NOW());
+----------------+------------------+------------------+------------------+
| DAYNAME(NOW()) | MONTHNAME(NOW()) | DAYOFWEEK(NOW()) | DAYOFYEAR(NOW()) |
+----------------+------------------+------------------+------------------+
| Wednesday
| October
|
4 |
298 |
+----------------+------------------+------------------+------------------+
Computing
another
date/time: DATE_SUB(date,
Computing
interval: DATEDIFF(end_date, start_date), TIMEDIFF(end_time, start_time), TIMESTAMPDIF
F(unit, start_timestamp, end_timestamp), e.g.,
Example
1. Create a table with various date/time columns. Only the TIMESTAMP column can have
the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP .
2. mysql> CREATE TABLE IF NOT EXISTS `datetime_arena` (
3.
`description` VARCHAR(50) DEFAULT NULL,
4.
`cDateTime`
DATETIME
DEFAULT '0000-00-00 00:00:00',
5.
`cDate`
DATE
DEFAULT '0000-00-00',
6.
`cTime`
TIME
DEFAULT '00:00:00',
7.
`cYear`
YEAR
DEFAULT '0000',
8.
`cYear2`
YEAR(2)
DEFAULT '00',
9.
`cTimeStamp`
TIMESTAMP
DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP
10.
);
11.
12. mysql> DESCRIBE `datetime_arena`;
13. +-------------+-------------+------+-----+---------------------+----------------------------+
14. | Field
| Type
| Null | Key | Default
| Extra
|
15. +-------------+-------------+------+-----+---------------------+----------------------------+
16. | description | varchar(50) | YES
|
| NULL
|
|
17. | cDateTime
| datetime
| YES
|
| 0000-00-00 00:00:00 |
|
18. | cDate
| date
| YES
|
| 0000-00-00
|
|
19. | cTime
| time
| YES
|
| 00:00:00
|
|
20. | cYear
| year(4)
| YES
|
| 0000
|
|
21. | cYear2
| year(2)
| YES
|
| 00
|
|
22. | cTimeStamp | timestamp
| NO
|
| CURRENT_TIMESTAMP
| on update
CURRENT_TIMESTAMP |
+-------------+-------------+------+-----+---------------------+----------------------------+
28.
29. mysql> SELECT * FROM `datetime_arena` WHERE description='Manual Entry';
30. +--------------+---------------------+------------+----------+-------+-------+---------------------+
31. | description | cDateTime
| cDate
| cTime
| cYear | cYear2 |
cTimeStamp
|
32. +--------------+---------------------+------------+----------+-------+-------+---------------------+
33. | Manual Entry | 2001-01-01 23:59:59 | 2002-02-02 | 12:30:30 | 2004 |
05 |
2010-04-08 14:44:37 |
+--------------+---------------------+------------+----------+-------+-------+---------------------+
42. Insert values using MySQL built-in functions now(), curdate(), curtime().
43. mysql> INSERT INTO `datetime_arena`
44.
(`description`, `cDateTime`, `cDate`, `cTime`, `cYear`, `cYear2`)
45.
VALUES
46.
('Built-in Functions', now(), curdate(), curtime(), now(), now());
47.
48. mysql> SELECT * FROM `datetime_arena` WHERE description='Built-in Functions';
49. +--------------------+---------------------+------------+----------+-------+-------+---------------------+
50. | description
| cDateTime
| cDate
| cTime
| cYear |
cYear2 | cTimeStamp
|
51. +--------------------+---------------------+------------+----------+-------+-------+---------------------+
52. | Built-in Functions | 2010-04-08 14:45:48 | 2010-04-08 | 14:45:48 | 2010 |
10 | 2010-04-08 14:45:48 |
+--------------------+---------------------+------------+----------+-------+-------+---------------------+
53. Insert invalid or out-of-range values. MySQL replaces with all zeros.
54. mysql> INSERT INTO `datetime_arena`
55.
(`description`, `cDateTime`, `cDate`, `cTime`, `cYear`, `cYear2`)
56.
VALUES
57.
('Error Input', '2001-13-31 23:59:59', '2002-13-31', '12:61:61',
'99999', '999');
58.
59. mysql> SELECT * FROM `datetime_arena` WHERE description='Error Input';
60. +-------------+---------------------+------------+----------+-------+--------+--------------------+
61. | description | cDateTime
| cDate
| cTime
| cYear | cYear2 |
cTimeStamp
|
62. +-------------+---------------------+------------+----------+-------+--------+--------------------+
63. | Error Input | 0000-00-00 00:00:00 | 0000-00-00 | 00:00:00 | 0000 |
00 |
2010-04-08 14:46:10 |
+-------------+---------------------+------------+----------+-------+--------+--------------------+
64. An useful built-in function INTERVAL can be used to compute a future date, e.g.,
65. mysql> SELECT `cDate`, `cDate` + INTERVAL 30 DAY, `cDate` + INTERVAL 1 MONTH
FROM `datetime_arena`;
66. +------------+---------------------------+----------------------------+
67. | cDate
| `cDate` + INTERVAL 30 DAY | `cDate` + INTERVAL 1 MONTH |
68. +------------+---------------------------+----------------------------+
69. | 2002-02-02 | 2002-03-04
| 2002-03-02
|
70. | 2010-04-08 | 2010-05-08
| 2010-05-08
|
71. | 0000-00-00 | NULL
| NULL
|
+------------+---------------------------+----------------------------+
5.3 View
A view is a virtual table that contains no physical data. It provide an alternative way to look at the
data.
Example
-- Define a VIEW called supplier_view from products, suppliers and products_suppliers
tables
mysql> CREATE VIEW supplier_view
AS
SELECT suppliers.name as `Supplier Name`, products.name as `Product Name`
FROM products
JOIN suppliers ON products.productID = products_suppliers.productID
JOIN
products_suppliers
ON
suppliers.supplierID
=
products_suppliers.supplierID;
-- You can treat the VIEW defined like a normal table
Example
mysql> DROP VIEW IF EXISTS patient_view;
mysql> CREATE VIEW patient_view
AS
SELECT
patientID AS ID,
name AS Name,
dateOfBirth AS DOB,
TIMESTAMPDIFF(YEAR, dateOfBirth, NOW()) AS Age
FROM patients
ORDER BY Age, DOB;
mysql> SELECT * FROM patient_view WHERE Name LIKE 'A%';
+------+---------+------------+------+
| ID
| Name
| DOB
| Age |
+------+---------+------------+------+
| 1003 | Ali
| 2011-01-30 |
1 |
| 1001 | Ah Teck | 1991-12-31 |
20 |
+------+---------+------------+------+
mysql> SELECT * FROM patient_view WHERE age >= 18;
+------+---------+------------+------+
| ID
| Name
| DOB
| Age |
+------+---------+------------+------+
| 1001 | Ah Teck | 1991-12-31 |
20 |
+------+---------+------------+------+
5.4 Transactions
A atomic transaction is a set of SQL statements that either ALL succeed or ALL fail. Transaction is
important to ensure that there is no partial update to the database, given an atomic of SQL
statements. Transactions are carried out via COMMIT and ROLLBACK.
Example
mysql> CREATE TABLE accounts (
name
VARCHAR(30),
balance
DECIMAL(10,2)
);
| balance |
+-------+---------+
| Paul
| 1000.00 |
| Peter | 2000.00 |
+-------+---------+
| Peter | 2100.00 |
+-------+---------+
If you start another mysql client and do a SELECT during the transaction (before the commit or
rollback), you will not see the changes.
Alternatively, you can also disable the so-called autocommit mode, which is set by default and
commit every single SQL statement.
-- Disable autocommit by setting it to false (0)
mysql> SET autocommit = 0;
mysql> UPDATE accounts SET balance = balance - 100 WHERE name = 'Paul';
mysql> UPDATE accounts SET balance = balance + 100 WHERE name = 'Peter';
mysql> COMMIT;
mysql> SELECT * FROM accounts;
+-------+---------+
| name | balance |
+-------+---------+
| Paul | 800.00 |
| Peter | 2200.00 |
+-------+---------+
mysql> UPDATE accounts SET balance = balance - 100 WHERE name = 'Paul';
mysql> UPDATE accounts SET balance = balance + 100 WHERE name = 'Peter';
mysql> ROLLBACK;
mysql> SELECT * FROM accounts;
+-------+---------+
| name | balance |
+-------+---------+
| Paul | 800.00 |
| Peter | 2200.00 |
+-------+---------+
mysql> SET autocommit = 1;
-- Enable autocommit
A transaction groups a set of operations into a unit that meets the ACID test:
1. Atomicity: If all the operations succeed, changes are committed to the database. If any of the
operations fails, the entire transaction is rolled back, and no change is made to the database.
In other words, there is no partial update.
2. Consistency: A transaction transform the database from one consistent state to another
consistent state.
3. Isolation: Changes to a transaction are not visible to another transaction until they are
committed.
4. Durability: Committed changes are durable and never lost.
6. More on JOIN
6.1 INNER JOIN
In an inner join of two tables, each row of the first table is combined (joined) with every row of
second table. Suppose that there are n1 rows in the first table and n2 rows in the second table,INNER
JOIN produces all combinations of n1n2 rows - it is known as Cartesian Product or Cross Product.
Example
mysql> DROP TABLE IF EXISTS t1, t2;
mysql> CREATE TABLE t1 (
id
INT PRIMARY KEY,
`desc` VARCHAR(30)
);
-- `desc` is a reserved word - must be back-quoted
mysql> CREATE TABLE t2 (
id
INT PRIMARY KEY,
`desc` VARCHAR(30)
);
mysql> INSERT INTO
(1, 'ID 1
(2, 'ID 2
(3, 'ID 3
t1
in
in
in
VALUES
t1'),
t1'),
t1');
t2
in
in
in
VALUES
t2'),
t2'),
t2');
+----+------------+
| 1 | ID 1 in t1 |
| 2 | ID 2 in t1 |
| 3 | ID 3 in t1 |
+----+------------+
mysql> SELECT * FROM t2;
+----+------------+
| id | desc
|
+----+------------+
| 2 | ID 2 in t2 |
| 3 | ID 3 in t2 |
| 4 | ID 4 in t2 |
+----+------------+
mysql> SELECT *
FROM t1 INNER JOIN t2;
+----+------------+----+------------+
| id | desc
| id | desc
|
+----+------------+----+------------+
| 1 | ID 1 in t1 | 2 | ID 2 in t2 |
| 2 | ID 2 in t1 | 2 | ID 2 in t2 |
| 3 | ID 3 in t1 | 2 | ID 2 in t2 |
| 1 | ID 1 in t1 | 3 | ID 3 in t2 |
| 2 | ID 2 in t1 | 3 | ID 3 in t2 |
| 3 | ID 3 in t1 | 3 | ID 3 in t2 |
| 1 | ID 1 in t1 | 4 | ID 4 in t2 |
| 2 | ID 2 in t1 | 4 | ID 4 in t2 |
| 3 | ID 3 in t1 | 4 | ID 4 in t2 |
+----+------------+----+------------+
-- SELECT all columns in t1 and t2 (*)
-- INNER JOIN produces ALL combinations of rows in t1 and t2
mysql> SELECT *
FROM t1 CROSS JOIN t2 ON t1.id = t2.id;
-- You can use USING clause if the join-columns have the same name
mysql> SELECT *
FROM t1 INNER JOIN t2 USING (id);
+----+------------+------------+
| id | desc
| desc
|
+----+------------+------------+
| 2 | ID 2 in t1 | ID 2 in t2 |
| 3 | ID 3 in t1 | ID 3 in t2 |
+----+------------+------------+
-- Only 3 columns in the result set, instead of 4 columns with ON clause
mysql> SELECT *
FROM t1 INNER JOIN t2 WHERE t1.id = t2.id;
mysql> SELECT *
FROM t1, t2 WHERE t1.id = t2.id;
hand, OUTER JOIN can produce rows that are in one table, but not in another table. There are two
kinds of OUTER JOINs: LEFT JOIN produces rows that are in the left table, but may not in the right
table; whereas RIGHT JOIN produces rows that are in the right table but may not in the left table.
In a LEFT JOIN, when a row in the left table does not match with the right table, it is still selected but
by combining with a "fake" record of all NULLs for the right table.
mysql> SELECT *
FROM t1 LEFT JOIN t2 ON t1.id = t2.id;
+----+------------+------+------------+
| id | desc
| id
| desc
|
+----+------------+------+------------+
| 1 | ID 1 in t1 | NULL | NULL
|
| 2 | ID 2 in t1 |
2 | ID 2 in t2 |
| 3 | ID 3 in t1 |
3 | ID 3 in t2 |
+----+------------+------+------------+
mysql> SELECT *
FROM t1 LEFT JOIN t2 USING (id);
+----+------------+------------+
| id | desc
| desc
|
+----+------------+------------+
| 1 | ID 1 in t1 | NULL
|
| 2 | ID 2 in t1 | ID 2 in t2 |
| 3 | ID 3 in t1 | ID 3 in t2 |
+----+------------+------------+
mysql> SELECT *
FROM t1 RIGHT JOIN t2 ON t1.id = t2.id;
+------+------------+----+------------+
| id
| desc
| id | desc
|
+------+------------+----+------------+
|
2 | ID 2 in t1 | 2 | ID 2 in t2 |
|
3 | ID 3 in t1 | 3 | ID 3 in t2 |
| NULL | NULL
| 4 | ID 4 in t2 |
+------+------------+----+------------+
mysql> SELECT *
FROM t1 RIGHT JOIN t2 USING (id);
+----+------------+------------+
| id | desc
| desc
|
+----+------------+------------+
| 2 | ID 2 in t2 | ID 2 in t1 |
| 3 | ID 3 in t2 | ID 3 in t1 |
| 4 | ID 4 in t2 | NULL
|
+----+------------+------------+
As the result, LEFT JOIN ensures that the result set contains every row on the left table. This is
important, as in some queries, you are interested to have result on every row on the left table, with
no match in the right table, e.g., searching for items without supplier. For example,
mysql> SELECT t1.id, t1.desc
FROM t1 LEFT JOIN t2 USING (id)
WHERE t2.id IS NULL;
+----+------------+
| id | desc
|
+----+------------+
| 1 | ID 1 in t1 |
+----+------------+