我有一个数据库,其中存储了退休申请模块上提交的文件的详细信息(仅显示相关字段)。我正在尝试创建一个视图,其中我获取员工的个人信息以及表示当前文档状态的布尔值表。我有四张桌子:
1-"主要记录"表,这是客户端应用程序的入口点
CREATE TABLE tbRegistro (
ID int IDENTITY(0,1) PRIMARY KEY,
ID_ANAGRAFICA int NOT NULL,
ID_DOCUMENTAZIONE int,
ID_COMUNICAZIONI int,
UTENTE nvarchar(15) NOT NULL,
DATA_CREAZIONE datetime NOT NULL,
LOCK bit
);
数据示例:
ID ID_ANAGRAFICA ID_DOCUMENTAZIONE ID_COMUNICAZIONI
----------- ------------- ----------------- ----------------
0 1 1 0
1 3 3 1
2 5 5 2
3 7 7 3
2-"个人信息表"退休员工
CREATE TABLE tbAnagrafica (
ID int IDENTITY(0,1) PRIMARY KEY,
MATRICOLA nvarchar(7) NOT NULL,
COGNOME nvarchar(50) NOT NULL,
NOME nvarchar(50) NOT NULL,
COD_ENTE char(5) NOT NULL,
NOME_ENTE nvarchar(150) NOT NULL,
UTENTE nvarchar(15) NOT NULL,
DATA_CREAZIONE datetime NOT NULL
);
数据示例:
ID MATRICOLA COGNOME NOME
----------- --------- ----------------- ----------------
1 DRTVDR SKYWALKER ANAKIN
3 EMPR0R PALPATINE SHEEV
5 NRFHRD SOLO HAN
7 SCARRD SOLO BEN
3-表格,其中包含退休人员提交的每份文件的详细信息
CREATE TABLE tbDettaglioDoc(
ID int IDENTITY(0,1) PRIMARY KEY,
PROT_NUM int NOT NULL,
PROT_DATA datetime NOT NULL,
PRESENTE bit NOT NULL,
INCOMPLETO bit NOT NULL,
DISABILITATO bit NOT NULL,
NOTE nvarchar(255),
ID_TIPODOCUMENTO int NOT NULL,
UTENTE nvarchar(15) NOT NULL,
DATA_CREAZIONE datetime NOT NULL
);
数据示例:
ID PROT_NUM PROT_DATA PRESENTE INCOMPLETO DISABILITATO ID_TIPODOCUMENTO
----------- ----------- ----------------------- -------- ---------- ------------ ----------------
6 84528 2018-05-07 00:00:00.000 1 0 0 0
7 84528 2018-05-07 00:00:00.000 1 0 0 3
8 84528 2018-05-07 00:00:00.000 1 0 0 5
11 84528 2018-05-07 00:00:00.000 1 0 0 9
12 238785 2018-05-07 00:00:00.000 1 0 0 0
13 238785 2018-05-07 00:00:00.000 1 0 0 3
14 238785 2018-05-07 00:00:00.000 1 1 0 5
25 51132 2018-05-07 00:00:00.000 1 0 0 4
26 51132 2018-05-07 00:00:00.000 1 0 0 5
28 51132 2018-05-07 00:00:00.000 1 0 0 9
29 84350 2018-05-07 00:00:00.000 1 0 0 0
30 84350 2018-05-07 00:00:00.000 1 1 0 3
4-包含所有文件的表格'整个应用程序的ID,当该特定文档仍然缺失时存储NULL值(这里只显示通用名称):
CREATE TABLE tbDocumentazione(
ID int IDENTITY(0,1) PRIMARY KEY,
ID_ISTANZA int,
ID_ATTIDISP int,
ID_CEDOLINO int,
ID_DATISENS int,
ID_NULLAOSTA int,
ID_INESDEBITI int,
ID_DUM int,
ID_MOD27 int,
ID_CODFISC int,
ID_DOCIDENTITA int,
ID_CERTMORTE int,
ID_ATTONOTORIO int,
UTENTE nvarchar(15) NOT NULL,
DATA_CREAZIONE datetime NOT NULL
);
数据示例:
ID ID_ISTANZA ID_ATTIDISP ID_CEDOLINO ID_DATISENS ID_NULLAOSTA ID_INESDEBITI ID_DUM ID_MOD27 ID_CODFISC ID_DOCIDENTITA ID_CERTMORTE ID_ATTONOTORIO
----------- ----------- ----------- ----------- ----------- ------------ ------------- ----------- ----------- ----------- -------------- ------------ --------------
1 6 NULL NULL 7 NULL 8 NULL 9 10 11 NULL NULL
3 12 NULL NULL 13 NULL 14 NULL NULL 15 16 NULL NULL
5 23 NULL NULL 24 25 26 NULL NULL 27 28 NULL NULL
7 29 NULL NULL 30 NULL 31 NULL 32 33 34 NULL NULL
8 38 NULL NULL 35 NULL 36 NULL NULL 39 37 NULL NULL
9 40 NULL NULL 41 NULL 42 NULL 43 44 45 NULL NULL
我希望它会返回这样的东西(书呆子警报!)
ID COGNOME NOME MATRICOLA ISTANZA ATTI_DISP CEDOLINO
+----+------------+-----------+-----------+---------+-----------+----------
1 SKYWALKER ANAKIN DRTVDR 1 0 1
2 PALPATINE SHEEV EMPROR 1 1 0
3 SOLO HAN NRFHRD 0 1 1
...and so on
其中" 0 =在文档未提交或不完整时显示,但我对T-SQL很新,我尝试的每个查询都失败了。所以我有点卡住了。任何帮助都非常感谢。
提前致谢。 的Davide。
答案 0 :(得分:0)
好的我没有看到FK的定义所以我会假设ID_TIPODOCUMENTO在tbDettaglioDoc与tbAnagrafica中的ID相关联,所以粗略的想法如下:
SELECT P.ID, P.COGNOME, P.NOME, P.MATRICOLA,
CASE WHEN COUNT(IDoc.ID) > 0 THEN 1 ELSE 0 END AS ISTANZA,
CASE WHEN COUNT(ADoc.ID) > 0 THEN 1 ELSE 0 END AS ATTI_DISP,
CASE WHEN COUNT(CDoc.ID) > 0 THEN 1 ELSE 0 END AS CEDOLINO
FROM tbAnagrafica P
LEFT JOIN tbDettaglioDoc I ON P.ID = I.ID_TIPODOCUMENTO AND I.PRESENTE = 1 AND I.INCOMPLETO = 0
LEFT JOIN tbDocumentazione IDoc ON I.ID = IDoc.ID_ISTANZA
LEFT JOIN tbDettaglioDoc A ON P.ID = A.ID_TIPODOCUMENTO AND A.PRESENTE = 1 AND A.INCOMPLETO = 0
LEFT JOIN tbDocumentazione ADoc ON A.ID = ADoc.ID_ATTIDISP
LEFT JOIN tbDettaglioDoc C ON P.ID = C.ID_TIPODOCUMENTO AND C.PRESENTE = 1 AND C.INCOMPLETO = 0
LEFT JOIN tbDocumentazione CDoc ON C.ID = CDoc.ID_CEDOLINO
GROUP BY P.ID, P.COGNOME, P.NOME, P.MATRICOLA
我不是说它会起作用,但应该是关于如何以一种方式做到这一点的想法,取决于你的表大小和索引,它可能是慢查询。
另一种方式是创建一个具有所需结果结构的临时/变量表,在一个查询中首先将个人记录插入其中,然后使用三个不同的查询更新表关于一种文件:
Select P.ID, P.COGNOME, P.NOME, P.MATRICOLA, 0 AS ISTANZA, 0 AS ATTI_DISP, 0 AS CEDOLINO
INTO #Result from tbAnagrafica P
UPDATE R
SET ISTANZA = 1
FROM #Result R
INNER JOIN tbDettaglioDoc I ON R.ID = I.ID_TIPODOCUMENTO
INNER JOIN tbDocumentazione IDoc ON I.ID = IDoc.ID_ISTANZA
WHERE I.PRESENTE = 1 AND I.INCOMPLETO = 0
UPDATE R
SET ATTI_DISP = 1
...
对于最后一部分,您可以使用EXISTS代替JOIN,理想情况下应该更好地使用性能
UPDATE R
SET ISTANZA = 1
FROM #Result R
WHERE EXISTS(SELECT 1 FROM tbDettaglioDoc I
INNER JOIN tbDocumentazione IDoc ON I.ID = IDoc.ID_ISTANZA
WHERE R.ID = I.ID_TIPODOCUMENTO AND I.PRESENTE = 1 AND I.INCOMPLETO = 0)
答案 1 :(得分:0)
我找到了获得我想要的方法:
SELECT
tbRegistro.ID,
tbAnagrafica.COGNOME,
tbAnagrafica.NOME,
tbAnagrafica.MATRICOLA,
(A.PRESENTE & ~A.INCOMPLETO) AS ISTANZA,
(B.presente & ~B.incompleto) AS ATTI_DISP,
(C.PRESENTE & ~C.INCOMPLETO) AS CEDOLINO,
(D.PRESENTE & ~D.INCOMPLETO) AS DATISENS,
(E.PRESENTE & ~E.INCOMPLETO) AS NULLAOSTA,
(F.PRESENTE & ~F.INCOMPLETO) AS INESDEBITI,
(G.PRESENTE & ~G.INCOMPLETO) AS DUM,
(H.PRESENTE & ~H.INCOMPLETO) AS MOD27,
(I.PRESENTE & ~I.INCOMPLETO) AS CODFISC,
(J.PRESENTE & ~J.INCOMPLETO) AS DOCIDENTITA,
(K.PRESENTE & ~K.INCOMPLETO) AS CERTMORTE,
(L.PRESENTE & ~L.INCOMPLETO) AS ATTONOTORIO
FROM
tbRegistro
INNER JOIN tbAnagrafica ON tbRegistro.ID_ANAGRAFICA = tbAnagrafica.ID
INNER JOIN tbDocumentazione ON tbRegistro.ID_DOCUMENTAZIONE = tbDocumentazione.ID
FULL JOIN tbDettaglioDoc AS A ON tbDocumentazione.ID_ISTANZA = A.ID
FULL JOIN tbDettaglioDoc AS B ON tbDocumentazione.ID_ATTIDISP = B.ID
FULL JOIN tbDettaglioDoc AS C ON tbDocumentazione.ID_CEDOLINO = C.ID
FULL JOIN tbDettaglioDoc AS D ON tbDocumentazione.ID_DATISENS = D.ID
FULL JOIN tbDettaglioDoc AS E ON tbDocumentazione.ID_NULLAOSTA = E.ID
FULL JOIN tbDettaglioDoc AS F ON tbDocumentazione.ID_INESDEBITI = F.ID
FULL JOIN tbDettaglioDoc AS G ON tbDocumentazione.ID_DUM = G.ID
FULL JOIN tbDettaglioDoc AS H ON tbDocumentazione.ID_MOD27 = H.ID
FULL JOIN tbDettaglioDoc AS I ON tbDocumentazione.ID_CODFISC = I.ID
FULL JOIN tbDettaglioDoc AS J ON tbDocumentazione.ID_DOCIDENTITA = J.ID
FULL JOIN tbDettaglioDoc AS K ON tbDocumentazione.ID_CERTMORTE = K.ID
FULL JOIN tbDettaglioDoc AS L ON tbDocumentazione.ID_ATTONOTORIO = L.ID
WHERE tbregistro.ID IS NOT NULL
结果示例:
ID COGNOME NOME MATRICOLA ISTANZA ATTI_DISP CEDOLINO DATISENS NULLAOSTA INESDEBITI DUM MOD27 CODFISC DOCIDENTITA CERTMORTE ATTONOTORIO
----------- ------------------- ----------- --------- ------- --------- -------- -------- --------- ---------- ----- ----- ------- ----------- --------- -----------
0 PALPATINE SHEEV EMPR0R 1 0 1 1 1 1 NULL NULL NULL 1 NULL NULL
1 SKYWALKER ANAKIN DRTVDR 1 NULL NULL 1 NULL NULL 0 NULL NULL 1 NULL NULL
1
表示正确提交,0
提交错误,NULL
未提交