- 判斷是否存在數(shù)據(jù)庫.表.字段
--判斷是否存在數(shù)據(jù)庫
SELECT * FROM sys.databases WHERE name = 'LeetCode'
--判斷是否存在表
SELECT * FROM sys.objects WHERE object_id=OBJECT_ID('LeetCode.dbo.Person');
--判斷是否存在字段
SELECT * FROM syscolumns WHERE name ='name' AND id=OBJECT_ID('Person')
- 創(chuàng)建數(shù)據(jù)庫
USE LeetCode;
GO
--delete the LeetCode database if it exists
IF EXISTS ( SELECT * FROM sys.databases WHERE name = 'LeetCode' )
BEGIN
DROP DATABASE LeetCode;--如果存在則刪除
CREATE DATABASE LeetCode;--重新創(chuàng)建數(shù)據(jù)庫
END;
- 創(chuàng)建表
--sqlServer版
USE LeetCode
--delete the Person datatable if it exists
IF EXISTS(SELECT * FROM sys.objects WHERE object_id=OBJECT_ID('LeetCode.dbo.Person'))
BEGIN
DROP TABLE Person
END
CREATE TABLE Person
(
id INT PRIMARY KEY IDENTITY(1,1),--主鍵,自增
name NVARCHAR(20) NOT NULL DEFAULT '',--默認值為''
email NVARCHAR(30) DEFAULT '' UNIQUE,--唯一
age INT NOT NULL DEFAULT 0 CHECK(age>0 AND age<200), --age只能時0-200之間
sex BIT NOT NULL DEFAULT 1
)
--mysql 版
CREATE TABLE `test`.`user_info` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` NVARCHAR(45) NULL,
`age` int(11) default NULL,
primary key(`id`),
Key `name_index`(`name`)
)engine=InnoDb default charset=utf8
刪除數(shù)據(jù)庫表
DROP TABLE table_name;
- 查看
use test;
show Databases;
show tables;
DROP TABLE table_name ; --刪除數(shù)據(jù)表
alter table test drop column testcol;-- 刪除表字段
alter table test add COLUMN new2 VARCHAR(20) NOT NULL;--新增字段
insert into user_info (name,age) values('a',20);--插入數(shù)據(jù)
CREATE INDEX index_name ON table_name (column_name);--創(chuàng)建索引
select * from user_info where name like '%wmin';--模糊查詢
select name,count(*) from user_info group by name;--分組查看name個數(shù)
select age ,count(age) as ageCount from user_info group by age;--給count另起名
select coalesce(name,'總數(shù)'),sum(age) as sumAge from user_info group by name with rollup;--如果名字為空,用總數(shù)代替,查詢age總年齡
select count(*) as count,name,age from user_info group by name,age;--查詢name和age都重復的個數(shù)
- GUID 唯一編碼
SELECT NEWID();
- REPLACE 字符串替換
REPLACE(NEWID(), '-', '')
- LOWER/UPPER 將字符串小/大寫
SELECT LOWER(NEWID()),UPPER(NEWID())
SELECT LOWER(REPLACE(NEWID(),'-','')),UPPER(REPLACE(NEWID(),'-',''))
- CAST 轉換類型
-- 獲取該月的啟示日期
DECLARE @year INT=2019;
DECLARE @month INT =4;
DECLARE @monthFirstDay DATETIME;
SET @monthFirstDay=CAST(@year AS NVARCHAR(4))+'-'+CAST(@month AS NVARCHAR(4))+'-01 00:00:00';
SELECT @monthFirstDay AS firstDay, DATEADD(Month,1,DATEADD(Day,-DAY(@monthFirstDay),@monthFirstDay)) AS lastDay;
- 對新建的表進行聯(lián)合查詢
SELECT * FROM dbo.aTable right JOIN dbo.bTable ON dbo.aTable.id = dbo.bTable.aid
- 對聯(lián)合查詢的結果新建視圖
CREATE VIEW Sys_ProjectDetailView as
SELECT * FROM dbo.aTable right JOIN dbo.bTable ON dbo.aTable.id = dbo.bTable.aid
- 批量加主健,過濾表已存在的主健
DECLARE @Sql NVARCHAR(max)=''
SELECT @Sql=@Sql+'ALTER TABLE ' + b.name + ' ADD Constraint PK_' + b.name
+ ' PRIMARY KEY (' + a.name + ');'
FROM sys.columns AS a
INNER JOIN sys.tables AS b ON b.object_id = a.object_id
WHERE a.is_identity = 1
AND NOT EXISTS ( SELECT 1
FROM sys.key_constraints
WHERE object_id = a.object_id
AND b.type = 'PK' );
EXEC(@Sql)
- 導入導出
- 在源數(shù)據(jù)庫生成表腳本,再導入數(shù)據(jù)就行了
- 打開SQL按F7,調出“對象資源管理器詳細信息”,在左側選中“存儲過程“或”Stored Procedures“目錄,到右側窗口,全選所有的要導入的sp,在選中的sp上鼠標右鍵。”生成存儲過程腳本為”->“Drop和Create到”->“File”,這樣就可以導出所有sp,將保存后的file到產(chǎn)品環(huán)境下運行一下就可以了。
- 關于創(chuàng)建索引
--直接創(chuàng)建索引(length表示使用名稱前1ength個字符)
CREATE INDEX index_name ON table_name(column_name(length))
--修改表結構的方式添加索引
ALTER TABLE table_name ADD INDEX index_name ON (column_name)
--創(chuàng)建表的時候同時創(chuàng)建索引
CREATE TABLE `table_name` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) NOT NULL ,
PRIMARY KEY (`id`),
INDEX index_name (title)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--刪除索引
DROP INDEX index_name ON table_name;
--建立復合索引
CREATE INDEX mytable_categoryid_userid ON mytable (category_id,user_id);
--注意命名時的習慣了嗎?使用"表名_字段1名_字段2名"的方式
SHOW INDEX FROM table_name;--顯示索引
- 更新數(shù)據(jù)
SET SQL_SAFE_UPDATES=0; //關閉安全模式
update user_info set name='liyue' where age = 15;
delete from user_info where name='h';
- 事務,用 BEGIN, ROLLBACK, COMMIT來實現(xiàn)
begin;--開啟事務
insert into user_info (name,age) value('www',11);--插入數(shù)據(jù)
commit;--提交事務
rollback; -- 回滾
- ALTER命令
show columns from user_info;--顯示table字段
alter table user_info add testColumn int;--添加字段
alter table user_info modify testColumn char(20) first name;--在name字段前添加,after相反
ALTER TABLE tableName MODIFY j BIGINT NOT NULL DEFAULT 100;--修改默認字段
alter table user_info drop testColumn;--刪除字段
show columns from user_info;--查看字段
alter table user_info modify testColumn char(20);--修改字段類型及名稱
alter table tableName engine=myisam;--修改存儲引擎
alter table tableName drop foreign key keyName;--刪除外鍵約束:keyName是外鍵別名
ALTER TABLE tableName ALTER colName SET DEFAULT 1000;--修改字段默認值
ALTER TABLE tableName RENAME TO tableName2;--修改表名
- 將數(shù)據(jù)庫表的字段變成自增方法:
--將表中字段刪除
alter table [dbo].[MemberInfo] drop column MemberID
--添加表中字段并使其自增
alter table [dbo].[MemberInfo] add MemberID int identity(1,1) primary key
- 復制表
show create table user_info; --顯示創(chuàng)建表的結構語句,然后修改表明執(zhí)行語句
INSERT INTO clone_tbl (runoob_id,
-> runoob_title,
-> runoob_author,
-> submission_date)
-> SELECT runoob_id,runoob_title,
-> runoob_author,submission_date
-> FROM runoob_tbl;--復制數(shù)據(jù)
- 獲取服務器元數(shù)據(jù)
SELECT VERSION(); --服務器版本信息
SELECT DATABASE(); -當前數(shù)據(jù)庫名 (或者返回空)
SELECT USER(); --當前用戶名
-- SHOW STATUS; --服務器狀態(tài)
-- SHOW VARIABLES;--服務器配置變量
- 查詢重復數(shù)據(jù)
SELECT phoneNum,COUNT(0) AS 重復數(shù)據(jù) FROM dbo.sys_user GROUP BY PhoneNum HAVING COUNT(PhoneNum)>0 ORDER BY 重復數(shù)據(jù)
- 重復數(shù)據(jù)處理
select count(*) as count,name,age from user_info group by name,age;--name和age都重復的個數(shù)
--linq 寫法
select age from user_info group by age;--讀取不重復數(shù)據(jù) with group by
select distinct age from user_info;--讀取不重復數(shù)據(jù) with distinct
- 重復數(shù)據(jù)處理 linq 方式
//單個group by 情況
var names = from p in details
group p by p.name into g
select new {g.Key, nameCount = g.Count() };
//多個group by 情況
var names = from p in details
group p by new { p.entryName,p.amount } into g
select new {g.Key.entryName, nameCount = g.Count() };
- 導出數(shù)據(jù)
SELECT * FROM runoob_tbl INTO OUTFILE '/tmp/tutorials.txt';
- 查詢數(shù)據(jù)庫mdf文件存放位置
select filename from master.dbo.sysdatabases where name LIKE '%'
- 分頁查詢方法(row_number)
//c#
//對應的linq表達式
Sys_UserInfo.Skip(20).Take(10).ToList();
-- Region Parameters
DECLARE @p0 INT = 20;
DECLARE @p1 INT = 10;
---- EndRegion
SELECT [t1].[UserID] ,
[t1].[LoginName] ,
[t1].[LoginPass] ,
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY [t0].[UserID], [t0].[LoginName], [t0].[LoginPass] ) AS [ROW_NUMBER] ,
[t0].[UserID] ,
[t0].[LoginName] ,
[t0].[LoginPass] ,
FROM [sys_UserInfo] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER];
- cross/outer apply 用法
將左表的每項值作為右輸入?yún)?shù),簡單的說 apply 允許我們將前面結果集每一行的數(shù)據(jù)作為參數(shù),傳遞到后面的表達式,后面的表達式可以是一個表值函數(shù),或者select結果集。outer apply 與left join 類似,cross apply 與inner join 類似
-- Region Parameters
DECLARE @p0 NVARCHAR(100) = '';
-- EndRegion
SELECT [t3].[value]
FROM ( SELECT [t0].[CompanyId]
FROM [sys_UserInfo] AS [t0]
GROUP BY [t0].[CompanyId]
) AS [t1]
OUTER APPLY ( SELECT COUNT(*) AS [value]
FROM [sys_UserInfo] AS [t2]
WHERE ( [t2].[UserRealName] <> @p0 )
AND ( [t1].[CompanyId] = [t2].[CompanyId] )
) AS [t3];
- ROW_NUMBER() 行號
返回結果集分區(qū)內行的序列號,每個分區(qū)的第一行從1開始,
ROW_NUMBER () OVER ([ <partition_by_clause> ] <order_by_clause>)
SELECT ROW_NUMBER() OVER(PARTITION BY m.memberID ORDER BY createTime) AS rowNum,m.* FROM dbo.MemberGPS AS m
在使用over等函數(shù)時,over里頭的分組及排序的執(zhí)行晚于“where,group by,order by”的執(zhí)行。
select
ROW_NUMBER() over(partition by customerID order by insDT) as rows,
customerID,totalPrice, DID
from OP_Order where insDT>'2011-07-22'
RANK 排名
分組后取每組第一條
ROW_NUMBER() OVER(PARTITION BY ID ORDER BY TIME)
SELECT *
FROM ( SELECT ROW_NUMBER() OVER ( PARTITION BY m.MemberID ORDER BY m.CreateTime ) as rowNum ,
m.*
FROM dbo.MemberGPS AS m
) AS t
WHERE t.rowNum = 1;
- linq to sql 表達式語句
下面用一個表格總結一下LINQ to SQL語句
Where 過濾;延遲
Select 選擇;延遲
Distinct 查詢不重復的結果集;延遲
Count 返回集合中的元素個數(shù),返回INT類型;不延遲
LongCount 返回集合中的元素個數(shù),返回LONG類型;不延遲
Sum 返回集合中數(shù)值類 型元素之和,集合應為INT類型集合;不延遲
Min 返回集合中元素的最小值;不延遲
Max 返回集合中元素的最大值;不延遲
Average 返回集合中的數(shù)值類型元素的平均 值。集合應為數(shù)字類型集合,其返回值類型為double;不延遲
Aggregate 根據(jù)輸入的表達式獲取聚合值;不延遲
- 存儲過程-- 1.無參數(shù)簡單存儲過程
SET ANSI_NULLS ON -- value 符合null值規(guī)則
GO
SET QUOTED_IDENTIFIER ON --標識符可以用,且需用雙引號引起來
GO
CREATE PROCEDURE user_proc
AS
BEGIN
SET NOCOUNT ON; --不返回計數(shù)
SELECT * FROM users;
SET NOCOUNT OFF; --打開返回計數(shù)
END
GO
-- EXEC dbo.user_proc --執(zhí)行存儲過程
第一次創(chuàng)建存儲過程后下次修改需將CREATE PROCEDURE改成ALTER PROCEDURE
- 存儲過程-- 2 帶參數(shù)存儲過程
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[user_proc]
@sname NVARCHAR(100)
AS
BEGIN
SELECT * FROM dbo.Users WHERE Name = @sname
END
GO
-- exec user_proc ''
- 存儲過程-- 3 輸出變量
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[user_proc]
@sname NVARCHAR(100),
@emptyNameCount INT OUTPUT --傳出參數(shù)
AS
BEGIN
SET @emptyNameCount =( SELECT COUNT(*) FROM dbo.Users WHERE Name = @sname)
END
GO
DECLARE @emptyNameCount int
exec user_proc '',@emptyNameCount OUTPUT
SELECT @emptyNameCount AS emptyNameCount
- 游標
DECLARE cursor_user CURSOR FOR SELECT * FROM dbo.Users
OPEN cursor_user
FETCH NEXT FROM cursor_user
while @@fetch_status=0
BEGIN
UPDATE dbo.Users SET Name = 'wwmin' WHERE CURRENT OF cursor_user
FETCH NEXT FROM cursor_user
END
CLOSE cursor_user
DEALLOCATE cursor_user
-- 601. 體育館的人流量 解法用到的游標示例
DECLARE @sid INT;
DECLARE @sdate DATE;
DECLARE @speople INT;
DECLARE @startdate DATE;
DECLARE @nextdate Date;
DECLARE @thisN INT =0;
DECLARE my_coursor CURSOR FOR SELECT id,date,people FROM stadium WHERE people >=100 --定義游標
OPEN my_coursor --打開游標
FETCH NEXT FROM my_coursor INTO @sid ,@sdate,@speople; --獲取游標值
SET @startDate=@sdate;
SET @nextDate=@sdate;
WHILE @@FETCH_STATUS=0 --循環(huán)遍歷游標 當?shù)扔?時結束
BEGIN
IF(@sdate = DATEADD(DAY,1,@nextDate))
BEGIN
SET @nextDate=@sdate;
SET @thisN=@thisN+1;
END
ELSE
BEGIN
SET @startDate=@sdate;
SET @nextDate=@sdate;
SET @thisN=0;
END
FETCH NEXT FROM my_coursor INTO @sid,@sdate,@speople; --獲取下一個游標值
END
CLOSE my_coursor; --關閉
DEALLOCATE my_coursor;--刪除游標引用
IF(@thisN >= 3)
BEGIN
SELECT * FROM dbo.stadium WHERE date >= @startDate AND date <= @nextDate
END
- 回滾操作 transaction
BEGIN TRY
BEGIN TRANSACTION; --開啟事務
INSERT INTO dbo.Users
( Name, Banned, Role )
VALUES ( N'a', -- Name - nvarchar(50)
N'1', -- Banned - nvarchar(10)
N'guest' -- Role - nvarchar(50)
);
COMMIT TRANSACTION; -- 提交事務
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS errornumber; --顯示錯誤數(shù)
ROLLBACK TRANSACTION; --回滾事務
END CATCH;
- 觸發(fā)器
IF(OBJECT_ID('tri_user') IS NOT NULL)
DROP TRIGGER tri_user --如果已存在則刪除觸發(fā)器
GO
CREATE TRIGGER tri_user --創(chuàng)建觸發(fā)器
ON dbo.Users -- 在哪個表上創(chuàng)建
FOR delete --delete 觸發(fā)器 ,相應的還有insert update觸發(fā)器
AS
DECLARE @p_Id INT
SELECT @p_Id = Users_Id FROM deleted --刪除的數(shù)據(jù),該數(shù)據(jù)存在deleted表中,相應的還有inserted臨時表
--但是沒有updated臨時表,而是用deleted和inserted兩個臨時表代替
DELETE dbo.Person WHERE user_id = @p_Id --做相應的操作
GO
-- instead of 觸發(fā)器,instead of 觸發(fā)器并不執(zhí)行其定義的操作(insert、update、delete)
--而僅是執(zhí)行觸發(fā)器本身,并且會覆蓋觸發(fā)語句的操作
CREATE TRIGGER tri_user_insteadof
ON dbo.Users
INSTEAD OF UPDATE,INSERT,DELETE
AS
DECLARE @count1 INT;
DECLARE @count2 INT;
SELECT @count1 = COUNT(1) FROM Deleted
SELECT @count2 = COUNT(1) FROM Inserted
IF(@count1>0 AND @count2>0)
BEGIN
SELECT 'update 操作'
END
ELSE IF(@count1>0)
BEGIN
SELECT 'delete 操作'
END
ELSE IF(@count2>0)
BEGIN
SELECT 'insert 操作'
END
GO
DISABLE TRIGGER tri_user ON dbo.Users;-- 關閉觸發(fā)器
ENABLE TRIGGER tri_user ON dbo.Users; -- 啟用觸發(fā)器
select * from sys.triggers; --查詢已存在的觸發(fā)器
select * from sys.objects where type = 'TR';--查詢已存在的觸發(fā)器
select * from sys.trigger_events --查詢觸發(fā)器事件對象視圖
exec sp_helptext 'tri_user' --查詢創(chuàng)建觸發(fā)器的 T-SQL 文本
定時器
在規(guī)定的時間執(zhí)行相應操作
1.首先開啟sql server 代理(SQL Server Agent),雙擊開啟即可
2.管理-->維護計劃-->右鍵新建維護計劃-->子計劃的計劃添加執(zhí)行時機-->在工具箱里面選擇維護計劃任務,將任務拖到任務面板里面,經(jīng)常用到的時備份數(shù)據(jù)庫和執(zhí)行T-SQL語句任務,雙加任務編寫語句
3.保存之后在管理-->維護計劃-->右鍵該任務選擇執(zhí)行即可生效延遲執(zhí)行或者是指定時間執(zhí)行
SELECT * FROM dbo.Users WAITFOR DELAY '00:00:10' --延遲10秒執(zhí)行
- 時間相關 (sql server)
BEGIN --時間相關
--當前日期 往前推7天
DECLARE @dl DATE = GETDATE()-7
--轉換日期格式為年月日字符串
DECLARE @dt1 NVARCHAR(32)=CONVERT(NVARCHAR(32), GETDATE()-7, 112);
--轉換日期格式為年月日日期
DECLARE @dt2 DATE=CONVERT(DATE, GETDATE()-7, 112);
--將日期轉換為新數(shù)據(jù)類型 style有效值為:
--CONVERT(data_type(length),data_to_be_converted,style)
-- Style ID Style 格式
--100 或者 0 mon dd yyyy hh:miAM (或者 PM)
--101 mm/dd/yy
--102 yy.mm.dd
--103 dd/mm/yy
--104 dd.mm.yy
--105 dd-mm-yy
--106 dd mon yy
--107 Mon dd, yy
--108 hh:mm:ss
--109 或者 9 mon dd yyyy hh:mi:ss:mmmAM(或者 PM)
--110 mm-dd-yy
--111 yy/mm/dd
--112 yymmdd
--113 或者 13 dd mon yyyy hh:mm:ss:mmm(24h)
--114 hh:mi:ss:mmm(24h)
--120 或者 20 yyyy-mm-dd hh:mi:ss(24h)
--121 或者 21 yyyy-mm-dd hh:mi:ss.mmm(24h)
--126 yyyy-mm-ddThh:mm:ss.mmm(沒有空格)
--130 dd mon yyyy hh:mi:ss:mmmAM
--131 dd/mm/yy hh:mi:ss:mmmAM
DECLARE @y INT = YEAR(GETDATE());--年
DECLARE @m INT =MONTH(GETDATE());--月 從1開始
DECLARE @d INT=DAY(GETDATE());--日
SELECT @dl,@dt1,@dt2,@y,@m,@d;
SELECT DATEADD(DAY,-7,GETDATE());-- 當前時間往前推7天
SELECT DATEADD(HOUR,1,GETDATE());-- 當前時間往后推1小時
SELECT DATEDIFF(d,@dl,GETDATE()); --計算兩個日期差值 d為日期
SELECT DATEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE()),DAY(GETDATE()));--根據(jù)年月日拼接處日期
SELECT DATENAME(YEAR,GETDATE());--獲取年 --有效值 YEAR|y,QUARTER|q,MONTH|m,WEEKDAY,WEEK|w,DAY|d,DAYOFYEAR,HOUR|h,MINUTE|m,SECOND|s,MS(毫秒)
SELECT DATEPART(ms,GETDATE());--獲取日期部分值, --有效值 YEAR|y,QUARTER|q,MONTH|m,WEEKDAY,WEEK|w,DAY|d,DAYOFYEAR,HOUR|h,MINUTE|m,SECOND|s,MS(毫秒)
SELECT DATETIME2FROMPARTS(2019,8,26,15,10,11,1,2);-- 拼接日期
SELECT DATETIMEFROMPARTS(2019,8,26,15,10,11,11);-- 拼接日期
SELECT DATETIMEOFFSETFROMPARTS(2019,8,26,15,10,11,1,2,1,2);--拼接出偏移日期
END
GO
- 更新某個表的字段值(依據(jù)自身做個計算)
UPDATE UserData SET num = CAST(ROUND(num, 0) as int) where id = 1
- 循環(huán)插入值
--insert into [Eletcric_3].dbo.account
--values('admin1','e35696dec3cfa6299f8ebd6c3434daf3','2019-09-29 07:17:39.877','2222','2100-01-01 00:00:00.000','0','1','13564066562','1','上海松江');
--循環(huán)執(zhí)行插入10000條數(shù)據(jù)
declare @ID int
begin
set @ID=2
while @ID<=100
begin
insert into [Eletcric_3].dbo.account
values('admin'+cast(@ID as varchar),'e35696dec3cfa6299f8ebd6c3434daf3','2019-09-29 07:17:39.877','2222','2100-01-01 00:00:00.000','0','1','13564066562','1','上海松江');
set @ID=@ID+1
end
end
- 查看某個表的所有字段及類型
SELECT name as column_name,TYPE_NAME(system_type_id) as column_type from sys.columns WHERE object_id = OBJECT_ID('t_table_name');
-- t_table_name 為表名
- 日期相關
字符串轉日期時間
SELECT CONVERT(datetime,'2021-8-2 00:02:44',20)
-- 2021-08-02 00:02:44.000
- SQL Server日期函數(shù)舉例:
- GetDate
select GetDate() --2021-08-02 08:59:49.500
- DateDiff
SELECT DateDiff(s,'2021-07-20','2021-07-25 22:56:32')
-- 返回值為 514592 秒
SELECT DateDiff(d,'2021-07-20','2021-07-25 22:56:32')
-- 返回值為 5 天
- DatePart
SELECT DatePart(w,'2021-7-26 22:56:32') -- 返回值為 2 即星期一(周日為1,周六為7)
SELECT DatePart(d,'2021-7-25 22:56:32') -- 返回值為 25即25號
SELECT DatePart(y,'2021-7-25 22:56:32') -- 返回值為 206即這一年中第206天
SELECT DatePart(yyyy,'2021-7-25 22:56:32') -- 返回值為 2021即2021年