顯示具有 SQL 標籤的文章。 顯示所有文章
顯示具有 SQL 標籤的文章。 顯示所有文章

2024年5月15日 星期三

SQL 十進位轉分數

取最大公因數 

Create FUNCTION dbo.GCD(@a INT, @b INT)
RETURNS INT
AS
BEGIN
    --最大公因數
    WHILE @b != 0
    BEGIN
        DECLARE @temp INT;
        SET @temp = @b;
        SET @b = @a % @b;
        SET @a = @temp;
    END
    RETURN @a;
END;

十進位轉分數

Create function dbo.DecimalToFraction (@decimal_value DECIMAL(18, 2))
returns NVARCHAR(50) AS
BEGIN
    DECLARE @whole_part INT;
    DECLARE @fraction_part DECIMAL(18, 2);
    DECLARE @numerator INT;
    DECLARE @denominator INT;
    DECLARE @gcd_value INT;
    DECLARE @fraction_string NVARCHAR(50);

    -- 取得整數部分和小數部分
    SET @whole_part = FLOOR(@decimal_value);
    SET @fraction_part = @decimal_value - @whole_part;
    -- 初始分母为100,以处理小数部分的十分位
    SET @denominator = 100;

    -- 将小数部分转换为分数的分子  0.75 * 100
    SET @numerator = @fraction_part * @denominator;

    -- 确保分子和分母为整数
    SET @numerator = ROUND(@numerator, 0);
    SET @denominator = ROUND(@denominator, 0);

    -- 求分子和分母的最大公因数
    SET @gcd_value = dbo.GCD(@numerator, @denominator);
    WHILE @gcd_value > 1
    BEGIN
        SET @numerator = @numerator / @gcd_value;
        SET @denominator = @denominator / @gcd_value;
        SET @gcd_value = dbo.GCD(@numerator, @denominator);
    END;

    -- 将整数部分和分数部分组合成分数形式
    if @numerator<>0
    begin
      SET @fraction_string = CONCAT(@whole_part, '-', @numerator, '/', @denominator);
    end
    else
    begin
      SET @fraction_string = @whole_part
    end

    return @fraction_string;
END;

SQL 英呎轉分數

取最大公因數

Create FUNCTION dbo.GCD(@a INT, @b INT)
RETURNS INT
AS
BEGIN
    --最大公因數
    WHILE @b != 0
    BEGIN
        DECLARE @temp INT;
        SET @temp = @b;
        SET @b = @a % @b;
        SET @a = @temp;
    END
    RETURN @a;
END;


英吋轉分數

Create function dbo.FeetToFraction (@decimal_value DECIMAL(18, 2))
returns NVARCHAR(50) 
AS
BEGIN
    --英呎轉分數
    declare @Int int;
    DECLARE @whole_part DECIMAL(18, 2);
    DECLARE @fraction_part DECIMAL(18, 2);
    DECLARE @numerator DECIMAL(18, 2);
    DECLARE @denominator DECIMAL(18, 2);
    DECLARE @gcd_value DECIMAL(18, 2);
    DECLARE @fraction_string NVARCHAR(50);

    -- 取得整數部分和小數部分
SET @Int = FLOOR(@decimal_value); --整數
    SET @fraction_part = @decimal_value - @Int; --小數

    -- 初始分母為16
    SET @denominator = 16;

    -- 將小數部份乘以 0.75 * 12
    SET @numerator = @fraction_part * 12;

    -- 取相乘後的整數
    SET @whole_part = FLOOR(@numerator); --整數
    SET @fraction_part = @numerator - @whole_part; --小數
    Set @fraction_part = FLOOR(@fraction_part * @denominator)

    -- 求分子和分母的最大公因数
    SET @gcd_value = dbo.GCD(@fraction_part, @denominator);
    WHILE @gcd_value > 1
    BEGIN
        SET @fraction_part = @fraction_part / @gcd_value;
        SET @denominator = @denominator / @gcd_value;
        SET @gcd_value = dbo.GCD(@fraction_part, @denominator);
    END;

    -- 組合成分數
    if convert(int, @fraction_part) <> 0 
    begin
      SET @fraction_string = CONCAT(@Int, ''' ' ,
  convert(int, @whole_part), '-', 
    convert(int, @fraction_part), '/', convert(int, @denominator),'"');
    end
    else
    begin
      SET @fraction_string = CONCAT(@Int, ''' ' ,
  convert(int, @whole_part), '"');
    end
    
    Return @fraction_string;
END;

2023年3月28日 星期二

