Showing posts with label Các Câu Lệnh SELECT. Show all posts
Showing posts with label Các Câu Lệnh SELECT. Show all posts

Tuesday, January 27, 2015

Tìm kiếm dữ liệu theo từ khóa .

-- SQL search all columns in all tables for wildcard - search all tables in database
-- SQL search database for text - SQL Server search all tables in database for keyword
-- Search all text & xml columns of all tables for keyword - information_schema columns
-- Searching for text / data in SQL database without full-text search
-- Search all columns of all tables in a database for a keyword - list all table columns
USE AdventureWorks2008;
GO
-- T-SQL create stored procedure for searching all tables in database
CREATE PROC sprocSearchDatabaseForText
           @WildcardSearchTerm NVARCHAR(64)
AS
  /* The following algorithm builds on metada from INFORMATION_SCHEMA views.

It loops through all tables in the database
by using an outer cursor WHILE loop.

Within the table cursor loop, it loops through all string/text/xml columns
by using an inner cursor WHILE loop.

It executes a dynamic SQL search for the wildcard keyword in each column
within the nested cursor loop.
*/
  BEGIN
    SET NOCOUNT  ON
    
    DECLARE  @OutputLength VARCHAR(4) = '256',    -- SQL Server 2008+ feature
             @NolockOption CHAR(8)    = '(NOLOCK))'
    
    DECLARE  @DynamicSQL        NVARCHAR(MAX),
             @SchemaTableName   NVARCHAR(256),
             @SchemaTableColumn NVARCHAR(128),
             @SearchWildcard    NVARCHAR(128)
    
    SELECT @SearchWildcard = CHAR(39)+REPLACE(@WildcardSearchTerm,CHAR(39),
                             CHAR(39)+CHAR(39))+CHAR(39)
    
    PRINT @SearchWildcard
    
    DECLARE  @SearchResults  TABLE(
                                   SchemaTableColumn NVARCHAR(384),
                                   TextWithKeyword   NVARCHAR(MAX)
                                   )
    
    DECLARE curAllTables CURSOR  FOR
    SELECT   QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) AS SchemaTable
    FROM     INFORMATION_SCHEMA.TABLES
    WHERE    TABLE_TYPE = 'BASE TABLE'
             AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' +
                 QUOTENAME(TABLE_NAME)), 'IsMSShipped') != 1
    ORDER BY SchemaTable
    
    OPEN curAllTables
    
    FETCH NEXT FROM curAllTables
    INTO @SchemaTableName
    
    WHILE (@@FETCH_STATUS = 0) -- Outer cursor loop
      BEGIN
        PRINT @SchemaTableName
        
        SET @SchemaTableColumn = ''
        
        DECLARE curAllColumns CURSOR  FOR -- Nested cursor
        
        SELECT   QUOTENAME(COLUMN_NAME)
        FROM     INFORMATION_SCHEMA.COLUMNS
        WHERE    TABLE_NAME = PARSENAME(@SchemaTableName,1)
                 AND TABLE_SCHEMA = PARSENAME(@SchemaTableName,2)
                 AND DATA_TYPE IN ('varchar','nvarchar','char','nchar','xml')
        ORDER BY ORDINAL_POSITION
        
        OPEN curAllColumns
        
        FETCH NEXT FROM curAllColumns
        INTO @SchemaTableColumn
        
        WHILE (@@FETCH_STATUS = 0) -- Inner cursor loop (nested cursor while)
          BEGIN
            PRINT '  ' + @SchemaTableColumn
            
            SET @DynamicSQL = 'SELECT ''' + @SchemaTableName + '.' +
                @SchemaTableColumn + ''', LEFT(CONVERT(nvarchar(max),' +
                @SchemaTableColumn + '),' + @OutputLength + ')  FROM ' +
                @SchemaTableName + ' ' +
                @NolockOption + ' WHERE CONVERT(nvarchar(max),' +
                @SchemaTableColumn + ') LIKE ' + @SearchWildcard
            
            INSERT INTO @SearchResults
            EXEC sp_executesql
              @DynamicSQL
            
            FETCH NEXT FROM curAllColumns
            INTO @SchemaTableColumn
          END  -- Inner cursor loop
        
        CLOSE curAllColumns
        DEALLOCATE curAllColumns
        
        FETCH NEXT FROM curAllTables
        INTO @SchemaTableName
      END  -- Outer cursor loop
    
    CLOSE curAllTables
    DEALLOCATE curAllTables
    
    SELECT DISTINCT SchemaTableColumn,
                    TextWithKeyword
    FROM   @SearchResults
  END
GO
------------

-- Test searching entire database for keywords
EXEC sprocSearchDatabaseForText  '%Hamilton%'
/* Partial results

SchemaTableColumn                   TextWithKeyWord
[Person].[Address].[AddressLine1]   9215 Hamilton Ave.
[Person].[Address].[AddressLine1]   9719 Hamilton Ave
[Person].[Address].[AddressLine1]   9732 Hamilton Ct.
[Person].[Address].[AddressLine1]   9738 Hamilton Drive
[Person].[Person].[LastName]        Hamilton
*/
EXEC sprocSearchDatabaseForText  'Sánchez'
/* SchemaTableColumn                TextWithKeyWord
[Person].[Person].[LastName]        Sánchez
*/
EXEC sprocSearchDatabaseForText  '%O''Donnell%'
/* SchemaTableColumn                TextWithKeyWord
[Person].[Person].[LastName]        O'Donnell
*/
-- XML column search example
EXEC sprocSearchDatabaseForText  '%Programming%'
/*
SchemaTableColumn TextWithKeyWord
[HumanResources].[JobCandidate].[Resume]  <ns:Resume xmlns:ns="http://schemas.microsoft.com/
sqlserver/2004/07/adventure-works/Resume"><ns:Name><ns:Name.Prefix>Mr.</ns:Name.Prefix><ns:Name.First>Krishna<
/ns:Name.First><ns:Name.Middle/><ns:Name.Last>Sunkammurali</ns:Name.Last><
ns:Name.Suffix/></ns:N
*/

------------

Source : sqlusa

SELECT dữ liệu với các toán tử .

USE AdventureWorks2008;

-- = (Equal to)
SELECT 'Equal to' WHERE 5 = 3+2

-- != (Not equal to)
SELECT 'Not equal to' WHERE 5 != 3+1
SELECT 'Not equal to' WHERE 5 <> (select count(*)
       from HumanResources.Department)

-- > (Greater than)
SELECT 'Greater than' WHERE (select COUNT(*) from HumanResources.Employee)
     > (select count(*) from HumanResources.Department)
    
-- >= (Greater than or equal to)
SELECT 'Greater than or equal to' WHERE (select COUNT(*)
        from HumanResources.Employee)  >= (select count(*) from
        HumanResources.Department)

-- SQL less than
SELECT 'Less than' WHERE (select COUNT(*) from HumanResources.Employee)
     < 400 -- < (Less than)
    
-- SQL less than or equal to
SELECT 'Less than or equal to' WHERE 10  <= (select count(*) from
        HumanResources.Department)

-- in (Equal to any list member)
SELECT 'In operator' WHERE (select count(*) from
        HumanResources.Department) in (15, 16, 17)

-- not in (Not equal to any list member)
SELECT 'Not in operator' WHERE (select count(*) from HumanResources.Department)
        not in (15, 17)

-- between  (Inclusive between two values)
SELECT 'Between' WHERE YEAR(getdate()) between 2009 and 2025

-- not between  (Inclusive not between two values)
SELECT 'Not between' WHERE 11 not between 1 and 10

-- OR operator - logical & bitwise OR
-- Bitwise OR
SELECT 2 | 16  -- 18
-- Logical OR
SELECT 'OR operator' WHERE 5=6 OR 10=2*5

-- AND operator - logical & bitwise AND
-- Bitwise AND
SELECT 8 & 31  -- 8
-- Logical AND
SELECT 'AND operator' WHERE 2*2=4 AND (YEAR(GETDATE()) BETWEEN 2009 AND 2025)

Source : sqlusa

SELECT dữ liệu theo ngày tháng , thời gian .

-- BETWEEN dates implementation for datetime OrderDate - QUICK SYNTAX
DECLARE @StartDate datetime ='20040201', @EndDate datetime = '20040205';
SELECT OrderCount=COUNT(*) FROM AdventureWorks2008.Sales.SalesOrderHeader
WHERE OrderDate >= @StartDate and OrderDate < DATEADD(DD,1,@EndDate);
-- 502
-- BETWEEN dates implementation for datetime OrderDate using DATE data type
DECLARE @StartDate date ='20040201', @EndDate date = '20040205';
SELECT OrderCount=COUNT(*) FROM AdventureWorks2008.Sales.SalesOrderHeader
WHERE OrderDate >= @StartDate and OrderDate < DATEADD(DD,1,@EndDate);
-- 502

------------
-- BETWEEN datetime range QUICK SYNTAX
-- NOTE: equal operator would miss orders dated after midnight (on purpose or by mistake)
------------
-- Past midnight and next midnight
SELECT dateadd(dd, datediff(dd, 0, CURRENT_TIMESTAMP)+0, 0),
       dateadd(dd, 1+datediff(dd, 0, CURRENT_TIMESTAMP)+0, 0)
-- 2016-10-23 00:00:00.000    2016-10-24 00:00:00.000

-- Orders for today (daterange 1 day)
SELECT * FROM AdventureWorks2008.Sales.SalesOrderHeader
WHERE OrderDate >= dateadd(dd, datediff(dd, 0, CURRENT_TIMESTAMP)+0, 0)
  AND OrderDate <  dateadd(dd, 1+datediff(dd, 0, CURRENT_TIMESTAMP)+0, 0)
------------

------------
-- SQL Server count business days function / UDF - exclude Saturdays & Sundays
------------
CREATE FUNCTION ufnGetBusinessDays (@DateStart DATETIME,
                                    @DateEnd   DATETIME)
RETURNS INT
AS
  BEGIN
      IF ( @DateStart IS NULL
            OR @DateEnd IS NULL )
        RETURN ( 0 )

      DECLARE @i INT = 0;

      WHILE ( @DateStart <= @DateEnd )
        BEGIN
            SET @i = @i + CASE
                            WHEN datename(dw, @DateStart) IN (
                                 'Saturday', 'Sunday' )
                          THEN 0
                            ELSE 1
                          END
            SET @DateStart = @DateStart + 1
        END -- while  
      RETURN ( @i )
  END -- function
GO

SELECT dbo.ufnGetBusinessDays('2016-01-01', '2016-12-31')
-- 261
------------
------------
-- SQL datetime between examples using copy of Sales.SalesOrderHeader
------------
USE tempdb;
SELECT * INTO SOH FROM AdventureWorks2008.Sales.SalesOrderHeader
GO

-- Sales order count for the entire month of MARCH 2004
SELECT COUNT(*) FROM SOH WHERE OrderDate >='2004-03-01  00:00:00.000'
                           AND OrderDate < '2004-04-01  00:00:00.000'                    
-- 2109

-- Equivalent datetime or date comparison queries
SELECT COUNT(*) FROM SOH WHERE OrderDate >='2004-03-01'
                           AND OrderDate < '2004-04-01'

-- SQL date between - new in SQL Server 2008 - SQL date range between
SELECT COUNT(*) FROM SOH WHERE
CAST(OrderDate AS DATE) BETWEEN '2004-03-01' AND '2004-03-31'

-- SQL datetime between with explicit inclusive lower and upper limits
/***** WORKS BUT NOT BEST PRACTICES FOR ENTIRE DAYS *****/  
SELECT COUNT(*) FROM SOH WHERE OrderDate
BETWEEN '2004-03-01 00:00:00.000' AND '2004-03-31 23:59:59.997'

-- The following two queries work ONLY if all TIME parts are 00:00:00.000
/***** NOT BEST PRACTICES - WRONG RESULT IF TIME PART IS NOT 12:00AM *****/  
SELECT COUNT(*) FROM SOH WHERE OrderDate
BETWEEN '2004-03-01 00:00:00.000' AND '2004-03-31 00:00:00.000'
SELECT COUNT(*) FROM SOH WHERE OrderDate
BETWEEN '2004-03-01' AND '2004-03-31'
-- datetime range / date range example for SQL between
-- TIME PART assumed to be 12:00AM = 00:00:00.000 not specified
-- SQL datetime between - SQL datetime comparison
SELECT COUNT(*) FROM SOH WHERE OrderDate BETWEEN '2004-01-02' AND '2004-01-07'
-- 344

-- Equivalent datetime range query
-- SQL between is inclusive operator - it includes the limits
SELECT COUNT(*) FROM SOH WHERE OrderDate
BETWEEN '2004-01-02 00:00:00.000' AND '2004-01-07 00:00:00.000'
-- 344

-- Create an order 1 sec passed midnight on 2004-01-07
-- SQL datetime functions
UPDATE TOP(1) SOH SET OrderDate=DATEADD(ss, 1, OrderDate)
       WHERE OrderDate='2004-01-07'
-- (1 row(s) affected)

 -- The sales order with OrderDate = 2004-01-07 00:00:01.000 excluded   
SELECT COUNT(*) FROM SOH WHERE OrderDate
BETWEEN '2004-01-02 00:00:00.000' AND '2004-01-07 00:00:00.000'
-- 343

-- To include the entire day of 2004-01-07 specify upper limit time
SELECT COUNT(*) FROM SOH WHERE OrderDate
BETWEEN '2004-01-02 00:00:00.000' AND '2004-01-07 23:59:59.997'
-- 344

-- Alternate formulation with >=...AND...< double datetime comparison
SELECT COUNT(*) FROM SOH WHERE OrderDate >='2004-01-02'
                           AND OrderDate < '2004-01-08'
-- 344

-- The new DATE type will work correctly with the between operator
-- SQL date between
SELECT COUNT(*) FROM SOH WHERE
CAST(OrderDate AS DATE) BETWEEN '2004-01-02' AND '2004-01-07'
-- 344

-- Equivalent datetime comparison query
SELECT COUNT(*) FROM SOH WHERE OrderDate >='2004-01-02  00:00:00.000'
                           AND OrderDate < '2004-01-08  00:00:00.000'
-- 344

-- Cleanup
DROP TABLE tempdb.dbo.SOH
GO
------------
------------
-- SQL datetime between T-SQL scripts using copy of HumanResources.EmployeePayHistory
------------
USE tempdb;
-- SQL select * into table
SELECT * INTO EPH
FROM AdventureWorks2008.HumanResources.EmployeePayHistory
GO
-- SQL select from new table - SQL datetime between - SQL date between
SELECT BusinessEntityID, RateChangeDate
FROM EPH
WHERE RateChangeDate BETWEEN '1997-11-01' AND '1998-01-05'
GO
/* Results

BusinessEntityID  RateChangeDate
3                 1997-12-12 00:00:00.000
4                 1998-01-05 00:00:00.000
*/

-- SQL update select into table
UPDATE EPH SET RateChangeDate = '1998-01-05 00:00:01.000'
WHERE BusinessEntityID = 4
  AND RateChangeDate = '1998-01-05'
GO

-- SQL between for DATE type
-- The following solution will NOT work correctly
-- The tacit assumption of TIME = 00.00.00.000 is no longer valid
SELECT BusinessEntityID, RateChangeDate
FROM EPH
WHERE RateChangeDate BETWEEN '1997-11-01' AND '1998-01-05'
GO
/* Results

BusinessEntityID  RateChangeDate
3                 1997-12-12 00:00:00.000
*/

-- The following solution will work correctly
SELECT BusinessEntityID, RateChangeDate
FROM EPH
WHERE RateChangeDate >= '1997-11-01' AND 
      RateChangeDate < DATEADD(dd,1,'1998-01-05')
GO
/* Results

BusinessEntityID  RateChangeDate
3                 1997-12-12 00:00:00.000
4                 1998-01-05 00:00:01.000
*/

-- Date type will work correctly - NOT SARGABLE
SELECT BusinessEntityID, RateChangeDate
FROM EPH
WHERE CONVERT(DATE,RateChangeDate) BETWEEN '1997-11-01' AND '1998-01-05'
GO

/* Results

BusinessEntityID  RateChangeDate
3                 1997-12-12 00:00:00.000
4                 1998-01-05 00:00:01.000
*/

-- Date only string type will also work correctly - NOT SARGABLE
SELECT BusinessEntityID, RateChangeDate
FROM EPH
WHERE CONVERT(char(10), RateChangeDate,102) BETWEEN '1997.11.01' AND '1998.01.05'
GO

/* Results

BusinessEntityID  RateChangeDate
3                 1997-12-12 00:00:00.000
4                 1998-01-05 00:00:01.000
*/


DROP TABLE tempdb.dbo.EPH
GO
----------
-- SQL date range between
----------
-- SQL between dates
USE AdventureWorks;
-- SQL between
SELECT [Sales]=COUNT(*) FROM Sales.SalesOrderHeader
WHERE OrderDate BETWEEN '20040301' AND '20040315'
-- Result: 1112

-- BETWEEN operator is equivalent to >=...AND....<=
SELECT [Sales]=COUNT(*) FROM Sales.SalesOrderHeader
WHERE OrderDate
BETWEEN '2004-03-01 00:00:00.000' AND '2004-03-15  00:00:00.000'
/*
Sales orders with OrderDates

'2004-03-15  00:00:01.000'  - 1 second after midnight (12:00AM)
'2004-03-15  00:01:00.000'  - 1 minute after midnight
'2004-03-15  01:00:00.000'  - 1 hour after midnight

are not included in the two queries above.
*/
-- To include the entire day of 2004-03-15 use the following two solutions
SELECT [Sales]=COUNT(*) FROM Sales.SalesOrderHeader
WHERE OrderDate >= '20040301' AND OrderDate < '20040316'

-- SQL between with DATE type (SQL Server 2008)- NOT SARGABLE
SELECT [Sales]=COUNT(*) FROM Sales.SalesOrderHeader
WHERE CONVERT(DATE, OrderDate) BETWEEN '20040301' AND '20040315'
-- 1112

-- SQL between with DATE type (SQL Server 2008)- SARGABLE
-- Same result accidentally because time part of OrderDate is 0
SELECT [Sales]=COUNT(*) FROM Sales.SalesOrderHeader
WHERE OrderDate BETWEEN '20040301' AND '20040315'
-- 1112 

-- SQL range with DATE type (SQL Server 2008)- SARGABLE
SELECT [Sales]=COUNT(*) FROM Sales.SalesOrderHeader
WHERE OrderDate >= CONVERT(DATE,'20040301') AND OrderDate < CONVERT(DATE,'20040316')
-- 1112 
------------

Source : sqlác