SQL Crib Sheet

These notes are intended to provide a simplified crib sheet (or reminder) on SQL. It is not a tutorial. A number of examples for common types of tasks are provided – but little or no explanation.

SQL – Structured Query Language – is a language understood by most database systems. Except where noted it is believed these SQL statements will work with Microsoft SQL Server, Oracle and MySQL.

Select

Return all records all columns in a table:

select * from TableName

Return all records but only field1 and field2 in a table:

select field1, field2 from TableName

Return field1 for all records in a table with a specific value for field2:

select field1 from TableName where field2=123

Return all records in a table where field1 is one of three possible values:

select * from TableName where field1 in (value1,value2,value3)

Return the number of records in a table:

select count(*) from TheTable

Return the number of records in a table with a specific value for field2:

select count(*) from TableName where field2=123

Simple join:

select * from table1, table2where table1.field1=table2.fieldA

or

select table1.field1, table2.fieldA from table1, table2
where table1.field2=table2.fieldB

or

select table1.field1, table2.fieldA
from table1 inner join table2 on table1.field2 = table2.fieldB

Select all unique values in field1 from a table (not supported in MSAccess):

select distinct(field1) from TableName

or

select distinct field1 from TableName

For MSAccess use:

SELECT count(*) from (select distinct field1 from TableName)

Select all unique values for field1 from a table together with the number of records with that unique value:

select field1, count(*) from TableNamegroup by field1

Select all unique values for combinations of field1 and field2 from a table together with the number of records with that combination:

select field1, field2, count(*) from TableNamegroup by field1, field2

Select the number of unique values:

select count(distinct field1) from TableName

Select all duplicate records in a table, where two (or more) records are considered duplicates if they share a common value for a single field:

select field, count(field) from TableNamegroup by field

having count(*) > 1

Select all duplicate records in a table, where two (or more) records are considered duplicates if they share common values for a pair of fields:

select field1, field2, count(*) from TableNamegroup by field1, field2

having count(*) > 1

Select similar records, i.e. all records which have duplicate field1 and field2 in a table but with different field3 (i.e. specifying which fields must be the same and which different):

select * from table as A, table as Bwhere A.field1=B.field1

and A.field2=B.field2

and A.field3<>B.field3;

Note:

  • It is important to specify at least one field which is different between the two records otherwise this query will list a record as being the same as itself.
  • This query will not find duplicate records, i.e. records with every field the same.

Select all records from a table which do not share a common ID with records from a second table:

select * from table1where field1 not in (select field2 from table2)

Note:

  • Sub-queries are quite slow.
  • Sub-queries are not supported in versions of MySQL prior to MySQL 5, so the above will not work on older versions of MySQL. My thanks to Kevin Bowman for pointing out that MySQL 5 supports sub-queries.

An alternative using a join (which can be much faster):

select table1.* from table1
left join table2 on (table1.field1 = table2.field2)
where table2.field2 is null;

The following method (which has been suggested by Michael Miller) is to use EXISTS. It is much faster on SQL Server than the above (but Michael says it is comparable with the left join technique on Oracle):

select * from table1
where not exists (select field2 from table2 where table2.field2 = table1.field1)

To perform a two way join:

select * from
table1 left join table2 on (table1.field1 = table2.field1),
table1 left join table3 on (table1.field2 = table3.field3)

this has been tested on SQL Server, but not on Oracle or MySql. It does not work with MS-Access.

To combine the results of two queries (be aware that the number and types of fields in both queries must agree):

select * from table1union select * from table2

To return a value based on the contents of a field. This can be done using either Iif, Decode or Case, depending on the database.

The following works with MSAccess:

select Iif(field1 = 1, 'one', 'not one')from TableName

This is equivalent to the following on SqlServer:

select Case when field1 = 1 then 'One' else 'Two' Endfrom TableName

For Oracle use the DECODE function.

To create a new table to hold the results of the select query:

select * into table2 from table1

Be aware that this will fail if table2 exists, and that the new table will be created without any indexes.


Insert

Insert new record into a table:

insert into TableName values (1,2,3)

Insert new record into a table explicitly naming fields:

insert into TableName (field1,field2,field3) values (1,2,3)

Insert new record into a table using values from another table:

insert into TableName (field1,field2,field3)select fieldA,2,fieldC from SomeTable

Update

Update all records in a table:

update TableName set field1=2

Update specific records in a table:

update TableName set field1=2 where field1=1

To update more than one field at a time:

update TableName set field1=2, field2=3

Update a field in a table using a value from another table where both records are referenced by a common key – warning, different databases support different syntax!

This works in MS-Access and MySQL (5) but not in SQL Server:

update TableOne
inner join TableTwo on TableOne.commonID = TableTwo.commonID
set TableOne.field1 = TableTwo.fieldX

or

This works in MS-Access but not in SQL Server:

update TableOne, TableTwo    set TableOne.field1 = TableTwo.fieldX

where TableOne.commonID = TableTwo.commonID

or

This works in SQL Server but not in MS-Access (my thanks to John Lee for this):

update tableOneset tableOne.field1=tableTwo.fieldX

from tableOne, tableTwo

where tableOne.commonID=tableTwo.commonID

