---
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
```
示範原始資料

取得資料

### 全文檢索
先建立`FULLTEXT Index`

`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
```

### 轉型別
#### 方法一
```sql=
CAST( expression AS data_type )
```
#### 方法二
```sql=
CONVERT( data_type , expression )
```
說明:data_type是指欲轉換成的資料型態
### 去掉前幾位
```sql=
RIGHT(欄位,LEN(欄位)-幾位)
```

### 去掉0
左邊
```sql=
SUBSTRING(欄位,PATINDEX('%[^0 ]%', 欄位 + ' '), LEN(欄位))
```

右邊
```sql=
REVERSE(SUBSTRING(REVERSE(V),PATINDEX('%[1-9]%',REVERSE(V)),LEN(V)))
```

### 左邊補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 資料表
```

### 排序函數 [ROW_NUMBER](https://ithelp.ithome.com.tw/articles/10225653) 取序號
> 例
```sql=
SELECT ROW_NUMBER() OVER(ORDER BY 欄位 ASC,欄位 DESC)
AS COMPUTE_1
FROM 資料表
```

### SUM
> 例 1
```sql=
ISNULL((SELECT SUM(B.目標欄位)
FROM 資料表 B
WHERE B.欄位1 = M.欄位1
AND B.欄位2 = M.欄位2 ),0)
```

> 例 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
```

### 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 |

### Stored Procedure
多一行合計 [RP_FNH0460R](https://hackmd.io/Rw5TaiLKT4yvIv2rQGBX6w)
```sql=
不要 GROUP BY 就可以
```

### [複製](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 主檔加入參數方式

### 資料遮罩
[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
```