1. 表A有5行數據,表B有7行數據,問Inner Join最多返回幾行數據,Left Join最多返回幾行數據,分別在什么情況下?
Inner Join 是返回關聯表的Cartesian product,然后根據On條件剔除掉不符合的行。這樣的話,返回最多行的情況就是保留整個Cartesian product,On對每一行都為True.
即最多返回5*7=35行。
Outer Join 是返回關聯表的Cartesian product,然后根據On條件剔除掉不符合的行,再將添加外部行。
外部行是指保留表中根據On條件在非保留表中找不到與之匹配行的行,非保留表的行數據用NULL值占位。
返回最多行的情況也是返回整個Cartesian product=35行。
最大返回行的示例代碼:
CodeCREATE TABLE tb1 (id INT,val NVARCHAR(10))
CREATE TABLE tb2 (id INT,val NVARCHAR(10))
GO
INSERT INTO tb1 VALUES(1,'a'),(1,'b'),(1,'c'),(1,'d'),(1,'e')
INSERT INTO tb2 VALUES(1,'a'),(1,'b'),(1,'c'),(1,'d'),(1,'e'),(1,'f'),(1,'g')
GO
SELECT * FROM tb2 a JOIN tb1 b
ON a.id=b.id;
SELECT * FROM tb2 a LEFT OUTER JOIN tb1 b
ON a.id=b.id
GO
2. 有表Tb如下,寫出SELECT COUNT(*),COUNT(col1),COUNT(col2),COUNT(DISTINCT col1),COUNT(DISTINCT col2),COUNT(col1+col2),COUNT(col1-col2) FROM Tb的返回結果。
col1 |
col2 |
1 |
1 |
1 |
NULL |
Null |
1 |
Null |
Null |
這是一個非常基礎和細節性的問題,如果能用電腦,試一下就知道答案了,但是試題上碰到,很少人能全寫對。定義問題,COUNT函數的定義如下:
返回組中的項。
COUNT(*) 返回組中的項數。包括 NULL 值和重復項。
COUNT(ALL expression) 對組中的每一行都計算 expression 並返回非空值的數量。
COUNT(DISTINCT expression) 對組中的每一行都計算 expression 並返回唯一非空值的數量。
同時,NULL參與的運算,結果始終為NULL。這樣結果就比較明顯了:4 2 2 1 1 1 1
3.如何得到一個1~9之間的隨機整數(包含1和9)?表Tb只有一列col,包含很多個這種整數,查詢Tb得到如下結果,Range隨機整數的范圍,Count表示計數:
1~9之間隨機整數:SELECT cast(ceiling(rand() * 9) AS INT )
rand()返加始終會是大於0且小於1的float,ceiling取大於或者等於給定表達式的最小整數,所以會得1~9之間的隨機整數。
CodeCREATE TABLE tb4 (id INT)
GO
DECLARE @i INT =100
WHILE @i>0
BEGIN
INSERT INTO tb4 VALUES(cast(ceiling(rand() * 9) AS INT ));
SET @i=@i-1
END
GO
--先根據不同區段分組統計並給數據打上flag,再根據flag去sum得到總數
;WITH cte AS (
SELECT ID,COUNT(id)AS counts,
(
CASE WHEN id BETWEEN 1 AND 3 THEN 1
WHEN id BETWEEN 4 AND 5 THEN 2
WHEN id BETWEEN 6 AND 9 THEN 3
END
) as flag
FROM tb4 GROUP BY id
)
SELECT
(
CASE flag WHEN 1 THEN '1~3'
WHEN 2 THEN '4~5'
WHEN 3 THEN '6~9'
END
) as [Range],
SUM(counts)AS [Count]
FROM cte
GROUP BY flag
4. Server1上有數據庫A,其鏡像數據庫是服務器Server2上的AM。Server2上定時生成AM的Snapshot庫AS。Server2上有一個庫AU,這個庫中沒有表,全是指向的AS的視圖。
用戶只能通過AU庫的視圖去訪問AS的數據。請問該如何實現這種安全性要求。
這其實是一個Ownership chain的問題。參考資料:Ownership Chains
分析:
a. 必需有一個login(就叫tb吧)對於數據庫A,AS和AU具有訪問權限.假設某個用戶的login叫做vw,它必需是庫A和AS的public成員,同時還要對庫AU中視圖具有查詢權限.
b. login tb在庫A和AU中必需相應表和視圖的Owner
c. 由於Mirroring db和Snapshot的安全配置繼承自主庫A且不可修改,所以在Server2上必需創建同名和同SID的login.
d. 在Server2上啟用cross db ownership chaining,允許跨庫的所有權鏈接.
測試代碼:
測試代碼中主庫為MirrorTest,鏡像庫也是MirrorTest,快照庫是MT_SS,視圖庫為MT_VIEW
a. 在Server1上創建庫和相關配置
Code--create the testing database and tables
use master
go
CREATE DATABASE [MirrorTest]
go
use [MirrorTest]
go
EXEC dbo.sp_changedbowner @loginame = N'sa', @map = false
go
select * into dbo.tb1 from sys.objects
select * into dbo.tb2 from sys.indexes
go
--create login and configure security
use master
go
create login tb with password ='joe123',check_policy=off
create login vw with password ='joe123',check_policy=off
--select name,sid from sys.server_principals where name in('vw','tb')
--tb 0xEF38C47530A81041A4F0455F7DCE71E9
--vw 0x1652B3E456CAE549B263C6C06D6D61B1
go
use [MirrorTest]
go
create user tb
create user vw
--set USER tb as the owner of tb1&tb2
ALTER AUTHORIZATION ON dbo.tb1 TO tb
ALTER AUTHORIZATION ON dbo.tb2 TO tb
go
b. 在成功配置鏡像會話之后,再在SERVER2上配置
Codeuse master
go
create login tb with password ='joe123',check_policy=off,sid=0xEF38C47530A81041A4F0455F7DCE71E9
create login vw with password ='joe123',check_policy=off,sid=0x1652B3E456CAE549B263C6C06D6D61B1
go
--drop database MT_SS
--create Snapshot of Mirroring db MirrorTest
create database MT_SS on
(Name='MirrorTest',filename='F:\SQL-DATA\MT.mdf')
as snapshot of MirrorTest
go
--create view
use master
go
create database MT_View
go
use MT_View
go
create user tb
create user vw
go
create view dbo.v1
as
select * from MT_ss.dbo.tb1
go
create view dbo.v2
as
select * from MT_ss.dbo.tb2
go
--set USER tb as the owner of v1&vv2
ALTER AUTHORIZATION ON dbo.v1 TO tb
ALTER AUTHORIZATION ON dbo.v2 TO tb
grant select on v1 to vw
grant select on v2 to vw
go
--select * from sys.configurations where name='cross db ownership chaining'
exec sp_configure 'cross db ownership chaining',1
reconfigure with override
這個時候以vw登錄SERVER2就可以實現題目所要求的.沒將USER tb和vm添加到某個role中,但是tb做為對象的owner,具有較高權限.vm只是相關庫public和視圖的查詢權限,不能直接訪問主庫和快照中的數據.
小結:
基礎知識很重要,不然就會用時方恨少.