Note:

  • MS-Access gives the error “Operation must use an updateable query” if you attempt to use any of the above with a view/query rather than a table. The work around is to copy the data from the query into a temporary table and use the temporary table instead.

Delete

Delete all records in a table (dangerous):

delete from TableName

Delete specific records in a table:

delete from TableName where field1=value

Delete records from one table which do not have a matching field in another table:

delete from TableName where field1 not in(select field2 from TableTwo)

Keys

Be aware that there are often subtle syntax variations between different database systems. Also other key properties (for example ‘clustered’) will vary between database systems. Therefore please treat this part of the SQL crib sheet as a guide only.

Create a primary key on a table:

Alter Table TheTable Add Primary Key (field1, field2)

To add an index on a field:

alter table TableName Add Index (field1)

To remove a primary key:

alter table drop primary key

via

SQL Paging

This stored procedure provides a simple method of SQL paging

 

CREATE PROCEDURE [dbo].[Up_Guestbook_List]
@PageNumber int,
@PageSize int
as
begin
set nocount on
declare @TotalRows int
declare @FirstRow int
declare @FirstRowId int
declare @PageTotal float
select @TotalRows = count(id) from Guestbook where status = 1
set @PageTotal = ceiling(cast(@TotalRows as float) / cast(@PageSize as float))
if (@PageNumber < 1) set @PageNumber = 1
if (@PageNumber > @PageTotal) set @PageNumber = @PageTotal
select @FirstRow = (@PageNumber - 1) * @PageSize + 1
if (@FirstRow <= @TotalRows)
begin
set rowcount @FirstRow
select @FirstRowId = id
from Guestbook where status = 1
order by 1c
set rowcount @PageSize
select
@PageNumber as PageNumber,
@PageSize as PageSize,
@PageTotal as PageTotal,
*
from Guestbook
where id >= @FirstRowId and status = 1
order by 1
end
set nocount off
end

Removing embedded HTML tags with SQL

This is an interesting piece of sql, the function accepts a string and removes HTML elements that is inside the string. This is genereally useful when you have data that has embedded HTML content on it. via

Create Function dbo.UTILfn_StripTags
(@Dirty varchar(4000))
Returns varchar(4000)
As
Begin
Declare @Start int,
@End int,
@Length int
While CharIndex('<', @Dirty) > 0 And CharIndex('>', @Dirty, CharIndex('<', @Dirty)) > 0
Begin
Select @Start = CharIndex('<', @Dirty),
@End = CharIndex('>', @Dirty, CharIndex('<', @Dirty))
Select @Length = (@End - @Start) + 1
If @Length > 0
Begin
Select @Dirty = Stuff(@Dirty, @Start, @Length, '')
End
End
return @Dirty
End

SQL Split Function

This SQL function is similar to the VB split function. It takes a nvarchar delimeted list and delimeter and returns a table with the values split on delimeter.

if exists
(select * from dbo.sysobjects where id = object_id(N'[dbo].[UTILfn_Split]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[UTILfn_Split]
GO
create function dbo.UTILfn_Split(
@String nvarchar (4000),
@Delimiter nvarchar (10)
)
returns @ValueTable table ([Value] nvarchar(4000))
begin
declare @NextString nvarchar(4000)
declare @Pos int
declare @NextPos int
declare @CommaCheck nvarchar(1)
--Initialize
set @NextString = ''
set @CommaCheck = right(@String,1)
--Check for trailing Comma, if not exists, INSERT
--if (@CommaCheck <> @Delimiter )
set @String = @String + @Delimiter
--Get position of first Comma
set @Pos = charindex(@Delimiter,@String)
set @NextPos = 1
--Loop while there is still a comma in the String of levels
while (@pos <> 0)
begin
set @NextString = substring(@String,1,@Pos - 1)
insert into @ValueTable ( [Value]) Values (@NextString)
set @String = substring(@String,@pos +1,len(@String))
set @NextPos = @Pos
set @pos = charindex(@Delimiter,@String)
end
return
end

via

SQL Word Filter

Use this snippet inside a SQL 2000 stored procedure to filter content for rude words. You will require a table called FilterWord, with a column called Word containing the words to filter out. The filter works on whole words, not word parts. In the example below, the filter is checking @FromName, @ToName and @Message, it then sets @Response if a filter word is found.

Declare @Words Table(Word varchar(50))
insert into @Words select Word from FilterWord

DECLARE Words_Cursor CURSOR FOR
SELECT Word FROM @Words

OPEN Words_Cursor

FETCH NEXT FROM Words_Cursor into @word

WHILE @@FETCH_STATUS = 0
Begin
if (‘ ‘ + @FromName +’ ‘ like ‘% ‘ + @Word + ‘ %’) begin: set @Response = 2; break; end
if (‘ ‘ + @ToName + ‘ ‘ like ‘% ‘ + @Word + ‘ %’) begin: set @Response = 3; break; end
if (‘ ‘ + @Message+ ‘ ‘ like ‘% ‘ + @Word + ‘ %’) begin: set @Response = 4; break; end

FETCH NEXT FROM Words_Cursor into @word
End
CLOSE Words_Cursor
DEALLOCATE Words_Cursor