2023年3月9日 星期四

SQL PIVOT 直向資料內容轉橫向輸出


Select *
  (
    Select Field01, Field02, Field03, Field04
    From Table1
  ) a
Pivot
  ( 
    Sum(Field05) /*合計值*/
    For Field04 in ([Value01], [Value02], [Value03], [Value04])  /*橫向表頭*/
  ) b




2021年8月27日 星期五

[^] (萬用字元 - 不相符的字元) (Transact-SQL)

 

[^] (萬用字元 - 不相符的字元) (Transact-SQL)


比對不在方括弧 [^] 之間指定範圍或集合內的任何單一字元。 這些萬用字元可用於包含模式比對 (如 LIKE 和 PATINDEX) 的字串比較中。

範例

簡單範例

下列範例會使用 [^] 運算子來尋找 Contact 資料表中前 5 個名字開頭都是 Al 且名字第三個字母不是 a 的人員。

-- Uses AdventureWorks SELECT TOP 5 FirstName, LastName FROM Person.Person WHERE FirstName LIKE 'Al[^a]%';

以下為結果集。

FirstName LastName --------- -------- Alex Adams Alexandra Adams Allison Adams Alisha Alan Alexandra Alexander

搜尋字元範圍

萬用字元集合可以包含單一字元或字元範圍,以及字元和範圍的組合。 下列範例會使用 [^] 運算子來尋找開頭並非字母或數字的字串。

SELECT [object_id], OBJECT_NAME(object_id) AS [object_name], name, column_id FROM sys.columns WHERE name LIKE '[^0-9A-z]%';

以下為結果集。

object_id object_name name column_id --------- ----------- ---- --------- 1591676718 JunkTable _xyz 1


轉貼至: https://docs.microsoft.com/zh-tw/sql/t-sql/language-elements/wildcard-character-s-not-to-match-transact-sql?view=sql-server-ver15

2021年8月26日 星期四

[] (萬用字元-字元 (s) 以符合) (transact-sql)

 符合方括號 [ ] 之間所指定之指定範圍或集合內的任何單一字元。 這些萬用字元可用於包含模式比對 (如 LIKE  PATINDEX) 的字串比較中。

範例

簡單範例

下列範例會傳回開頭為字母 m 的名稱。 [n-z] 會指定第二個字母必須是範圍從 n 到 z 中的某一個字母。 百分比萬用字元 % 允許開頭為字元 3 的任何字元或沒有字元。 model 和 msdb 資料庫符合此原則。 master 資料庫不符合準則,並會從結果集中加以排除。


SELECT name FROM sys.databases WHERE name LIKE 'm[n-z]%';

以下為結果集。

name ----- model msdb


使用結合範圍和單一字元的集合

萬用字元集合可同時包含單一字元和範圍。 下列範例會使用 [] 運算子來尋找開頭為數字或一系列特殊字元的字串。

SELECT [object_id], OBJECT_NAME(object_id) AS [object_name], name, column_id FROM sys.columns WHERE name LIKE '[0-9!@#$.,;_]%';

以下為結果集。

object_id object_name name column_id --------- ----------- ---- --------- 615673241 vSalesPersonSalesByFiscalYears 2002 5 615673241 vSalesPersonSalesByFiscalYears 2003 6 615673241 vSalesPersonSalesByFiscalYears 2004 7 1591676718 JunkTable _xyz 1


轉貼至: https://docs.microsoft.com/zh-tw/sql/t-sql/language-elements/wildcard-character-s-to-match-transact-sql?view=sql-server-ver15


2020年6月9日 星期二

Table 分組後取最大的資料列


