--- tags: 上班遇到問題 --- # SQL遇到問題 ## MY SQL ### 刪除表中重複項 ```sql= DELETE t1 FROM table_name t1 INNER JOIN table_name t2 WHERE t1.id > t2.id AND t1.relation_id = t2.relation_id AND t1.foo = t2.foo AND t1.bar = t2.bar; ``` ### 取得資料表中特定紀錄次數並group by ```sql= SELECT M.store_id, COUNT(CASE WHEN discountable_type LIKE '%GroupStoreDiscount%' THEN 1 ELSE NULL END) AS groupTotal, COUNT(CASE WHEN discountable_type LIKE '%DiscountTime%' THEN 1 ELSE NULL END) AS discountTotal, COUNT(*) AS count FROM log_discount_usage AS M GROUP BY M.store_id ``` 示範原始資料 ![](https://i.imgur.com/2LQ04eT.jpg) 取得資料 ![](https://i.imgur.com/p66N8pP.jpg) ### 全文檢索 先建立`FULLTEXT Index` ![](https://i.imgur.com/ysDsHeH.jpg) `MATCH` 是 MySQL 中用於執行全文搜索查詢的函數。括號中的列名列表是要搜索的列。 `AGAINST` 是用於指定要搜索的字符串的語句。 在這個例子中,`?` 是佔位符,用於在查詢中傳遞實際的搜索字符串。 在實際查詢中,你需要使用實際的搜索字符串替換 `?`。 如果在 `MATCH` 函數中有多個列被包括,`MySQL` 將會使用所有列的相關性來計算匹配度。當搜索多個列時,它還將嘗試為每個列返回一個相關度值。 ```sql= -- ? 為使用者查詢文字 select `id`, `store_id`, `category_id`, `hash`, `name`, `pictures`, `price`, `views`, `link` from `products` where MATCH ( name, subname, description ) AGAINST (? IN BOOLEAN MODE) ``` #### 全文搜索 vs. 模糊查詢 全文搜索和模糊查詢是兩種不同的查詢方法,它們有以下區別: 1. 匹配方式不同:全文搜索是基於自然語言的匹配,它可以找到與搜索查詢詞語的語義相關的匹配項,而模糊查詢則是基於字符匹配的,它只能找到與搜索查詢詞語相似的匹配項。 1. 精度不同:全文搜索的匹配精度通常更高,因為它可以理解查詢語句中的語義,同時可以將不同的語義元素分配不同的權重。模糊查詢的匹配精度通常較低,因為它只是基於字符匹配,可能會返回一些不相關的匹配項。 1. 性能差異:全文搜索的查詢需要在數據庫中創建全文索引,以便加速查詢,而模糊查詢則可以在任何列上執行。全文搜索查詢通常比模糊查詢要快得多,因為它可以利用索引來快速找到匹配項。 總之,全文搜索和模糊查詢都有自己的優缺點,應該根據實際需求和數據特點選擇合適的查詢方法。如果需要更精確的匹配和更好的查詢性能,則全文搜索可能是更好的選擇。如果需要在任何列上執行搜索,則可以使用模糊查詢。 ## MSSQL ### 將某資料最後一位去掉 ```sql= SUBSTRING(欄位,1,LEN(欄位) - 1) ``` > 例 ```sql= SELECT TOP (2) SUBSTRING(FIVCHTI_CODE,1,LEN(FIVCHTI_CODE) - 1) A, LEN(FIVCHTI_CODE) B,FIVCHTI_CODE FROM FNFIVCHTI ``` ![](https://i.imgur.com/3ePeH8k.png) ### 轉型別 #### 方法一 ```sql= CAST( expression AS data_type ) ``` #### 方法二 ```sql= CONVERT( data_type , expression ) ``` 說明:data_type是指欲轉換成的資料型態 ### 去掉前幾位 ```sql= RIGHT(欄位,LEN(欄位)-幾位) ``` ![](https://i.imgur.com/UDRJHdt.png) ### 去掉0 左邊 ```sql= SUBSTRING(欄位,PATINDEX('%[^0 ]%', 欄位 + ' '), LEN(欄位)) ``` ![](https://i.imgur.com/RH8HgRF.png) 右邊 ```sql= REVERSE(SUBSTRING(REVERSE(V),PATINDEX('%[1-9]%',REVERSE(V)),LEN(V))) ``` ![](https://i.imgur.com/jILVAao.png) ### 左邊補0 #### 方法一 ```sql= SELECT RIGHT('00000'+CAST(ID AS nvarchar(50)),5) FROM dbo.TableName --左邊補0,如 00001,00039 ``` #### 方法二 ```sql= SELECT REPLICATE('0',5-len('39'))+'39' --左邊補0, 如 00039 ``` ### 取資料表內最大日期+1 > 例 ```sql= select cast(convert(nvarchar(8),(DATEADD(day,1,convert(datetime,cast (MAX(欄位) + 19110000 as nvarchar(8))))),112)-19110000 as nvarchar(7)) as NEXTDATE from 資料表 ``` ![](https://i.imgur.com/gOob1yY.png) ### 排序函數 [ROW_NUMBER](https://ithelp.ithome.com.tw/articles/10225653) 取序號 > 例 ```sql= SELECT ROW_NUMBER() OVER(ORDER BY 欄位 ASC,欄位 DESC) AS COMPUTE_1 FROM 資料表 ``` ![](https://i.imgur.com/NVrruyx.png) ### SUM > 例 1 ```sql= ISNULL((SELECT SUM(B.目標欄位) FROM 資料表 B WHERE B.欄位1 = M.欄位1 AND B.欄位2 = M.欄位2 ),0) ``` ![](https://i.imgur.com/tZ2FlDN.png) > 例 2 (加撇節去小數) ```sql= PARSENAME(Convert(varchar,Convert(money ,ISNULL((SELECT SUM(B.FACTORS_REVOLUTION) FROM FNFFACTORS B WHERE B.FACTORS_YYMM = M.FACTORS_YYMM AND B.FACTORS_FUND = M.FACTORS_FUND ),0)),1),2) COMPUTE_2 ``` ![](https://i.imgur.com/hbF3MLR.png) ### UPDATE ```sql= UPDATE 資料表 SET 欲變更欄位 = '變更資料' WHERE 欄位 = 條件 ``` ### HAVING ```sql= SELECT "欄位1", SUM("欄位2") FROM "表格名" GROUP BY "欄位1" HAVING (函數條件); --範例 SELECT Store_Name, SUM(Sales) FROM Store_Information GROUP BY Store_Name HAVING SUM(Sales) > 1500; ``` | Store_Name | Sales | Txn_Date | | -------- | -------- | -------- | | Los Angeles | 1500 | 1999-01 | | San Diego | 250 | 1999-07 | | Los Angeles | 300 | 1999-11 | | San Diego | 700 | 1999-02 | ![](https://i.imgur.com/yZxA2m6.png) ### Stored Procedure 多一行合計 [RP_FNH0460R](https://hackmd.io/Rw5TaiLKT4yvIv2rQGBX6w) ```sql= 不要 GROUP BY 就可以 ``` ![](https://i.imgur.com/HNL8JNU.png) ### [複製](https://dotblogs.com.tw/mis0800/2014/02/09/143889)資料表 只複製結構,不複製資料 ```sql= SELECT * INTO 新TABLE FROM 舊TABLE WHERE 1=0 ``` ### SP定變數(前一年) ```sql= SET @LS_PYEAR = RIGHT('000'+CONVERT(NVARCHAR,(CONVERT(INT,@LS_YEAR)-1)),3) ``` ### SP欄位前面加空格(用level多少去判斷他要加多少空格) ```sql= REPLICATE(' ', CAST(LEVEL欄位 AS DECIMAL(10, 0))-1) + 名稱欄位 AS 取名 ``` ### SP階層合計GROUP BY [GROUP BY](https://www.1keydata.com/tw/sql/sqlgroupby.html) ### SP用 ```sql= DECLARE @FUND NVARCHAR(3), @YEAR NVARCHAR(3), @CASHNO NVARCHAR(8), @BDATE NVARCHAR(7), @EDATE NVARCHAR(7) SET @FUND = '001' SET @YEAR = '110' SET @CASHNO = '110102' SET @BDATE = '1100201' SET @EDATE = '1100228' ``` ### C# sql 主檔加入參數方式 ![](https://i.imgur.com/jG6CRPD.png) ### 資料遮罩 [GO](https://ithelp.ithome.com.tw/articles/10187606) 欄位遮罩方式(不同用法) ```sql= ALTER TABLE Customers ALTER COLUMN Birthday ADD MASKED WITH(FUNCTION='default()') ALTER TABLE Customers ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()') ALTER TABLE Customers ALTER COLUMN Name ADD MASKED WITH (FUNCTION = 'partial(1,"X",1)') ALTER TABLE Customers ALTER COLUMN CreditCard ADD MASKED WITH (FUNCTION = 'partial(4,"-xxxx-xxxx-",4)') ``` 建立測試帳號 ```sql= CREATE USER u WITHOUT LOGIN GRANT SELECT ON Customers TO u EXEC AS USER = 'u' SELECT * FROM Customers REVERT ```