###### tags: `D-CODE` # SQL --- :::info [ Isolation Levels](https://totoroliu.medium.com/%E8%B3%87%E6%96%99%E5%BA%AB-isolation-levels-c587d3103ba4) * SQL null無法比對運算,因此要用ISNULL把值改為空白後方能比對 ::: --- :::spoiler 常用 ``` RIGHT('00000000' + CAST(t.pat_no AS varchar), 8) (CAST(FORMAT(DATEADD(YEAR,-1911, CAST(a.enc_time AS date)), N'yyyMM') AS int) CAST(STR(SUBSTRING(a.his_opd_no, 1, 7) + 19110000) AS date) AS ODR_RO_DATE ``` ::: --- :::spoiler ROWS BETWEEN 以「視窗框架」:ROWS BETWEEN 2 PRECEDING AND CURRENT ROW為例,這是指定一個視窗,此視窗是從目前資料列前面的第二個資料列作為起始點,而以目前資料列作為結束點,此視窗函數可以操作的資料列視窗大小為三筆資料列。 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:此為預設值,這是指定一個視窗,此視窗從資料分割的第一個資料列作為起始點,而以資料分割的目前資料列作為結束點。 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING:這是指定一個視窗,此視窗從資料分割的目前資料列作為起始點,而以資料分割的最後一個資料列作為結束點。 ROWS BETWEEN 2 FOLLOWING AND 10 FOLLOWING:這是指定一個視窗,此視窗是從目前資料列後面的第二個資料列作為起始點,而以目前資料列後面的第十個資料列作為結束點。 ::: --- :::spoiler UNPIVOT ![](https://i.imgur.com/wMM1OMC.png) ``` SELECT * FROM ( Select GroupCol,col2,col3,col4........ FROM SourceTable -- 3.1 欲進行反轉置的資料來源 ) AS p UNPIVOT ( ValueCol FOR unPivotCol IN (col2,col3,col4.........) -- ㄧ定要不包含群組欄位 -- 3.2 ValueCol 和 unPivotCol 為使用者自行命名的欄位名稱 -- 3.3 ValueCol 的資料為資料列(Row)資料轉成資料行(Column)資料(非群組欄位轉為ValueCol) -- 3.4 unPivotCol 的資料為 col2欄位資料、col3欄位資料、col4欄位資料........ ) AS pv SELECT * FROM ( Select Employee,事假,病假,公假,陪產假 FROM #UNPIVOT ) AS p UNPIVOT ( Hours FOR Kind IN (事假,病假,公假,陪產假) ) AS pv -- OR SELECT * FROM #UNPIVOT AS p UNPIVOT ( Hours FOR Kind IN (事假,病假,公假,陪產假) ) AS pv -- AAAAA的陪產假為NULL,UNPIVOT後,AAAAA的假別就不會有陪產假 ``` ::: --- :::spoiler TRY CATCH BEGIN TRY BEGIN TRANSACTION IF @@ERROR = 0 --沒問題就確認交易完成,資料也會在這時候確認新增和修改 COMMIT TRANSACTION ELSE --若是有問題就取消交易,讓資料不被這三段T-SQL所影響 ROLLBACK TRANSACTION END TRY BEGIN CATCH END CATCH ::: --- :::spoiler ALTER alter TABLE [dbo].[tableName] ALTER COLUMN [FiledName] [nvarchar](40) ::: --- :::spoiler 查詢主KEY select From INFORMATION_SCHEMA.KEY_COLUMN_USAGE ::: --- :::spoiler 欄位合併 SELECT ProductId, ( SELECT ',' + PO_A.[Owner] FROM ProductOwner PO_A WHERE PO_A.ProductId = PO_B.ProductId FOR XML PATH('') ) AS Owners FROM ProductOwner PO_B ::: --- :::spoiler 找出重覆資料 SELECT * FROM table GROUP BY id HAVING count(*)>1 ::: --- :::spoiler PATINDEX SELECT * FROM TBDEP a ORDER BY CASE WHEN PATINDEX( '%(舊)%' ,depname) > 0 THEN depno ELSE '' END ::: --- :::spoiler CTE 日期 WITH mycte AS ( SELECT CAST('1900-01-01' AS DATETIME) DateValue UNION ALL SELECT DateValue + 1 FROM mycte WHERE DateValue + 1 < '2050-12-31' ) SELECT DateValue FROM mycte OPTION (MAXRECURSION 0) ::: --- :::spoiler PIVOT DECLARE @Year nvarchar(40) = '106'; DECLARE @Semester nvarchar(40) ='1'; DECLARE @DayfgID nvarchar(5) ='1'; --select isnull(a.Vaild,0) Vaild,COUNT(1) Amt --from tVoteTeCategoryUsers a --join tVoteTeAnswers b --on a.TeCategoryID=b.TeCategoryID --and a.StudentID=b.StudentID --join tVoteTeCategory c --on a.TeCategoryID=c.TeCategoryID --where c.ACADYear = @Year and c.Semester = @Semester --group by isnull(a.Vaild,0) SELECT [0] inVaild,[1] Vaild FROM ( select isnull(a.Vaild,0) Vaild from tVoteTeCategoryUsers a join tVoteTeAnswers b on a.TeCategoryID=b.TeCategoryID and a.StudentID=b.StudentID join tVoteTeCategory c on a.TeCategoryID=c.TeCategoryID where c.ACADYear = @Year and c.Semester = @Semester ) as GroupTable PIVOT ( count(Vaild) FOR Vaild IN ([0], [1]) ) AS PivotTable --https://blog.xuite.net/f8789/DCLoveEP/30800686-SQL+-+%E4%BD%BF%E7%94%A8+PIVOT SELECT * FROM ( SELECT a.fundsno3, --學校配合款 a.years, SUM(a.smoney) AS smoney, SUM(a.appmoney) AS appmoney_核定前金額, --核定前金額, ( SELECT SUM(smoney) FROM ITSCHOOLDEPBUDGET WHERE fundsno3 = a.fundsno3 AND years = '109' ) AS AA, ( SELECT SUM(smoney) FROM ITSCHOOLDEPBUDGET WHERE fundsno3 = a.fundsno3 AND years = '110' ) AS BB FROM ITSCHOOLDEPBUDGET a --預算明細檔 INNER JOIN TBREFCODE b --系統代碼檔 ON b.refcodeno = 'budfunds' AND b.refcode = a.fundsno3 INNER JOIN ( SELECT depno, CASE WHEN ISNULL(upper,'') = '0000' THEN depno ELSE upper END AS upper FROM TBDEP --學校部門表 ) c ON c.depno = a.depno WHERE LEFT(a.budsubno,1) = '4' AND --預算科目 LEFT(a.fundsno3,1) <> 'P' AND --學校配合款 a.years BETWEEN '109' AND '110' AND a.fundsno3 = '419200' GROUP BY b.upper,a.fundsno3,b.refname,c.upper,a.years --ORDER BY b.upper,a.fundsno3,b.refname,c.upper,a.years ) t PIVOT ( -- 設定彙總欄位及方式 MAX(years) -- 設定轉置欄位,並指定轉置欄位中需彙總的條件值作為新欄位 FOR years IN ( [109], [110]) ) p; ::: --- :::spoiler STRING_SPLIT SELECT b.inno, b.money,b.indate, * FROM TBPENNY_DETIAL a --收款收據-收款收據明細資料表 LEFT JOIN TBINDETAIL b --收入相關-收入明細資料表 ON a.doc_id IN ( SELECT value FROM STRING_SPLIT(b.pennyautoid, ',') ) WHERE a.pennyno = '111600-11002220002' 2014版寫法 SELECT Split.a.value('.', 'NVARCHAR(MAX)') AS Value FROM ( SELECT CAST ('<M>' + REPLACE(CAST (nid_rec AS nvarchar(MAX)) , ',', '</M><M>') + '</M>' AS XML) AS Data FROM hg_mnid WHERE nid_id = '06BC' AND nid_code IN ('011')   ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a) ::: --- :::spoiler 一對多筆資料 ``` WITH CTE_ITFORM AS ( SELECT formno, wruserno, wrusername, depno, ( SELECT depname FROM TBDEP WHERE TBDEP.depno = ITFORM.depno ) AS depname, CASE WHEN isbt = 'purchase' THEN '請購' WHEN isbt = 'normal' THEN '借支' END AS isbt, casename, ( SELECT TOP 1 budno + ',' + ( SELECT budname FROM ITSCHOOLDEPBUDGET WHERE budno = ITFORM_DETIAL.budno ) FROM ITFORM_DETIAL WHERE formno = ITFORM.formno ) AS budno, ( SELECT SUM(bmoney) FROM ITFORM_DETIAL WHERE ITFORM_DETIAL.formno = ITFORM.formno ) AS bmoney FROM ITFORM WHERE kind = '1' AND status >= 1 AND status < 9 AND EXISTS ( SELECT 1 FROM ITFORM_DETIAL INNER JOIN ITSCHOOLDEPBUDGET ON ITSCHOOLDEPBUDGET.budno = ITFORM_DETIAL.budno INNER JOIN ITSCHOOLDEP ON ITSCHOOLDEP.planno = ITSCHOOLDEPBUDGET.planno WHERE ( ITSCHOOLDEP.edate = CONVERT(VARCHAR,CAST(YEAR(GETDATE()) AS NVARCHAR) + '-06' + '-01',111) OR ITSCHOOLDEP.edate = CONVERT(VARCHAR,CAST(YEAR(GETDATE()) AS NVARCHAR) + '-12' + '-01',111) ) ) ), CET_WRUSERNO AS ( SELECT wruserno FROM ITFORM WHERE kind = '1' AND status >= 1 AND status < 9 AND EXISTS ( SELECT 1 FROM ITFORM_DETIAL INNER JOIN ITSCHOOLDEPBUDGET ON ITSCHOOLDEPBUDGET.budno = ITFORM_DETIAL.budno INNER JOIN ITSCHOOLDEP ON ITSCHOOLDEP.planno = ITSCHOOLDEPBUDGET.planno WHERE ( ITSCHOOLDEP.edate = CONVERT(VARCHAR,CAST(YEAR(GETDATE()) AS NVARCHAR) + '-06' + '-01',111) OR ITSCHOOLDEP.edate = CONVERT(VARCHAR,CAST(YEAR(GETDATE()) AS NVARCHAR) + '-12' + '-01',111) ) ) GROUP BY wruserno ) SELECT wruserno, ( SELECT b.formno + ':' + b.isbt + ':' + b.casename + ':' + b.budno + ':' + CAST ( b.bmoney AS Varchar ) + ';' FROM CTE_ITFORM b WHERE b.wruserno = a.wruserno FOR XML PATH('') ) AS formno FROM CET_WRUSERNO a UNION SELECT 'ACC' AS wruserno, ( SELECT b.formno + ':' + b.isbt + ':' + b.casename + ':' + b.budno + ':' + CAST ( b.bmoney AS Varchar ) + ':' + b.depname + ':' + b.wrusername + ';' FROM CTE_ITFORM b FOR XML PATH('') ) AS formno FROM CTE_ITFORM b ``` ::: --- :::spoiler 抓小數點後幾位數 SELECT MONEY,* FROM ITFORM_BUYACT WHERE PARSENAME(MONEY, 1) > 0 ::: --- :::spoiler 往前抓到有資料為止 select bankno,sdate,remark from TBINOUTDAY where sdate = ( SELECT TOP 1 h.sdate FROM ( SELECT a.sdate AS sdate FROM TBINOUTDAY a WHERE a.remark is not null AND a.sdate <= '2020-11-30' GROUP BY a.sdate ) h ORDER BY h.sdate DESC ) order by bankno DESC ::: --- :::spoiler 指標 CREATE TABLE [#Table_name] ( COLUMN_NAME nvarchar(100) ) INSERT INTO #Table_name (COLUMN_NAME) SELECT a.COLUMN_NAME FROM ( SELECT b.COLUMN_NAME FROM INFORMATION_SCHEMA.TABLES a LEFT JOIN INFORMATION_SCHEMA.COLUMNS b ON a.TABLE_NAME=b.TABLE_NAME WHERE TABLE_TYPE='BASE TABLE' AND a.Table_name IN ( 'tSteBuy' ) --輸入想要的表格名稱 ) a --1.不回傳受影響的資料列(可節省網路傳輸),通常如果沒有要看的話,會寫不回傳,又能節省網路傳輸) --2.雖然不回傳,但不影響@@ROWCOUNT,所以如果想知道影響的資料列,還是能用@@ROWCOUNT來讀取 SET NOCOUNT ON DECLARE @COLUMN_NAME NVARCHAR(MAX) --宣告資料指標內容 DECLARE MYCURSOR CURSOR FOR ( SELECT COLUMN_NAME FROM #Table_name ) --開啟資料指標 OPEN MYCURSOR --取得資料指標內第一筆資料 FETCH NEXT FROM MYCURSOR INTO @COLUMN_NAME --當成功取的資料進入處理程序 WHILE @@FETCH_STATUS = 0 BEGIN ----資料處理區---- -- 找出哪些欄位比較常用(超過原始資料筆數的70%) DECLARE @query NVARCHAR(MAX) = N' SELECT ''' + @COLUMN_NAME + ''', '+ 'COUNT(' + @COLUMN_NAME + ') FROM tSteBuy WHERE ISNULL(CONVERT(varchar,' + @COLUMN_NAME + '),' + '''' + '''' + ') <> '''' HAVING COUNT(' + @COLUMN_NAME + ') > (SELECT COUNT(formno) FROM tSteBuy) * 0.7 ' --SELECT @query EXECUTE sp_executesql @query --SELECT @COLUMN_NAME , @COLUMN_NAME --FROM ITFORM --WHERE ISNULL(@COLUMN_NAME, '') <> '' ------------------ --取得下一筆資料 FETCH NEXT FROM MYCURSOR INTO @COLUMN_NAME END --關閉資料指標 CLOSE MYCURSOR --移除資料指標參考 DEALLOCATE MYCURSOR --移除暫存表 DROP TABLE #Table_name ::: --- :::spoiler usp_Del CREATE PROCEDURE usp_Del_Products @ProdctID int AS BEGIN SET NOCOUNT ON; DECLARE @count int SET @count = (SELECT count(*) FROM [dbo].[Products] WHERE ProdctID = @ProdctID) IF @count > 0 BEGIN BEGIN TRY BEGIN TRANSACTION DELETE FROM Products WHERE ProdctID = @ProdctID; IF @@ERROR = 0 BEGIN commit transaction;--確認交易 END ELSE BEGIN rollback transaction;--回復交易 END END TRY BEGIN CATCH --DB查詢用 SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage, ERROR_LINE() AS ErrorLine, ERROR_PROCEDURE() AS ErrorProcedure, ERROR_SEVERITY() AS ErrorSeverity, ERROR_STATE() AS ErrorState --系統拋回訊息用 DECLARE @ErrorMessage As VARCHAR(1000) = CHAR(10)+'錯誤代碼:' +CAST(ERROR_NUMBER() AS VARCHAR) +CHAR(10)+'錯誤訊息:'+ ERROR_MESSAGE() +CHAR(10)+'錯誤行號:'+ CAST(ERROR_LINE() AS VARCHAR) +CHAR(10)+'錯誤程序名稱:'+ ISNULL(ERROR_PROCEDURE(),'') DECLARE @ErrorSeverity As Numeric = ERROR_SEVERITY() DECLARE @ErrorState As Numeric = ERROR_STATE() RAISERROR( @ErrorMessage, @ErrorSeverity, @ErrorState);--回傳錯誤資訊 END CATCH END END ::: --- :::spoiler MERGE MERGE 語法是 SQL Server 2008 的新語法,可根據與來源資料表聯結的結果,在目標資料表上執行插入、更新或刪除作業。以下就來以範例的方式來實作... Code: --建立新資料表名為 大倉庫 Create Table 大倉庫 ( 品名 nvarchar(50), 庫存量 integer ); --新增大倉庫資料表資料 Insert into 大倉庫 Values('中文書', 10),('英文書', 5),('法文書', 1); --建立新資料表名為 進退貨倉庫 Create Table 進退貨倉庫 ( 品名 nvarchar(50), 進退貨量 integer ); --新增進退貨倉庫資料表資料 Insert into 進退貨倉庫 Values('中文書', 5),('英文書', -5),('日文書', 6); --查詢 大倉庫 與 進退貨倉庫 兩資料表的資料 Select * From dbo.大倉庫 Select * From dbo.進退貨倉庫 --將兩張表 MERGE --當兩張表有資料 MERGE 時,且 庫存量 加上 進退貨量 等於零時,則刪除資料 --當兩張表有資料 MERGE 時,將 庫存量 加上 進退貨量 更新到 庫存量 --當兩張表沒有資料 MERGE 時,將 進退貨倉庫 的資料新增到 大倉庫 中 MERGE INTO 大倉庫 USING 進退貨倉庫 ON 大倉庫.品名 = 進退貨倉庫.品名 WHEN MATCHED AND (大倉庫.庫存量 + 進退貨倉庫.進退貨量 = 0) THEN DELETE WHEN MATCHED THEN UPDATE SET 大倉庫.庫存量 = 大倉庫.庫存量 + 進退貨倉庫.進退貨量 WHEN NOT MATCHED THEN INSERT VALUES(進退貨倉庫.品名, 進退貨倉庫.進退貨量); --查詢 MERGE 後的結果 Select * From dbo.大倉庫 Select * From dbo.進退貨倉庫 ::: --- :::spoiler ASP.NET BeginTransaction ``` using (ACAD_NPUSTEntities pubkind = new ACAD_NPUSTEntities()) { using (ACAD_NPUSTEntities pubcod = new ACAD_NPUSTEntities()) { using (var pubkindTs = pubkind.Database.BeginTransaction()) { using (var pubcodTs = pubcod.Database.BeginTransaction()) { pubkind.pubkind.Add(m); pubkind.Configuration.ValidateOnSaveEnabled = false; //pubkind.SaveChanges(); for (int i = 0; i < n; i++) { var r = new pubcod(); //r.codekind = m.codekind; //r.code = Request["dt_code[]"].Split(',')[i]; //r.codsc = Request["dt_codsc[]"].Split(',')[i]; //r.ecodsc = Request["dt_ecodsc[]"].Split(',')[i]; //r.status = Request["dt_status[]"].Split(',')[i]; //r.updat_date = DateTime.Now; //r.user_id = getUserAuthInfo().id ?? null; //r.updat_time = m.updat_date.Value.ToString("HHmmss"); pubcod.pubcod.Add(r); //pubcod.SaveChanges(); } try { pubkind.SaveChanges(); pubcod.SaveChanges(); pubkindTs.Commit(); pubcodTs.Commit(); } catch (Exception) { pubkindTs.Rollback(); pubcodTs.Rollback(); TempData["CommMsg"] = "新增作業失敗 !"; return View(); } } } } } } ``` ::: --- :::spoiler TRANSACTION ``` DECLARE @count int SET @count = (SELECT count(*) FROM [dbo].[Products] WHERE ProdctID = @ProdctID) IF @count > 0 BEGIN BEGIN TRY BEGIN TRANSACTION DELETE FROM Products WHERE ProdctID = @ProdctID; IF @@ERROR = 0 BEGIN commit transaction;--確認交易 END ELSE BEGIN rollback transaction;--回復交易 END END TRY BEGIN CATCH --DB查詢用 SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage, ERROR_LINE() AS ErrorLine, ERROR_PROCEDURE() AS ErrorProcedure, ERROR_SEVERITY() AS ErrorSeverity, ERROR_STATE() AS ErrorState --系統拋回訊息用 DECLARE @ErrorMessage As VARCHAR(1000) = CHAR(10)+'錯誤代碼:' +CAST(ERROR_NUMBER() AS VARCHAR) +CHAR(10)+'錯誤訊息:'+ ERROR_MESSAGE() +CHAR(10)+'錯誤行號:'+ CAST(ERROR_LINE() AS VARCHAR) +CHAR(10)+'錯誤程序名稱:'+ ISNULL(ERROR_PROCEDURE(),'') DECLARE @ErrorSeverity As Numeric = ERROR_SEVERITY() DECLARE @ErrorState As Numeric = ERROR_STATE() RAISERROR( @ErrorMessage, @ErrorSeverity, @ErrorState);--回傳錯誤資訊 END CATCH END ``` ::: --- :::spoiler STRING_AGG 資料集組成字串的串接功能 ```資料集組成字串的串接功能 SELECT STRING_AGG(name, ',') FROM F1Driver ``` ::: --- :::spoiler 流水號 ``` select RIGHT(REPLICATE('0', 6) + CAST(ISNULL(MAX(CAST(CourseNo AS INT)),0)+1 AS varchar) , 6) AS CourseNo ``` ::: --- :::spoiler SQL Function ``` USE [Test_NCYU_DEV] GO /****** Object: UserDefinedFunction [dbo].[getPubcod] Script Date: 2022/6/23 上午 08:36:18 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- 建立 FUNCTION /* 08:班級 */ ALTER FUNCTION [dbo].[getPubcod](@codekind varchar(5), @code varchar(5), @pattern varchar(1)) RETURNS varchar(1000) -- 500若不夠,請加大 BEGIN DECLARE @string varchar(1000) -- 500若不夠,請加大 SET @string = '' IF @pattern = '1' BEGIN SELECT @string = @string + code + '-' + codsc + ',' FROM pubcod WHERE codekind = @codekind AND code = @code END ELSE BEGIN SELECT @string = @string + codsc + ',' FROM pubcod WHERE codekind = @codekind AND code = @code END IF LEN(@string) > 1 BEGIN SET @string = LEFT(@string, LEN(@string) - 1 ) -- 把最後面的逗號後刪除 END RETURN @string END ``` ::: --- :::spoiler 暫存表 ``` ----增加索引 >> 已有執行 --USE [Test_NCYU_DEV] --GO --CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>] --ON [dbo].[selstch] ([syear],[sem]) --INCLUDE ([stuno],[deptno],[seqno],[cono],[seldomain],[credit]) -- 清除暫存表 IF object_id('tempdb..#crsopenf_CTE') IS NOT NULL DROP TABLE #crsopenf_CTE; --學生選課資料(暫存表) SELECT DISTINCT b.syear , b.sem , a.acadno, c.colno , a.deptno AS sut_deptno, a.secno , e.secnam, a.grade , a.clacod , a.stuno , d.cname , b.deptno , b.seqno , b.attdepno , b.att_y , b.att_cls , b.att_grou , f.seldomain , f.cono , f.credit , b.termnum , b.credit AS crs_credit, b.smn INTO #crsopenf_CTE FROM stufile a INNER JOIN selstch f ON a.stuno = f.stuno INNER JOIN crsopenf b ON f.syear = b.syear AND f.sem = b.sem AND f.deptno = b.deptno AND f.seqno = b.seqno INNER JOIN pubdep c ON a.deptno = c.deptno INNER JOIN sclperson d ON a.idno = d.idno INNER JOIN pubsec e ON a.deptno = e.deptno AND a.secno = e.secno WHERE b.actcd <> '1' AND b.domainno NOT IN ('0001', '0002', '0000') AND f.syear = '110' AND f.sem = '1' --AND a.stuno = '1100404' --上課時間 ;WITH crstime_CTE AS ( SELECT   crstime.syear, crstime.sem, clweek, bcl, ecl, crstime.deptno, crstime.seqno FROM crstime, #crsopenf_CTE WHERE crstime.syear = #crsopenf_CTE.syear   AND crstime.sem = #crsopenf_CTE.sem   AND crstime.deptno = #crsopenf_CTE.deptno AND crstime.seqno = #crsopenf_CTE.seqno ), -- 將上課時間拆成星期一到星期日,並將節次的資料整合在一格內 week_all AS ( SELECT DISTINCT ( SELECT DISTINCT b.bcl + '-' + b.ecl + ',' FROM crstime_CTE b WHERE a.syear = b.syear AND a.sem = b.sem AND a.deptno = b.deptno AND a.seqno = b.seqno AND a.clweek = b.clweek FOR XML PATH('') ) AS t_t, a.syear, a.sem, a.deptno, a.seqno, a.clweek FROM crstime_CTE a ) SELECT a.syear, a.sem, a.acadno, a.colno, a.sut_deptno, a.secno, a.secnam, a.grade, a.clacod, a.stuno, a.cname, a.deptno, a.seqno, a.attdepno, a.att_y, a.att_cls, a.att_grou, a.seldomain, a.cono, a.credit, a.termnum, a.crs_credit, a.smn, week_1.t_t AS t_t1, week_2.t_t AS t_t2, week_3.t_t AS t_t3, week_4.t_t AS t_t4, week_5.t_t AS t_t5, week_6.t_t AS t_t6, week_7.t_t AS t_t7 FROM #crsopenf_CTE a LEFT JOIN (SELECT * FROM week_all a WHERE a.clweek = 1) AS week_1 ON a.syear = week_1.syear AND a.sem = week_1.sem AND a.deptno = week_1.deptno AND a.seqno = week_1.seqno LEFT JOIN (SELECT * FROM week_all a WHERE a.clweek = 2) AS week_2 ON a.syear = week_2.syear AND a.sem = week_2.sem AND a.deptno = week_2.deptno AND a.seqno = week_2.seqno LEFT JOIN (SELECT * FROM week_all a WHERE a.clweek = 3) AS week_3 ON a.syear = week_3.syear AND a.sem = week_3.sem AND a.deptno = week_3.deptno AND a.seqno = week_3.seqno LEFT JOIN (SELECT * FROM week_all a WHERE a.clweek = 4) AS week_4 ON a.syear = week_4.syear AND a.sem = week_4.sem AND a.deptno = week_4.deptno AND a.seqno = week_4.seqno LEFT JOIN (SELECT * FROM week_all a WHERE a.clweek = 5) AS week_5 ON a.syear = week_5.syear AND a.sem = week_5.sem AND a.deptno = week_5.deptno AND a.seqno = week_5.seqno LEFT JOIN (SELECT * FROM week_all a WHERE a.clweek = 6) AS week_6 ON a.syear = week_6.syear AND a.sem = week_6.sem AND a.deptno = week_6.deptno AND a.seqno = week_6.seqno LEFT JOIN (SELECT * FROM week_all a WHERE a.clweek = 7) AS week_7 ON a.syear = week_7.syear AND a.sem = week_7.sem AND a.deptno = week_7.deptno AND a.seqno = week_7.seqno --WHERE a.syear = '110' -- AND a.sem = '1' -- AND a.deptno = '151' -- AND a.seqno = '0014' ``` ::: --- :::spoiler CUBE [CUBE](https://www.mssqltips.com/sqlservertip/6315/group-by-in-sql-server-with-cube-rollup-and-grouping-sets-examples/) ::: --- :::spoiler CTE + PIVOT ``` --查詢學生選課的教室及上課時間 --學生選課資料 WITH crsopenf_cte AS ( SELECT DISTINCT b.syear, b.sem, a.acadno, c.colno, a.deptno AS sut_deptno, a.secno, e.secnam, a.grade, a.clacod, a.stuno, d.cname, b.deptno, b.seqno, b.attdepno, b.att_y, b.att_cls, b.att_grou, f.seldomain, f.cono, f.credit, b.termnum, b.credit AS crs_credit, b.smn FROM stufile a, crsopenf b, pubdep c, sclperson d, selstch f, pubsec e WHERE a.deptno = e.deptno AND a.secno = e.secno AND a.deptno = c.deptno AND a.idno = d.idno AND a.stuno = f.stuno AND f.syear = b.syear AND f.sem = b.sem AND f.deptno = b.deptno AND f.seqno = b.seqno AND f.syear = '110' AND f.sem = '1' --AND a.stuno = '1100404' AND b.actcd <> '1' AND b.domainno NOT IN ('0001', '0002', '0000') ),--上課教室 class_room_cte AS ( SELECT crsbu.buna, crstime.roomno, crstime.syear, crstime.sem, crstime.deptno, crstime.seqno FROM crstime, crsbu WHERE crsbu.buno=crstime.buno AND crsbu.areano=crstime.areano ) --上課時間 , crstime_cte AS ( SELECT   crstime.syear, crstime.sem, clweek, bcl, ecl, crstime.deptno, crstime.seqno FROM crstime ) SELECT p.syear, p.sem, p.acadno, p.colno, p.sut_deptno, p.secno, p.secnam, p.grade, p.clacod, p.stuno, p.cname, p.deptno, p.seqno, p.attdepno, p.att_y, p.att_cls, p.att_grou, p.seldomain, p.cono, p.credit, p.smn, ( SELECT DISTINCT b.buna + '-' + roomno + ',' FROM class_room_cte b WHERE p.syear = b.syear AND p.sem = b.sem AND p.deptno = b.deptno AND p.seqno = b.seqno FOR XML PATH('') ) AS room, --教室 p.[1], --星期1 p.[2], --星期2 p.[3], --星期3 p.[4], --星期4 p.[5], --星期5 p.[6], --星期6 p.[7] --星期7 FROM ( SELECT a.syear, a.sem, a.acadno, a.colno, a.sut_deptno, a.secno, a.secnam, a.grade, a.clacod, a.stuno, a.cname, a.deptno, a.seqno, a.attdepno, a.att_y, a.att_cls, a.att_grou, a.seldomain, a.cono, a.credit, a.termnum, a.crs_credit, a.smn, x.clweek AS col, x.t_t AS value FROM crsopenf_cte a OUTER APPLY ( SELECT b.clweek, --星期 ( SELECT DISTINCT c.bcl + '-' + c.ecl + ',' FROM crstime_cte c WHERE b.syear = c.syear AND b.sem = c.sem AND b.deptno = c.deptno AND b.seqno = c.seqno AND b.clweek = c.clweek FOR XML PATH('') ) t_t --上課時間 FROM crstime_cte b WHERE a.syear = b.syear AND a.sem = b.sem --AND a.stuno = b.stuno AND a.deptno = b.deptno AND a.seqno = b.seqno ) x ) t PIVOT ( MAX([value]) FOR [col] IN ("1", "2", "3", "4", "5", "6", "7") ) p --ORDER BY p.stuno, -- p.deptno, -- p.seqno, -- p.cono ``` ::: --- :::spoiler REPLICATE SELECT *, REPLICATE('1', h.level) FROM questionnaires_cte h ::: --- :::spoiler 判斷table或暫存表是否存在 ```   IF EXISTS( SELECT * FROM sys.tables WHERE name = 'Ins_opd_check' ) BEGIN DROP TABLE Ins_opd_check END IF object_id('tempdb..#chek_die') IS NOT NULL BEGIN DROP TABLE #chek_die END ``` ::: --- :::spoiler 日期轉換 ``` CAST(STR('1050101' + 19110000) AS DATETIME) RIGHT('00000000' + CAST(t.pat_no AS varchar), 8) (CAST(FORMAT(DATEADD(YEAR,-1911, CAST(a.enc_time AS date)), N'yyyMM') AS int))  CAST(STR(SUBSTRING(a.his_opd_no, 1, 7) + 19110000) AS date) AS ODR_RO_DATE ``` ::: --- :::spoiler 欄位描述 ``` SELECT * FROM ( SELECT a.TABLE_NAME, a.COLUMN_NAME, ( SELECT tc.CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcu ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME AND tc.TABLE_SCHEMA = kcu.TABLE_SCHEMA AND tc.TABLE_NAME = kcu.TABLE_NAME WHERE tc.TABLE_NAME = a.TABLE_NAME AND kcu.COLUMN_NAME = a.COLUMN_NAME ) AS CONSTRAINT_TYPE, ( SELECT value FROM fn_listextendedproperty (NULL, 'schema', a.TABLE_SCHEMA, 'table', a.TABLE_NAME, 'column', default) WHERE name='MS_Description' and objtype='COLUMN' AND objname Collate Chinese_Taiwan_Stroke_CI_AS = a.COLUMN_NAME ) AS 欄位描述, a.DATA_TYPE, a.IS_NULLABLE FROM ( SELECT a.TABLE_NAME, b.COLUMN_NAME, a.TABLE_SCHEMA, b.DATA_TYPE, b.IS_NULLABLE, b.CHARACTER_SET_SCHEMA FROM INFORMATION_SCHEMA.TABLES a LEFT JOIN INFORMATION_SCHEMA.COLUMNS b ON a.TABLE_NAME = b.TABLE_NAME --WHERE a.TABLE_NAME LIKE '%opd_enc%' -- AND b.COLUMN_NAME = 'enc_json'   ) a ) t WHERE     --t.TABLE_NAME LIKE '%D%'  --AND t.COLUMN_NAME LIKE '%aplx_nor_a_no%'   --AND  --CAST(t.欄位描述 AS nvarchar(100)) LIKE '%序號%'   --SELECT * --FROM ho_micd ``` ::: --- :::spoiler split ``` WITH split AS (  SELECT * FROM ( SELECT Split.a.value('.', 'NVARCHAR(MAX)') AS Value FROM ( SELECT CAST ('<M>' + REPLACE(CAST (nid_rec AS nvarchar(MAX)) , ',', '</M><M>') + '</M>' AS XML) AS Data FROM hg_mnid WHERE nid_id = '9301' AND nid_code IN ('0')   ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a) ) T WHERE T.Value LIKE '%糖尿病已進入第二階段管理照護不得再申報第一階段管理照護費%' ) SELECT * FROM ( SELECT Split.a.value('.', 'NVARCHAR(MAX)') AS Value FROM ( SELECT CAST ('<M>' + REPLACE(CAST (Value AS nvarchar(MAX)) , ':', '</M><M>') + '</M>' AS XML) AS Data FROM split     ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a) ) T ``` ::: --- :::spoiler SQL TO JSON ``` SELECT '' AS Id,  -- A.No AS No, JSON_QUERY( '[' + STUFF(( SELECT ',' + '"' + a.hwchd_cid + '"' FROM hw_mchd b WHERE a.hwchd_oid = b.hwchd_oid FOR XML PATH ('') ), 1, 1, '')  + ']' ) AS json FROM hw_mchd a FOR JSON AUTO ``` ::: ---