1.
  Select A.* 
  From [Table1] as A
  Inner Join (
              Select [Field01], Max([Score]) Score
              From [Table1]
              Group By [Field01) as B on A.[Field01]=B.[Field01] and A.[Score]=B.[Score] 
  Order By A.[Field01]

2.
  Select *
  From (
    Select ROW_NUMBER() OVER(PARTITION BY [Field01] ORDER BY [Score] DESC) as rowid, *
    FROM [Table1]
  )
  Where rowid=1

2020年2月13日 星期四

遞迴 SQL With...

  with [recursive] as(
    ----------------------
    --資料來源 begin
    ----------------------
    Select field1 , field2
    From Table a
    Where field1 = 1
    --------------------
    --資料來源 end
    -------------------
    Union All
    Select b.field1, b.field2
    From Table b
    Join [recursive] on b.field2 = [recursive].fied01
  )
  select * from [recursive]

2018年8月22日 星期三

SQL convert Datetime

Select CONVERT(nvarchar(100), GETDATE(), 0)   -- May 28 2019  8:25AM
Select CONVERT(nvarchar(100), GETDATE(), 1)   -- 05/28/19
Select CONVERT(nvarchar(100), GETDATE(), 2)   -- 19.05.28
Select CONVERT(nvarchar(100), GETDATE(), 3)   -- 28/05/19
Select CONVERT(nvarchar(100), GETDATE(), 4)   -- 28.05.19
Select CONVERT(nvarchar(100), GETDATE(), 5)   -- 28-05-19
Select CONVERT(nvarchar(100), GETDATE(), 6)   -- 28 May 19
Select CONVERT(nvarchar(100), GETDATE(), 7)   -- May 28, 19
Select CONVERT(nvarchar(100), GETDATE(), 8)   -- 08:28:35
Select CONVERT(nvarchar(100), GETDATE(), 9)   -- May 28 2019  8:28:35:360AM
Select CONVERT(nvarchar(100), GETDATE(), 10)  -- 05-28-19
Select CONVERT(nvarchar(100), GETDATE(), 11)  -- 19/05/28
Select CONVERT(nvarchar(100), GETDATE(), 12)  -- 190528
Select CONVERT(nvarchar(100), GETDATE(), 13)  -- 28 May 2019 08:28:53:277
Select CONVERT(nvarchar(100), GETDATE(), 14)  -- 08:28:53:277
Select CONVERT(nvarchar(100), GETDATE(), 20)  -- 2019-05-28 08:29:10
Select CONVERT(nvarchar(100), GETDATE(), 21)  -- 2019-05-28 08:29:10.180
Select CONVERT(nvarchar(100), GETDATE(), 22)  -- 05/28/19  8:29:10 AM
Select CONVERT(nvarchar(100), GETDATE(), 23)  -- 2019-05-28
Select CONVERT(nvarchar(100), GETDATE(), 24)  -- 08:29:27
Select CONVERT(nvarchar(100), GETDATE(), 25)  -- 2019-05-28 08:29:27.490
Select CONVERT(nvarchar(100), GETDATE(), 100) -- May 28 2019  8:29AM
Select CONVERT(nvarchar(100), GETDATE(), 101) -- 05/28/2019
Select CONVERT(nvarchar(100), GETDATE(), 102) -- 2019.05.28
Select CONVERT(nvarchar(100), GETDATE(), 103) -- 28/05/2019
Select CONVERT(nvarchar(100), GETDATE(), 104) -- 28.05.2019
Select CONVERT(nvarchar(100), GETDATE(), 105) -- 28-05-2019
Select CONVERT(nvarchar(100), GETDATE(), 106) -- 28 May 2019
Select CONVERT(nvarchar(100), GETDATE(), 107) -- May 28, 2019
Select CONVERT(nvarchar(100), GETDATE(), 108) -- 08:30:00
Select CONVERT(nvarchar(100), GETDATE(), 109) -- May 28 2019  8:30:00:127AM
Select CONVERT(nvarchar(100), GETDATE(), 110) -- 05-28-2019
Select CONVERT(nvarchar(100), GETDATE(), 111) -- 2019/05/28
Select CONVERT(nvarchar(100), GETDATE(), 112) -- 20190528
Select CONVERT(nvarchar(100), GETDATE(), 113) -- 28 May 2019 08:30:21:373
Select CONVERT(nvarchar(100), GETDATE(), 114) -- 08:30:21:373
Select CONVERT(nvarchar(100), GETDATE(), 120) -- 2019-05-28 08:30:40
Select CONVERT(nvarchar(100), GETDATE(), 121) -- 2019-05-28 08:30:40.233
Select CONVERT(nvarchar(100), GETDATE(), 126) -- 2019-05-28T08:30:40.233
Select CONVERT(nvarchar(100), GETDATE(), 130) -- 24 رمضان 1440  8:30:55:117AM
Select CONVERT(nvarchar(100), GETDATE(), 131) -- 24/09/1440  8:31:01:990AM

2017年10月27日 星期五

SQL Server - 取英文月份名稱

set language  'us_english'

select  convert(char, getdate(), 107)

列出所有 Table 的資料結構.

/* 列出所有 Table 的資料結構.sql */
select C.name as TableName,
case A.status
   when '16' then 'PK'
   else ''
end as [Key], A.name as FieldName, '' as [Desc], D.name as type, A.length,
case A.isnullable
   when '1' then 'V'
   else ''
end as isnullable, isnull(B.text, '') as [Default],
case C.type
  when 'U' then 'Table'
  when 'V' then 'View'
  else ''
end as TableOrView
from syscolumns as A, syscomments as B, systypes as D, sysobjects as C
 where A.cdefault = B.id and A.xtype = D.xtype and D.status <> '1'  -- 排除sysname 和 nvarchar 同 xtype = 231
 and A.id = C.id
 and (C.type = 'U' or C.type = 'V')
order by C.name, A.colid

轉貼至 http://tw.myblog.yahoo.com/jw!nowr4YGVQE4pAgs1INa7JnTZmg--/article?mid=509

將多筆資料的特定欄位依分隔符號組成字串

select STUFF(
  (select  ',' +field1
   from table1
   where ..................
   FOR XML PATH('')
  ), 1, 1, '') aa

參考至 http://www.dotblogs.com.tw/terrychuang/archive/2011/04/16/22867.aspx

TSQL 解析JSON-fn_ParseJSON (轉貼)

Create FUNCTION [dbo].[fn_ParseJSON]( @json nvarchar(max) ) 
RETURNS @hierarchy table 

  element_id int IDENTITY(1, 1) NOT NULL, /* internal surrogate primary key gives the order of parsing and the list order */ 
  parent_id int NOT NULL, /* [0 -- Root] if the element has a parent then it is in this column. The document is the ultimate parent, so you can get the structure from recursing from the document */ 
  object_id int NOT NULL, /* [0 -- Not an object] each list or object has an object id. This ties all elements to a parent. Lists are treated as objects here */ 
  name nvarchar(2000), /* the name of the object */ 
  stringvalue nvarchar(4000) NOT NULL, /*the string representation of the value of the element. */ 
  valuetype nvarchar(100) NOT NULL, /* the declared type of the value represented as a string in stringvalue*/ 
  bigintvalue bigint 

 
AS 
 
BEGIN 
    --20140703 Peter Copy
    --select * from dbo.fn_ParseJSON('{"a":"1", "b":"2"}')

    DECLARE 
        @firstobject int, --the index of the first open bracket found in the JSON string 
        @opendelimiter int, --the index of the next open bracket found in the JSON string 
        @nextopendelimiter int,--the index of subsequent open bracket found in the JSON string 
        @nextclosedelimiter int,--the index of subsequent close bracket found in the JSON string 
        @type nvarchar(10),--whether it denotes an object or an array 
        @nextclosedelimiterChar CHAR(1),--either a '}' or a ']' 
        @contents nvarchar(MAX), --the unparsed contents of the bracketed expression 
        @start int, --index of the start of the token that you are parsing 
        @end int,--index of the end of the token that you are parsing 
        @param int,--the parameter at the end of the next Object/Array token 
        @endofname int,--the index of the start of the parameter at end of Object/Array token 
        @token nvarchar(4000),--either a string or object 
        @value nvarchar(MAX), -- the value as a string 
        @name nvarchar(200), --the name as a string 
        @parent_id int,--the next parent ID to allocate 
        @lenjson int,--the current length of the JSON String 
        @characters NCHAR(62),--used to convert hex to decimal 
        @result BIGINT,--the value of the hex symbol being parsed 
        @index SMALLINT,--used for parsing the hex value 
        @escape int; --the index of the next escape character 
     
    /* in this temporary table we keep all strings, even the names of the elements, since they are 'escaped' 
     * in a different way, and may contain, unescaped, brackets denoting objects or lists. These are replaced in 
     * the JSON string by tokens representing the string 
     */ 
    DECLARE @strings table 
    ( 
        string_id int IDENTITY(1, 1), 
        stringvalue nvarchar(MAX) 
    ) 
     
    /* initialise the characters to convert hex to ascii */ 
    SET @characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
    SET @parent_id = 0; 
     
    /* firstly we process all strings. This is done because [{} and ] aren't escaped in strings, which complicates an iterative parse. */ 
    WHILE 1 = 1 /* forever until there is nothing more to do */ 
    BEGIN 
        SET @start = PATINDEX('%[^a-zA-Z]["]%', @json collate SQL_Latin1_General_CP850_Bin); /* next delimited string */ 
         
        IF @start = 0 BREAK; /*no more so drop through the WHILE loop */ 
         
        IF SUBSTRING(@json, @start+1, 1) = '"' 
        BEGIN  /* Delimited name */ 
            SET @start = @start+1; 
            SET @end = PATINDEX('%[^\]["]%', RIGHT(@json, LEN(@json+'|')-@start) collate SQL_Latin1_General_CP850_Bin); 
        END 
         
        IF @end = 0 /*no end delimiter to last string*/ 
            BREAK; /* no more */ 
         
        SELECT @token = SUBSTRING(@json, @start+1, @end-1) 
         
        /* now put in the escaped control characters */ 
        SELECT @token = REPLACE(@token, from_string, to_string) 
        FROM 
        ( 
            SELECT '\"' AS from_string, '"' AS to_string 
            UNION ALL 
            SELECT '\\', '\' 
            UNION ALL 
            SELECT '\/', '/' 
            UNION ALL 
            SELECT '\b', CHAR(08) 
            UNION ALL 
            SELECT '\f', CHAR(12) 
            UNION ALL 
            SELECT '\n', CHAR(10) 
            UNION ALL 
            SELECT '\r', CHAR(13) 
            UNION ALL 
            SELECT '\t', CHAR(09) 
        ) substitutions; 
         
        SET @result = 0; 
        SET @escape = 1; 
         
        /*Begin to take out any hex escape codes*/ 
        WHILE @escape > 0 
        BEGIN 
         
            /* find the next hex escape sequence */ 
            SET @index = 0; 
            SET @escape = PATINDEX('%\x[0-9a-f][0-9a-f][0-9a-f][0-9a-f]%', @token collate SQL_Latin1_General_CP850_Bin); 
             
            IF @escape > 0 /* if there is one */ 
            BEGIN 
                 
                WHILE @index < 4 /* there are always four digits to a \x sequence  */ 
                BEGIN 
                    /* determine its value */ 
                    SET @result = @result + POWER(16, @index) * (CHARINDEX(SUBSTRING(@token, @escape + 2 + 3 - @index, 1), @characters) - 1); 
                    SET @index = @index + 1; 
                END 
                 
                /* and replace the hex sequence by its unicode value */ 
                SET @token = STUFF(@token, @escape, 6, NCHAR(@result)); 
            END 
             
        END 
         
        /* now store the string away */ 
        INSERT INTO @strings (stringvalue) SELECT @token; 
         
        /* and replace the string with a token */ 
        SET @json = STUFF(@json, @start, @end + 1, '@string' + CONVERT(nvarchar(5), @@identity)); 
         
    END 
     
    /* all strings are now removed. Now we find the first leaf. */ 
    WHILE 1 = 1  /* forever until there is nothing more to do */ 
    BEGIN 
     
        SET @parent_id = @parent_id + 1; 
         
        /* find the first object or list by looking for the open bracket */ 
        SET @firstobject = PATINDEX('%[{[[]%', @json collate SQL_Latin1_General_CP850_Bin);  /*object or array*/ 
         
        IF @firstobject = 0 BREAK; 
         
        IF (SUBSTRING(@json, @firstobject, 1) = '{') 
            SELECT @nextclosedelimiterChar = '}', @type = 'object'; 
        ELSE 
            SELECT @nextclosedelimiterChar = ']', @type = 'array'; 
         
         
        SET @opendelimiter = @firstobject; 
         
        WHILE 1 = 1 --find the innermost object or list... 
        BEGIN 
            SET @lenjson = LEN(@json+'|') - 1; 
             
            /* find the matching close-delimiter proceeding after the open-delimiter */ 
            SET @nextclosedelimiter = CHARINDEX(@nextclosedelimiterChar, @json, @opendelimiter + 1); 
             
            /* is there an intervening open-delimiter of either type */ 
            SET @nextopendelimiter = PATINDEX('%[{[[]%',RIGHT(@json, @lenjson-@opendelimiter) collate SQL_Latin1_General_CP850_Bin); /*object*/ 
             
            IF @nextopendelimiter = 0 BREAK; 
             
            SET @nextopendelimiter = @nextopendelimiter + @opendelimiter; 
             
            IF @nextclosedelimiter < @nextopendelimiter BREAK; 
             
            IF SUBSTRING(@json, @nextopendelimiter, 1) = '{' 
                SELECT @nextclosedelimiterChar = '}', @type = 'object'; 
            ELSE 
                SELECT @nextclosedelimiterChar = ']', @type = 'array'; 
             
            SET @opendelimiter = @nextopendelimiter; 
        END 
         
        /* and parse out the list or name/value pairs */ 
        SET @contents = SUBSTRING(@json, @opendelimiter+1, @nextclosedelimiter-@opendelimiter - 1); 
         
        SET @json = STUFF(@json, @opendelimiter, @nextclosedelimiter - @opendelimiter + 1, '@' + @type + CONVERT(nvarchar(5), @parent_id)); 
         
        WHILE (PATINDEX('%[A-Za-z0-9@+.e]%', @contents collate SQL_Latin1_General_CP850_Bin)) <  > 0 
        BEGIN /* WHILE PATINDEX */ 
         
            IF @type = 'object' /*it will be a 0-n list containing a string followed by a string, number,boolean, or null*/ 
            BEGIN 
                 
                SET @end = CHARINDEX(':', ' '+@contents); /*if there is anything, it will be a string-based name.*/ 
                SET @start = PATINDEX('%[^A-Za-z@][@]%', ' ' + @contents collate SQL_Latin1_General_CP850_Bin); /*AAAAAAAA*/ 
                 
                SET @token = SUBSTRING(' '+@contents, @start + 1, @end - @start - 1); 
                SET @endofname = PATINDEX('%[0-9]%', @token collate SQL_Latin1_General_CP850_Bin); 
                SET @param = RIGHT(@token, LEN(@token)-@endofname + 1); 
                 
                SET @token = LEFT(@token, @endofname - 1); 
                SET @contents = RIGHT(' ' + @contents, LEN(' ' + @contents + '|') - @end - 1); 
                 
                SELECT @name = stringvalue FROM @strings WHERE string_id = @param; /*fetch the name*/ 
                 
            END 
            ELSE 
            BEGIN 
                SET @name = null; 
            END 
             
            SET @end = CHARINDEX(',', @contents);  /*a string-token, object-token, list-token, number,boolean, or null*/ 
             
            IF @end = 0 
                SET @end = PATINDEX('%[A-Za-z0-9@+.e][^A-Za-z0-9@+.e]%', @contents+' ' collate SQL_Latin1_General_CP850_Bin) + 1; 
             
            SET @start = PATINDEX('%[^A-Za-z0-9@+.e][A-Za-z0-9@+.e]%', ' ' + @contents collate SQL_Latin1_General_CP850_Bin); 
             
            /*select @start,@end, LEN(@contents+'|'), @contents */ 
             
            SET @value = RTRIM(SUBSTRING(@contents, @start, @end-@start)); 
            SET @contents = RIGHT(@contents + ' ', LEN(@contents+'|') - @end); 
             
            IF SUBSTRING(@value, 1, 7) = '@object' 
                INSERT INTO @hierarchy (name, parent_id, stringvalue, object_id, valuetype) 
                SELECT @name, @parent_id, SUBSTRING(@value, 8, 5), SUBSTRING(@value, 8, 5), 'object'; 
             
            ELSE 
                IF SUBSTRING(@value, 1, 6) = '@array' 
                    INSERT INTO @hierarchy (name, parent_id, stringvalue, object_id, valuetype) 
                    SELECT @name, @parent_id, SUBSTRING(@value, 7, 5), SUBSTRING(@value, 7, 5), 'array'; 
                ELSE 
                    IF SUBSTRING(@value, 1, 7) = '@string' 
                        INSERT INTO @hierarchy (name, parent_id, stringvalue, valuetype, object_id) 
                        SELECT @name, @parent_id, stringvalue, 'string', 0 
                        FROM @strings 
                        WHERE string_id = SUBSTRING(@value, 8, 5); 
                    ELSE 
                        IF @value IN ('true', 'false') 
                            INSERT INTO @hierarchy (name, parent_id, stringvalue, valuetype, object_id) 
                            SELECT @name, @parent_id, @value, 'boolean', 0; 
                        ELSE 
                            IF @value = 'null' 
                                INSERT INTO @hierarchy (name, parent_id, stringvalue, valuetype, object_id) 
                                SELECT @name, @parent_id, @value, 'null', 0; 
                            ELSE 
                                IF PATINDEX('%[^0-9]%', @value collate SQL_Latin1_General_CP850_Bin) > 0 
                                    INSERT INTO @hierarchy (name, parent_id, stringvalue, valuetype, object_id) 
                                    SELECT @name, @parent_id, @value, 'real', 0; 
                                ELSE 
                                    INSERT INTO @hierarchy (name, parent_id, stringvalue, valuetype, object_id, bigintvalue) 
                                    SELECT @name, @parent_id, @value, 'bigint', 0, dbo.TryConvertBigInt(@value); 
                                 
        END /* WHILE PATINDEX */ 
     
    END /* WHILE 1=1 forever until there is nothing more to do */ 
     
    INSERT INTO @hierarchy (name, parent_id, stringvalue, object_id, valuetype) 
    SELECT '', 0, '', @parent_id - 1, @type; 
     
    RETURN; 
 
END 

TSQL 小數轉分數-fn_DftOf

Create [dbo].[fn_DftOf](@JSON nvarchar(2000))
RETURNS varchar(100)
as 
begin
  -----------------
  --小數轉分數-----
  -----------------
  declare
    @type varchar(50)='',
    @value varchar(50)='',
    @num1 varchar(50)='',
    @num2 varchar(50)=''
 
  declare
    @sStr    varchar(50),
    @iValue  decimal(12,6),
    @sResult varchar(50),
    @sFh     varchar(20)='', --負數符號
    @sZs     varchar(20),    --整數 
    @sXs     varchar(20),    --小數 
    @iPos    int,            --小數點位置 
    @iFm     int,            --分母 
    @iFz     int,            --分子 
    @iZdgys  int             --最大公約數
   
  declare
    @iYs int, --餘數
    @iNum1 int,
    @iNum2 int 
   
  select @type=stringvalue from dbo.fn_parsejson(@JSON) where name='type' 
  select @value=stringvalue from dbo.fn_parsejson(@JSON) where name='value'
  select @num1=stringvalue from dbo.fn_parsejson(@JSON) where name='num1'
  select @num2=stringvalue from dbo.fn_parsejson(@JSON) where name='num2'
 
  ------------------------------------------------------------------------------------------------------------------------
  ------------------------------------------------------------------------------------------------------------------------
  --小數轉分數
  ------------------------------------------------------------------------------------------------------------------------
  ------------------------------------------------------------------------------------------------------------------------
  if @type=''
  begin
    --select dbo.fn_DftOf('{"value":"0.5"}')
    --select dbo.fn_DftOf('{"value":"-3.5"}')
    --select dbo.fn_DftOf('{"value":"90.000000"}')
    --select dbo.fn_DftOf('{"value":"90"}')
    --select dbo.fn_DftOf('{"value":"26.156250"}')
   
    set @iValue = Convert(Decimal(12,6), @value)
    if @iValue<0
      set @sFh = '-'
    set @sZs = Convert(varchar(50), Abs(Cast(@iValue as int))) --整數 
    set @iValue = @iValue - cast(@iValue  as int)         --Ex: -1.2345 -> -0.2345
    set @iValue = Abs(@iValue)                            --Ex: -0.2345 -> 0.2345
    set @sXs = Convert(varchar(50), @iValue)
    set @sXs = convert(varchar(50), convert(int, right(@sXs, len(@sXs)-2))) --小數
 
    if @sXs = '0'
    begin
      return @sZs --純整數
    end
    else
    begin

      set @iFz = convert(int, @sXs)   --分子
      set @iFm = power(10, len(@sXs)) --分母 
      set @iZdgys = (select dbo.fn_DftOf('{"type":"getZDGYS", "num1":"'+convert(varchar(10), @iFm)+'", "num2":"'+convert(varchar(10), @iFz)+'"}')) --求最大公約數 
      set @sResult = convert(varchar(50),(@iFz/@iZdgys))+'/'+convert(varchar(50),(@iFm/@iZdgys))


      if @sZs='0'
        set @sZs = ''
      else
        set @sZs = @sZs +'-' --整數與分數的連接符號

      if @sFh='-'
        set @sResult = '-(' + @sZs + @sResult + ')' --Ex: -(3-1/2)
      else
        set @sResult = @sZs + @sResult              --Ex:   3-1/2
    end
   
    return @sResult
  end
  ------------------------------------------------------------------------------------------------------------------------
  ------------------------------------------------------------------------------------------------------------------------
  --取最大公約數
  ------------------------------------------------------------------------------------------------------------------------
  ------------------------------------------------------------------------------------------------------------------------
  else if @type='getZDGYS'
  begin
    --select dbo.fn_DftOf('{"type":"getZDGYS", "num1":"10", "num2":"5"}') --求最大公約數 
    --select dbo.fn_DftOf('{"type":"getZDGYS", "num1":"100", "num2":"75"}') --求最大公約數 

    --輾轉相除法
    set @iNum1=convert(int, @num1)
    set @iNum2=convert(int, @num2)
    set @iYs=@iNum1 - @iNum2 * convert(int, @iNum1/@iNum2)  --MOD

    while @iYs <> 0
    begin
      set @iNum1 = @iNum2
      set @iNum2 = @iYs 
      set @iYs   = @iNum1 - @iNum2 * convert(int, @iNum1/@iNum2) --MOD
    end

    set @sResult = convert(varchar(50), @iNum2)

    return @sResult
  end
 
  return '' 
end
 



改編至 http://blog.csdn.net/yzsind/article/details/2604798

SQL 常用數值函式

-------------------------------------------------------------------------------------------------------
--數字
-------------------------------------------------------------------------------------------------------
--取整數 select 
select cast(12.345  as int)
--取小數
select   12.345 - cast(12.345  as int)
-------------------------------------------------------------------------------------------------------
--字串
-------------------------------------------------------------------------------------------------------
--字串前面補零   
select REPLICATE('0',10-LEN(Field)) + RTRIM(CAST(Field AS CHAR)) FROM Table
-------------------------------------------------------------------------------------------------------
--日期
-------------------------------------------------------------------------------------------------------
--年初
select DATEADD(yy, datediff(yy, 0,  getdate()), 0) as 年初
--年底
select DATEADD(yy, datediff(yy, 0,  getdate())+1, -1) as 年底
--月初
select DATEADD(mm, DATEDIFF(mm, '', getdate()), '') as 月初
--月底
select DATEADD(day, -1, DATEADD(mm, DATEDIFF(mm, '', getdate())+1, '')) as 月底
--上月初
select DATEADD(mm, -1, DATEADD(mm, DATEDIFF(mm, '', getdate()), '')) as 上月初
--上月底
select DATEADD(day, -1, DATEADD(mm, DATEDIFF(mm, '', getdate()), '')) as 上月底
--前二個月初
select DATEADD(mm, DATEDIFF(mm, '', getdate())-2, '') as 前二個月初   
--前二個月底           
select DATEADD(day, -1, DATEADD(mm, DATEDIFF(mm, '', getdate())-1, '')) as 前二個月底 
--下個月初
select DATEADD(mm, DATEDIFF(mm, '', getdate())+1, '') as 下個月初 
--下個月底           
select DATEADD(day, -1, DATEADD(mm, DATEDIFF(mm, '', getdate())+2, '')) as 下個月底
--本週起始日_週日起算
select Getdate()-DATEPART(dw, GETDATE()-7)+1 as 本週起始日_週日起算
--本週末_週六
select Getdate()-DATEPART(dw, GETDATE()-7)+7 as 本週末_週六
--本週起始日_週一起算
select Getdate()-DATEPART(dw, GETDATE())+2 as 本週起始日_週一起算
--本週末_週日
select Getdate()-DATEPART(dw, GETDATE())+8 as 本週末_週日
--上週起始日_週日起算
select Getdate()-7-DATEPART(dw, GETDATE()-7)+1 as 上週起始日_週日起算
--上週末(週六)
select Getdate()-7-DATEPART(dw, GETDATE()-7)+7 as 上週末_週六
--上週起始日_週一起算
select Getdate()-7-DATEPART(dw, GETDATE()-7)+2 as 上週起始日_週一起算
--上週末_週日
select Getdate()-7-DATEPART(dw, GETDATE()-7)+8 as 上週末_週日

MSSQL RowID By Group

Select ROW_NUMBER() OVER(PARTITION BY [Field1] ORDER BY [Field1] DESC) AS RowID, *
from [Table]

SQL 找不到要更新的資料列。最後讀取的值已被變更

Ex:

  SQL Server

    Close;
    SQL.Text := 'SET NOCOUNT OFF';
    ExecSQL;

    UpdateBatch();

    Close;
    SQL.Text := 'SET NOCOUNT ON';
    ExecSQL;

SQL 常用日期函式

本週星期一
SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0)

第一個星期一
select DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,6-datepart(day,getdate()),getdate())), 0)

月初
SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)

月底
SELECT DATEADD(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0))   

上個月底
SELECT DATEADD(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0))

年初
SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)

年底
SELECT DATEADD(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))

去年底
SELECT DATEADD(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0))

2017年9月7日 星期四

搜尋資料庫主機

procedure TForm1.Button1Click(Sender: TObject);
var
    i: integer;
    SQLServer: Variant;
    ServerList: Variant;
    Resultvalue: boolean;
begin
    Resultvalue := False;
    memo1.Lines.Clear;
    try
    SQLServer := CreateOleObject('SQLDMO.Application');
    ServerList := SQLServer.ListAvailableSQLServers;
    for i := 1 to Serverlist.Count do
        memo1.Lines.Add (Serverlist.item(i));
    Resultvalue := True;
    Finally
    SQLServer := NULL;
    ServerList := NULL;
    end;
end;