联合查询在每一行中重复相同的子查询
Query with union repeating same subquery into each row
在我的数据库中,我有 5 个 table 的详细信息,要从每个 table 中提取详细信息,我需要再加入 3 个 table。
我还需要获取(进入结果查询 table)一些数据(每个 IdLite
总是相同的数据)并将它们添加到每一行。
我写了一个有效的查询,但它非常非常慢,所以我不能使用它。
我用了两次CONCAT
:
第一次从每个细节中获取细节table;
第二次从别人tables那里获取数据(这些数据总是一样的)。
CONCAT
之前的数据也始终相同(对于每个 IdLite
)。
我怎样才能改进我的查询?我正在考虑使用变量,但我做不到。
(
SELECT
t.Office,
li.Year,
li.RIFNUM,
1 IdTable,
li.IdLite,
IdLiteUser,
d1.IdEvent,
CONCAT_WS('_',
IFNULL(d1.TypeT,''),
IFNULL(d1.In_Date,''),
IFNULL(d1.Out_Date,'')
) AS Dett,
CONCAT_WS('_',
IFNULL(li.Section,''),
IFNULL(li.InDate,''),
IFNULL(li.Type,''),
IFNULL(li.Subject,''),
IFNULL(li.DCU_Instance,''),
IFNULL(li.DC_Instance,'')
) AS Essential
FROM TRDetails1 d1
INNER JOIN TRUserLite lU USING (IdLite)
INNER JOIN TRLite li USING (IdLite)
INNER JOIN TR t USING(IdOffice)
WHERE lU.IdUser= '@myVarInsertedEachTime'
AND lU.Status = 0
AND d1.IdEvent NOT IN (
SELECT IdEvent
FROM TRInfo
WHERE IdUser= '@myVarInsertedEachTime'
AND IdTable = 1
AND IdEvent = d1.IdEvent
AND Date > d1.Changed)
)
UNION
(
SELECT
t.Office,
li.Year,
li.RifNum,
2 IdTable,
li.IdLite,
IdLiteUser,
d2.IdEvent,
CONCAT_WS('_',
IFNULL(DocType,''),
IFNULL(d2.Number,''),
IFNULL(d2.Side,''),
IFNULL(d2.InDate,'')
) AS Dett,
CONCAT_WS('_',
IFNULL(li.Section,''),
IFNULL(li.InDate,''),
IFNULL(li.Type,''),
IFNULL(li.Subject,''),
IFNULL(li.DCU_Instance,''),
IFNULL(li.DC_Instance,'')
) AS Essential
FROM TRDetails2 d2
INNER JOIN TRUserLite lU USING (IdLite)
INNER JOIN TRLite li USING (IdLite)
INNER JOIN TR t USING(IdOffice)
WHERE lU.IdUser= '@myVarInsertedEachTime'
AND lU.Status = 0
AND d2.IdEvent NOT IN (
SELECT IdEvent
FROM TRInfo
WHERE IdUser= lU.IdUser
AND IdTable= 2)
)
UNION
(
SELECT
t.Office,
li.Year,
li.RifNum,
3 IdTable,
li.IdLite,
IdLiteUser,
d3.IdEvent,
CONCAT_WS('_',
IFNULL(d3.UdiDate,''),
IFNULL(d3.UdiType,''),
IFNULL(d3.UdiResult,''),
IFNULL(d3.Supervisor,''),
IFNULL(d3.GroupIn,''),
IFNULL(d3.ROrder,'')
) AS Dett,
CONCAT_WS('_',
IFNULL(li.Section,''),
IFNULL(li.InDate,''),
IFNULL(li.Type,''),
IFNULL(li.Subject,''),
IFNULL(li.DCU_Instance,''),
IFNULL(li.DC_Instance,'')
) AS Essential
FROM TRDetails3 d3
INNER JOIN TRUserLite lU USING (IdLite)
INNER JOIN TRLite li USING (IdLite)
INNER JOIN TR t USING(IdOffice)
WHERE lU.IdUser= '@myVarInsertedEachTime'
AND lU.Status = 0
AND d3.IdEvent NOT IN (
SELECT IdEvent
FROM TRInfo
WHERE IdUser= lU.IdUser
AND IdTable= 3)
)
UNION
(
SELECT
t.Office,
li.Year,
li.RifNum,
4 IdTable,
li.IdLite,
IdLiteUser,
d4.IdEvent,
CONCAT_WS('_',
IFNULL(d4.Type,''),
IFNULL(d4.Number,''),
IFNULL(d4.Supervisor,''),
IFNULL(d4.PubDate,''),
IFNULL(d4.UdiDate,''),
IFNULL(d4.UdiType,''),
IFNULL(d4.Result,'')
) AS Dett,
CONCAT_WS('_',
IFNULL(li.Section,''),
IFNULL(li.InDate,''),
IFNULL(li.Type,''),
IFNULL(li.Subject,''),
IFNULL(li.DCU_Instance,''),
IFNULL(li.DC_Instance,'')
) AS Essential
FROM TRDetails4 d4
INNER JOIN TRUserLite lU USING (IdLite)
INNER JOIN TRLite li USING (IdLite)
INNER JOIN TR t USING(IdOffice)
WHERE lU.IdUser= '@myVarInsertedEachTime'
AND lU.Status = 0
AND d4.IdEvent NOT IN (
SELECT IdEvent
FROM TRInfo
WHERE IdUser= lU.IdUser
AND IdTable= 4)
)
UNION
(
SELECT
t.Office,
li.Year,
li.RifNum,
5 IdTable,
li.IdLite,
IdLiteUser,
d5.IdEvent,
CONCAT_WS('_',
IFNULL(d5.Type,''),
IFNULL(d5.Number,''),
IFNULL(d5.Supervisor,''),
IFNULL(d5.PubDate,''),
IFNULL(d5.Result,'')
) AS Dett,
CONCAT_WS('_',
IFNULL(li.Section,''),
IFNULL(li.InDate,''),
IFNULL(li.Type,''),
IFNULL(li.Subject,''),
IFNULL(li.DCU_Instance,''),
IFNULL(li.DC_Instance,'')
) AS Essential
FROM TRDetails5 d5
INNER JOIN TRUserLite lU USING (IdLite)
INNER JOIN TRLite li USING (IdLite)
INNER JOIN TR t USING(IdOffice)
WHERE lU.Idutente = '@myVarInsertedEachTime'
AND lU.Status = 0
AND d5.IdEvent NOT IN (
SELECT IdEvent
FROM TRInfo
WHERE IdUser= lU.Idutente
AND IdTable= 5)
)
ORDER BY Office, Year, RifNum, IdTable
编辑:
我的数据库的结构是:
IdLite
为基础数据id。
每个IdLite
有一个Office
,一个Year
,一个RifNum
,一个TR
。
每个 IdLite
在每个 5 table 的细节上都有许多记录 (TRDetails1
, TRDetails2
, TRDetails3
, TRDetails4
, TRDetails5
).
每个User
有很多IdLite
(通过ref存储在TRUserLite
中)并且需要知道每个event
(存储在每个[=74=中的5个中) ]s) 每个 IdLite
.
当一个 User
知道一个细节时,它 (rif) 被存储到 TRInfo
我需要检索事件(从所有 5 个 table 中),每个 IdLite
(链接到特定的 User
)他都不知道这些事件。
编辑2:
这些是我的 table 结构:
CREATE TABLE IF NOT EXISTS `TRDetails1` (
`IdEvent` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`IdLite` bigint(20) NOT NULL,
`TypeT` varchar(50) DEFAULT NULL,
`In_Date` date DEFAULT NULL,
`Out_Date` date DEFAULT NULL,
`Changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRDetails2` (
`IdEvent` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`IdLite` bigint(20) NOT NULL,
`DocType` varchar(200) DEFAULT NULL,
`Number` int(10) DEFAULT NULL,
`Side` varchar(50) DEFAULT NULL,
`InDate` date DEFAULT NULL,
`Updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRDetails3` (
`IdEvent` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`IdLite` bigint(20) NOT NULL,
`UdiDate` date DEFAULT NULL,
`UdiType` varchar(50) DEFAULT NULL,
`UdiResult` varchar(200) DEFAULT NULL,
`Supervisor` varchar(50) DEFAULT NULL,
`GroupIn` varchar(50) DEFAULT NULL,
`ROrder` int(5) DEFAULT NULL,
`Updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRDetails4` (
`IdEvent` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`IdLite` bigint(20) NOT NULL,
`TypeT` varchar(50) DEFAULT NULL,
`Number` int(10) DEFAULT NULL,
`Supervisor` varchar(50) DEFAULT NULL,
`PubDate` date DEFAULT NULL,
`UdiDate` date DEFAULT NULL,
`UdiType` varchar(50) DEFAULT NULL,
`Result` varchar(50) DEFAULT NULL,
`Updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRDetails5` (
`IdEvent` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`IdLite` bigint(20) NOT NULL,
`TypeT` varchar(50) DEFAULT NULL,
`Number` int(10) DEFAULT NULL,
`Supervisor` varchar(50) DEFAULT NULL,
`PubDate` date DEFAULT NULL,
`Result` varchar(50) DEFAULT NULL,
`Updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRLite` (
`IdLite` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Region` char(30) NOT NULL,
`IdOffice` smallint(4) NOT NULL,
`RIFNUM` int(11) NOT NULL,
`Year` mediumint(4) NOT NULL,
`Sub` tinyint(2) DEFAULT NULL,
`Section` tinyint(2) NOT NULL,
`InDate` date NOT NULL,
`Type` varchar(50) NOT NULL,
`Subject` varchar(200) NOT NULL,
`DCU_Instance` char(1) DEFAULT NULL,
`DC_Instance` char(1) DEFAULT NULL,
`Defined` tinyint(2) DEFAULT NULL,
`DefinedDate` date DEFAULT NULL,
`Updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`Scroll_Table` set
('00001','00010','00011','00100','00101','00110','00111','01000','01001','01010','01011','01100','01101
','01110','01111','10000','10001','10010','10011','10100','10101','10110','10111','11000','11001','1101
0','11011','11100','11101','11110','11111') DEFAULT NULL
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRUserLite` (
`IdUser` bigint(20) NOT NULL,
`IdLite` bigint(20) NOT NULL,
`IdLiteUser` varchar(150) DEFAULT NULL,
`Status` tinyint(5) NOT NULL DEFAULT '0',
PRIMARY KEY (`IdUser`,`IdLite`),
KEY `IdLite` (`IdLite`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TR` (
`IdOffice` smallint(4) NOT NULL PRIMARY KEY,
`IdRegion` tinyint(2) NOT NULL,
`Office` char(200) NOT NULL,
`IdWebOffice` varchar(30) NOT NULL
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRInfo` (
`IdInfo` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`IdUser` bigint(20) NOT NULL,
`IdLite` bigint(20) NOT NULL,
`IdTable` tinyint(1) NOT NULL,
`IdEvent` bigint(20) NOT NULL,
`InfoDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `Users` (
`IdUser` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`User` varchar(50) NOT NULL,
`Status` tinyint(5) NOT NULL DEFAULT '0'
) ENGINE=InnoDB;
ALTER TABLE `TRUserLite`
ADD CONSTRAINT `TRUserLite_ibfk_1` FOREIGN KEY (`IdUser`) REFERENCES `Users` (`IdUser`),
ADD CONSTRAINT `TRUserLite_ibfk_2` FOREIGN KEY (`IdLite`) REFERENCES `TRLite` (`IdLite`);
编辑 3:(数据库插入数据标准)
每个 IdLite 可以有很多细节(关于 5 个细节中的一个或多个 tables)。
发生某些事情时,我会在一个(或多个)详细信息中插入 table 一条新记录。
之后,每个用户(只)需要知道新的细节。
为此,我将已知的详细信息保存到 TRInfo 中,并且只向每个用户提供新的详细信息(指链接到用户的 IdLite)。
所以我需要提取所有未知的细节。
编辑 4:(如何修改数据库插入条件)
如果我理解你的提示,你建议在细节已知之前插入 TRInfo,并添加一个字段来检查相关用户是否知道它。
因此,我会将所有详细信息都放入 TRInfo 中,并删除已知的信息。
这是你告诉我的方式吗?
哇......我真的不得不为这个问题挠头,我明白为什么没有其他人试图帮助你了。可能比简单的查询/聚合更令人困惑。无论如何,让我看看我是否理解这些 table 的流程。条目将添加到详细信息 table 的 1-5 中的任何一个。这些被分配给某些用户。基于手头的任务,当他们最终
完成后,一条记录将插入 TRInfo,从而关闭事件。出于这个原因,您从每个细节 table 开始,然后将 WHERE NOT IN 查询应用于 TRINFO table
也就是说,您正在寻找与给定用户关联的交易。从这里,我们可以直接从 TRUserLite table 开始。
从 TRUserLite table,我们可以在 IdLite ID 上加入相应的 Details tables 1-5,同时保留来自 detail table 的 IdEvent 及其对应的 1 -5 事件来源的值。最后,我们可以为同一用户、事件和 table ID # 对 TRInfo table 执行 LEFT-JOIN。通过执行 left-join 它比 NOT IN 子选择更快。我们通过包含在 WHERE 子句
中来消除那些已经 "completed" 的记录
AND TRInfo.IdEvent IS NULL
现在,综上所述,如果准确的话,以下查询应该可以帮助您。它可能有一些您可能能够解决的小语法问题(别名、字段等)。
现在我将解释查询。为了简化原始查询的所有额外连接,我从 TRUserLite 开始并获取那些无需额外连接到 TRLite 和 TR tables 就符合条件的条目。我只是将它们加入/联合到细节和 TRInfo 以获得符合条件的记录。在连接到详细信息 table 时,我将相应的连接字段作为公共 "Dett" 结果列。一旦所有符合条件的记录都完成,然后我才加入回 TRLite 和 TR 以提取最终查询的附加数据。这使内部查询对有限的细节更加严格,然后提取其余部分。
Recommended indexes
table index
TRUserLite ( IdUser, Status ) to optimize the WHERE clause.
TRInfo ( IdUser, IdLite, IdEvent, IdTable )
SELECT
TR.Office,
TRL.`Year`,
TRL.RIFNum,
All5.IdTable
All5.IdLite,
All5.IdLiteUser,
All5.IdEvent,
All5.IdUser,
All5.Dett,
U.User,
U.Status as UserStatus,
CONCAT_WS('_',
IFNULL( TRL.Section,''),
IFNULL( TRL.InDate,''),
IFNULL( TRL.Type,''),
IFNULL( TRL.Subject,''),
IFNULL( TRL.DCU_Instance,''),
IFNULL( TRL.DC_Instance,'') ) AS Essential
from
( SELECT
TRUL.IDUser,
TRUL.IdLite,
TRUL.IdLiteUser,
1 as IdTable,
TD1.IdEvent,
CONCAT_WS('_',
IFNULL( TD1.TypeT,''),
IFNULL( TD1.In_Date,''),
IFNULL( TD1.Out_Date,'') ) AS Dett
from
TRUserLite TRUL
JOIN TRDetails1 TD1
ON TRUL.IdLite = TD1.IdLite
LEFT JOIN TRInfo
ON TRUL.IdUser = TRInfo.IdUser
AND TRUL.IdLite = TRInfo.IdLite
AND TD1.IdEvent = TRInfo.IdEvent
AND TRInfo.IdTable = 1
where
TRUL.IdUser = '@myVarInsertedEachTime'
AND TRUL.Status = 0
AND TRInfo.IdEvent IS NULL
UNION ALL
SELECT
TRUL.IDUser,
TRUL.IdLite,
TRUL.IdLiteUser,
2 as IdTable,
TD2.IdEvent,
CONCAT_WS( '_',
IFNULL( TD2.DocType,''),
IFNULL( TD2.Number,''),
IFNULL( TD2.Side,''),
IFNULL( TD2.InDate,'') ) AS Dett
from
TRUserLite TRUL
JOIN TRDetails2 TD2
ON TRUL.IdLite = TD2.IdLite
LEFT JOIN TRInfo
ON TRUL.IdUser = TRInfo.IdUser
AND TRUL.IdLite = TRInfo.IdLite
AND TD2.IdEvent = TRInfo.IdEvent
AND TRInfo.IdTable = 2
where
TRUL.IdUser = '@myVarInsertedEachTime'
AND TRUL.Status = 0
AND TRInfo.IdEvent IS NULL
UNION ALL
SELECT
TRUL.IDUser,
TRUL.IdLite,
TRUL.IdLiteUser,
3 as IdTable,
TD3.IdEvent,
CONCAT_WS('_',
IFNULL( TD3.UdiDate,''),
IFNULL( TD3.UdiType,''),
IFNULL( TD3.UdiResult,''),
IFNULL( TD3.Supervisor,''),
IFNULL( TD3.GroupIn,''),
IFNULL( TD3.ROrder,'') ) AS Dett
from
TRUserLite TRUL
JOIN TRDetails3 TD3
ON TRUL.IdLite = TD3.IdLite
LEFT JOIN TRInfo
ON TRUL.IdUser = TRInfo.IdUser
AND TRUL.IdLite = TRInfo.IdLite
AND TD3.IdEvent = TRInfo.IdEvent
AND TRInfo.IdTable = 3
where
TRUL.IdUser = '@myVarInsertedEachTime'
AND TRUL.Status = 0
AND TRInfo.IdEvent IS NULL
UNION ALL
SELECT
TRUL.IDUser,
TRUL.IdLite,
TRUL.IdLiteUser,
4 as IdTable,
TD4.IdEvent,
CONCAT_WS('_',
IFNULL( TD4.Type,''),
IFNULL( TD4.Number,''),
IFNULL( TD4.Supervisor,''),
IFNULL( TD4.PubDate,''),
IFNULL( TD4.UdiDate,''),
IFNULL( TD4.UdiType,''),
IFNULL( TD4.Result,'') ) AS Dett
from
TRUserLite TRUL
JOIN TRDetails4 TD4
ON TRUL.IdLite = TD4.IdLite
LEFT JOIN TRInfo
ON TRUL.IdUser = TRInfo.IdUser
AND TRUL.IdLite = TRInfo.IdLite
AND TD4.IdEvent = TRInfo.IdEvent
AND TRInfo.IdTable = 4
where
TRUL.IdUser = '@myVarInsertedEachTime'
AND TRUL.Status = 0
AND TRInfo.IdEvent IS NULL
UNION ALL
SELECT
TRUL.IDUser,
TRUL.IdLite,
TRUL.IdLiteUser,
5 as IdTable,
TD5.IdEvent,
CONCAT_WS('_',
IFNULL( TD5.Type,''),
IFNULL( TD5.Number,''),
IFNULL( TD5.Supervisor,''),
IFNULL( TD5.PubDate,''),
IFNULL( TD5.Result,'') ) AS Dett
from
TRUserLite TRUL
JOIN TRDetails5 TD5
ON TRUL.IdLite = TD5.IdLite
LEFT JOIN TRInfo
ON TRUL.IdUser = TRInfo.IdUser
AND TRUL.IdLite = TRInfo.IdLite
AND TD5.IdEvent = TRInfo.IdEvent
AND TRInfo.IdTable = 5
where
TRUL.IdUser = '@myVarInsertedEachTime'
AND TRUL.Status = 0
AND TRInfo.IdEvent IS NULL ) All5
JOIN Users U
ON All5.IdUser = U.IdUser
JOIN TRLite TRL
ON All5.IdLite = TRL.IdLite
JOIN TR
ON TRL.IdOffice = TR.IdOffice
ORDER BY
TR.Office,
TRL.`Year`,
TRL.RIFNum,
All5.IdTable
(顺便说一句,我将用户 table 添加到连接中,以防您也需要这些列...可以轻松删除)
了解您的原始查询与此结果的执行时间会很有趣,即使它不能解析您的查询时间。
反馈
您目前正在查找不在 TRInfo table 中的内容。如果您可以重组它,以便将状态列添加到 TRInfo,例如 "IsRecordOpen"(夸大列名)并将其设置为 1,然后插入到 TRDetails table。然后当它完成时,将标志设置为零(不再是开放任务)。因此,这是要完成的每个待处理工作的基础,它通过事件 ID 指向相应的详细信息 table。然后您的查询将被简化为类似..
select
TR.Office,
TRL.`Year`,
TRL.RIFNum,
TRI.IdTable
TRI.IdLite,
TRUL.IdLiteUser,
TRI.IdEvent,
TRI.IdUser,
case when TRI.IdTable = 1 THEN
CONCAT_WS('_',
IFNULL( TD1.TypeT,''),
IFNULL( TD1.In_Date,''),
IFNULL( TD1.Out_Date,'') )
when TRI.IdTable = 2 THEN
CONCAT_WS( '_',
IFNULL( TD2.DocType,''),
IFNULL( TD2.Number,''),
IFNULL( TD2.Side,''),
IFNULL( TD2.InDate,'') )
when TRI.IdTable = 3 THEN
CONCAT_WS('_',
IFNULL( TD3.UdiDate,''),
IFNULL( TD3.UdiType,''),
IFNULL( TD3.UdiResult,''),
IFNULL( TD3.Supervisor,''),
IFNULL( TD3.GroupIn,''),
IFNULL( TD3.ROrder,'') )
when TRI.IdTable = 4 THEN
CONCAT_WS('_',
IFNULL( TD4.Type,''),
IFNULL( TD4.Number,''),
IFNULL( TD4.Supervisor,''),
IFNULL( TD4.PubDate,''),
IFNULL( TD4.UdiDate,''),
IFNULL( TD4.UdiType,''),
IFNULL( TD4.Result,'') )
when TRI.IdTable = 5 THEN
CONCAT_WS('_',
IFNULL( TD5.Type,''),
IFNULL( TD5.Number,''),
IFNULL( TD5.Supervisor,''),
IFNULL( TD5.PubDate,''),
IFNULL( TD5.Result,'') )
END AS Dett,
CONCAT_WS('_',
IFNULL( TRL.Section,''),
IFNULL( TRL.InDate,''),
IFNULL( TRL.Type,''),
IFNULL( TRL.Subject,''),
IFNULL( TRL.DCU_Instance,''),
IFNULL( TRL.DC_Instance,'') ) AS Essential
from
TRInfo TRI
JOIN TRLite TRL
on TRI.IdLite = TRL.IdLite
JOIN TR
on TRL.IdOffice = TR.IdOffice
JOIN TRUserLite TRUL
on TRI.IdUser = TRUL.IdUser
AND TRI.IdLite = TRUL.IdLite
AND TRUL.Status = 0
LEFT JOIN TRDetails1 TD1
ON TRI.TableID = 1
AND TRI.IdEvent = TD1.IdEvent
LEFT JOIN TRDetails2 TD2
ON TRI.TableID = 2
AND TRI.IdEvent = TD2.IdEvent
LEFT JOIN TRDetails1 TD3
ON TRI.TableID = 3
AND TRI.IdEvent = TD3.IdEvent
LEFT JOIN TRDetails1 TD4
ON TRI.TableID = 4
AND TRI.IdEvent = TD4.IdEvent
LEFT JOIN TRDetails1 TD5
ON TRI.TableID = 5
AND TRI.IdEvent = TD5.IdEvent
where
TRI.IdUser = 'the user ID you want'
AND TRI.IsRecordOpen
在我的数据库中,我有 5 个 table 的详细信息,要从每个 table 中提取详细信息,我需要再加入 3 个 table。
我还需要获取(进入结果查询 table)一些数据(每个 IdLite
总是相同的数据)并将它们添加到每一行。
我写了一个有效的查询,但它非常非常慢,所以我不能使用它。
我用了两次CONCAT
:
第一次从每个细节中获取细节table;
第二次从别人tables那里获取数据(这些数据总是一样的)。
CONCAT
之前的数据也始终相同(对于每个 IdLite
)。
我怎样才能改进我的查询?我正在考虑使用变量,但我做不到。
(
SELECT
t.Office,
li.Year,
li.RIFNUM,
1 IdTable,
li.IdLite,
IdLiteUser,
d1.IdEvent,
CONCAT_WS('_',
IFNULL(d1.TypeT,''),
IFNULL(d1.In_Date,''),
IFNULL(d1.Out_Date,'')
) AS Dett,
CONCAT_WS('_',
IFNULL(li.Section,''),
IFNULL(li.InDate,''),
IFNULL(li.Type,''),
IFNULL(li.Subject,''),
IFNULL(li.DCU_Instance,''),
IFNULL(li.DC_Instance,'')
) AS Essential
FROM TRDetails1 d1
INNER JOIN TRUserLite lU USING (IdLite)
INNER JOIN TRLite li USING (IdLite)
INNER JOIN TR t USING(IdOffice)
WHERE lU.IdUser= '@myVarInsertedEachTime'
AND lU.Status = 0
AND d1.IdEvent NOT IN (
SELECT IdEvent
FROM TRInfo
WHERE IdUser= '@myVarInsertedEachTime'
AND IdTable = 1
AND IdEvent = d1.IdEvent
AND Date > d1.Changed)
)
UNION
(
SELECT
t.Office,
li.Year,
li.RifNum,
2 IdTable,
li.IdLite,
IdLiteUser,
d2.IdEvent,
CONCAT_WS('_',
IFNULL(DocType,''),
IFNULL(d2.Number,''),
IFNULL(d2.Side,''),
IFNULL(d2.InDate,'')
) AS Dett,
CONCAT_WS('_',
IFNULL(li.Section,''),
IFNULL(li.InDate,''),
IFNULL(li.Type,''),
IFNULL(li.Subject,''),
IFNULL(li.DCU_Instance,''),
IFNULL(li.DC_Instance,'')
) AS Essential
FROM TRDetails2 d2
INNER JOIN TRUserLite lU USING (IdLite)
INNER JOIN TRLite li USING (IdLite)
INNER JOIN TR t USING(IdOffice)
WHERE lU.IdUser= '@myVarInsertedEachTime'
AND lU.Status = 0
AND d2.IdEvent NOT IN (
SELECT IdEvent
FROM TRInfo
WHERE IdUser= lU.IdUser
AND IdTable= 2)
)
UNION
(
SELECT
t.Office,
li.Year,
li.RifNum,
3 IdTable,
li.IdLite,
IdLiteUser,
d3.IdEvent,
CONCAT_WS('_',
IFNULL(d3.UdiDate,''),
IFNULL(d3.UdiType,''),
IFNULL(d3.UdiResult,''),
IFNULL(d3.Supervisor,''),
IFNULL(d3.GroupIn,''),
IFNULL(d3.ROrder,'')
) AS Dett,
CONCAT_WS('_',
IFNULL(li.Section,''),
IFNULL(li.InDate,''),
IFNULL(li.Type,''),
IFNULL(li.Subject,''),
IFNULL(li.DCU_Instance,''),
IFNULL(li.DC_Instance,'')
) AS Essential
FROM TRDetails3 d3
INNER JOIN TRUserLite lU USING (IdLite)
INNER JOIN TRLite li USING (IdLite)
INNER JOIN TR t USING(IdOffice)
WHERE lU.IdUser= '@myVarInsertedEachTime'
AND lU.Status = 0
AND d3.IdEvent NOT IN (
SELECT IdEvent
FROM TRInfo
WHERE IdUser= lU.IdUser
AND IdTable= 3)
)
UNION
(
SELECT
t.Office,
li.Year,
li.RifNum,
4 IdTable,
li.IdLite,
IdLiteUser,
d4.IdEvent,
CONCAT_WS('_',
IFNULL(d4.Type,''),
IFNULL(d4.Number,''),
IFNULL(d4.Supervisor,''),
IFNULL(d4.PubDate,''),
IFNULL(d4.UdiDate,''),
IFNULL(d4.UdiType,''),
IFNULL(d4.Result,'')
) AS Dett,
CONCAT_WS('_',
IFNULL(li.Section,''),
IFNULL(li.InDate,''),
IFNULL(li.Type,''),
IFNULL(li.Subject,''),
IFNULL(li.DCU_Instance,''),
IFNULL(li.DC_Instance,'')
) AS Essential
FROM TRDetails4 d4
INNER JOIN TRUserLite lU USING (IdLite)
INNER JOIN TRLite li USING (IdLite)
INNER JOIN TR t USING(IdOffice)
WHERE lU.IdUser= '@myVarInsertedEachTime'
AND lU.Status = 0
AND d4.IdEvent NOT IN (
SELECT IdEvent
FROM TRInfo
WHERE IdUser= lU.IdUser
AND IdTable= 4)
)
UNION
(
SELECT
t.Office,
li.Year,
li.RifNum,
5 IdTable,
li.IdLite,
IdLiteUser,
d5.IdEvent,
CONCAT_WS('_',
IFNULL(d5.Type,''),
IFNULL(d5.Number,''),
IFNULL(d5.Supervisor,''),
IFNULL(d5.PubDate,''),
IFNULL(d5.Result,'')
) AS Dett,
CONCAT_WS('_',
IFNULL(li.Section,''),
IFNULL(li.InDate,''),
IFNULL(li.Type,''),
IFNULL(li.Subject,''),
IFNULL(li.DCU_Instance,''),
IFNULL(li.DC_Instance,'')
) AS Essential
FROM TRDetails5 d5
INNER JOIN TRUserLite lU USING (IdLite)
INNER JOIN TRLite li USING (IdLite)
INNER JOIN TR t USING(IdOffice)
WHERE lU.Idutente = '@myVarInsertedEachTime'
AND lU.Status = 0
AND d5.IdEvent NOT IN (
SELECT IdEvent
FROM TRInfo
WHERE IdUser= lU.Idutente
AND IdTable= 5)
)
ORDER BY Office, Year, RifNum, IdTable
编辑:
我的数据库的结构是:
IdLite
为基础数据id。
每个IdLite
有一个Office
,一个Year
,一个RifNum
,一个TR
。
每个 IdLite
在每个 5 table 的细节上都有许多记录 (TRDetails1
, TRDetails2
, TRDetails3
, TRDetails4
, TRDetails5
).
每个User
有很多IdLite
(通过ref存储在TRUserLite
中)并且需要知道每个event
(存储在每个[=74=中的5个中) ]s) 每个 IdLite
.
当一个 User
知道一个细节时,它 (rif) 被存储到 TRInfo
我需要检索事件(从所有 5 个 table 中),每个 IdLite
(链接到特定的 User
)他都不知道这些事件。
编辑2:
这些是我的 table 结构:
CREATE TABLE IF NOT EXISTS `TRDetails1` (
`IdEvent` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`IdLite` bigint(20) NOT NULL,
`TypeT` varchar(50) DEFAULT NULL,
`In_Date` date DEFAULT NULL,
`Out_Date` date DEFAULT NULL,
`Changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRDetails2` (
`IdEvent` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`IdLite` bigint(20) NOT NULL,
`DocType` varchar(200) DEFAULT NULL,
`Number` int(10) DEFAULT NULL,
`Side` varchar(50) DEFAULT NULL,
`InDate` date DEFAULT NULL,
`Updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRDetails3` (
`IdEvent` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`IdLite` bigint(20) NOT NULL,
`UdiDate` date DEFAULT NULL,
`UdiType` varchar(50) DEFAULT NULL,
`UdiResult` varchar(200) DEFAULT NULL,
`Supervisor` varchar(50) DEFAULT NULL,
`GroupIn` varchar(50) DEFAULT NULL,
`ROrder` int(5) DEFAULT NULL,
`Updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRDetails4` (
`IdEvent` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`IdLite` bigint(20) NOT NULL,
`TypeT` varchar(50) DEFAULT NULL,
`Number` int(10) DEFAULT NULL,
`Supervisor` varchar(50) DEFAULT NULL,
`PubDate` date DEFAULT NULL,
`UdiDate` date DEFAULT NULL,
`UdiType` varchar(50) DEFAULT NULL,
`Result` varchar(50) DEFAULT NULL,
`Updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRDetails5` (
`IdEvent` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`IdLite` bigint(20) NOT NULL,
`TypeT` varchar(50) DEFAULT NULL,
`Number` int(10) DEFAULT NULL,
`Supervisor` varchar(50) DEFAULT NULL,
`PubDate` date DEFAULT NULL,
`Result` varchar(50) DEFAULT NULL,
`Updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRLite` (
`IdLite` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Region` char(30) NOT NULL,
`IdOffice` smallint(4) NOT NULL,
`RIFNUM` int(11) NOT NULL,
`Year` mediumint(4) NOT NULL,
`Sub` tinyint(2) DEFAULT NULL,
`Section` tinyint(2) NOT NULL,
`InDate` date NOT NULL,
`Type` varchar(50) NOT NULL,
`Subject` varchar(200) NOT NULL,
`DCU_Instance` char(1) DEFAULT NULL,
`DC_Instance` char(1) DEFAULT NULL,
`Defined` tinyint(2) DEFAULT NULL,
`DefinedDate` date DEFAULT NULL,
`Updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`Scroll_Table` set
('00001','00010','00011','00100','00101','00110','00111','01000','01001','01010','01011','01100','01101
','01110','01111','10000','10001','10010','10011','10100','10101','10110','10111','11000','11001','1101
0','11011','11100','11101','11110','11111') DEFAULT NULL
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRUserLite` (
`IdUser` bigint(20) NOT NULL,
`IdLite` bigint(20) NOT NULL,
`IdLiteUser` varchar(150) DEFAULT NULL,
`Status` tinyint(5) NOT NULL DEFAULT '0',
PRIMARY KEY (`IdUser`,`IdLite`),
KEY `IdLite` (`IdLite`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TR` (
`IdOffice` smallint(4) NOT NULL PRIMARY KEY,
`IdRegion` tinyint(2) NOT NULL,
`Office` char(200) NOT NULL,
`IdWebOffice` varchar(30) NOT NULL
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `TRInfo` (
`IdInfo` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`IdUser` bigint(20) NOT NULL,
`IdLite` bigint(20) NOT NULL,
`IdTable` tinyint(1) NOT NULL,
`IdEvent` bigint(20) NOT NULL,
`InfoDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `Users` (
`IdUser` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`User` varchar(50) NOT NULL,
`Status` tinyint(5) NOT NULL DEFAULT '0'
) ENGINE=InnoDB;
ALTER TABLE `TRUserLite`
ADD CONSTRAINT `TRUserLite_ibfk_1` FOREIGN KEY (`IdUser`) REFERENCES `Users` (`IdUser`),
ADD CONSTRAINT `TRUserLite_ibfk_2` FOREIGN KEY (`IdLite`) REFERENCES `TRLite` (`IdLite`);
编辑 3:(数据库插入数据标准)
每个 IdLite 可以有很多细节(关于 5 个细节中的一个或多个 tables)。
发生某些事情时,我会在一个(或多个)详细信息中插入 table 一条新记录。
之后,每个用户(只)需要知道新的细节。
为此,我将已知的详细信息保存到 TRInfo 中,并且只向每个用户提供新的详细信息(指链接到用户的 IdLite)。
所以我需要提取所有未知的细节。
编辑 4:(如何修改数据库插入条件)
如果我理解你的提示,你建议在细节已知之前插入 TRInfo,并添加一个字段来检查相关用户是否知道它。
因此,我会将所有详细信息都放入 TRInfo 中,并删除已知的信息。
这是你告诉我的方式吗?
哇......我真的不得不为这个问题挠头,我明白为什么没有其他人试图帮助你了。可能比简单的查询/聚合更令人困惑。无论如何,让我看看我是否理解这些 table 的流程。条目将添加到详细信息 table 的 1-5 中的任何一个。这些被分配给某些用户。基于手头的任务,当他们最终 完成后,一条记录将插入 TRInfo,从而关闭事件。出于这个原因,您从每个细节 table 开始,然后将 WHERE NOT IN 查询应用于 TRINFO table
也就是说,您正在寻找与给定用户关联的交易。从这里,我们可以直接从 TRUserLite table 开始。
从 TRUserLite table,我们可以在 IdLite ID 上加入相应的 Details tables 1-5,同时保留来自 detail table 的 IdEvent 及其对应的 1 -5 事件来源的值。最后,我们可以为同一用户、事件和 table ID # 对 TRInfo table 执行 LEFT-JOIN。通过执行 left-join 它比 NOT IN 子选择更快。我们通过包含在 WHERE 子句
中来消除那些已经 "completed" 的记录 AND TRInfo.IdEvent IS NULL
现在,综上所述,如果准确的话,以下查询应该可以帮助您。它可能有一些您可能能够解决的小语法问题(别名、字段等)。
现在我将解释查询。为了简化原始查询的所有额外连接,我从 TRUserLite 开始并获取那些无需额外连接到 TRLite 和 TR tables 就符合条件的条目。我只是将它们加入/联合到细节和 TRInfo 以获得符合条件的记录。在连接到详细信息 table 时,我将相应的连接字段作为公共 "Dett" 结果列。一旦所有符合条件的记录都完成,然后我才加入回 TRLite 和 TR 以提取最终查询的附加数据。这使内部查询对有限的细节更加严格,然后提取其余部分。
Recommended indexes
table index
TRUserLite ( IdUser, Status ) to optimize the WHERE clause.
TRInfo ( IdUser, IdLite, IdEvent, IdTable )
SELECT
TR.Office,
TRL.`Year`,
TRL.RIFNum,
All5.IdTable
All5.IdLite,
All5.IdLiteUser,
All5.IdEvent,
All5.IdUser,
All5.Dett,
U.User,
U.Status as UserStatus,
CONCAT_WS('_',
IFNULL( TRL.Section,''),
IFNULL( TRL.InDate,''),
IFNULL( TRL.Type,''),
IFNULL( TRL.Subject,''),
IFNULL( TRL.DCU_Instance,''),
IFNULL( TRL.DC_Instance,'') ) AS Essential
from
( SELECT
TRUL.IDUser,
TRUL.IdLite,
TRUL.IdLiteUser,
1 as IdTable,
TD1.IdEvent,
CONCAT_WS('_',
IFNULL( TD1.TypeT,''),
IFNULL( TD1.In_Date,''),
IFNULL( TD1.Out_Date,'') ) AS Dett
from
TRUserLite TRUL
JOIN TRDetails1 TD1
ON TRUL.IdLite = TD1.IdLite
LEFT JOIN TRInfo
ON TRUL.IdUser = TRInfo.IdUser
AND TRUL.IdLite = TRInfo.IdLite
AND TD1.IdEvent = TRInfo.IdEvent
AND TRInfo.IdTable = 1
where
TRUL.IdUser = '@myVarInsertedEachTime'
AND TRUL.Status = 0
AND TRInfo.IdEvent IS NULL
UNION ALL
SELECT
TRUL.IDUser,
TRUL.IdLite,
TRUL.IdLiteUser,
2 as IdTable,
TD2.IdEvent,
CONCAT_WS( '_',
IFNULL( TD2.DocType,''),
IFNULL( TD2.Number,''),
IFNULL( TD2.Side,''),
IFNULL( TD2.InDate,'') ) AS Dett
from
TRUserLite TRUL
JOIN TRDetails2 TD2
ON TRUL.IdLite = TD2.IdLite
LEFT JOIN TRInfo
ON TRUL.IdUser = TRInfo.IdUser
AND TRUL.IdLite = TRInfo.IdLite
AND TD2.IdEvent = TRInfo.IdEvent
AND TRInfo.IdTable = 2
where
TRUL.IdUser = '@myVarInsertedEachTime'
AND TRUL.Status = 0
AND TRInfo.IdEvent IS NULL
UNION ALL
SELECT
TRUL.IDUser,
TRUL.IdLite,
TRUL.IdLiteUser,
3 as IdTable,
TD3.IdEvent,
CONCAT_WS('_',
IFNULL( TD3.UdiDate,''),
IFNULL( TD3.UdiType,''),
IFNULL( TD3.UdiResult,''),
IFNULL( TD3.Supervisor,''),
IFNULL( TD3.GroupIn,''),
IFNULL( TD3.ROrder,'') ) AS Dett
from
TRUserLite TRUL
JOIN TRDetails3 TD3
ON TRUL.IdLite = TD3.IdLite
LEFT JOIN TRInfo
ON TRUL.IdUser = TRInfo.IdUser
AND TRUL.IdLite = TRInfo.IdLite
AND TD3.IdEvent = TRInfo.IdEvent
AND TRInfo.IdTable = 3
where
TRUL.IdUser = '@myVarInsertedEachTime'
AND TRUL.Status = 0
AND TRInfo.IdEvent IS NULL
UNION ALL
SELECT
TRUL.IDUser,
TRUL.IdLite,
TRUL.IdLiteUser,
4 as IdTable,
TD4.IdEvent,
CONCAT_WS('_',
IFNULL( TD4.Type,''),
IFNULL( TD4.Number,''),
IFNULL( TD4.Supervisor,''),
IFNULL( TD4.PubDate,''),
IFNULL( TD4.UdiDate,''),
IFNULL( TD4.UdiType,''),
IFNULL( TD4.Result,'') ) AS Dett
from
TRUserLite TRUL
JOIN TRDetails4 TD4
ON TRUL.IdLite = TD4.IdLite
LEFT JOIN TRInfo
ON TRUL.IdUser = TRInfo.IdUser
AND TRUL.IdLite = TRInfo.IdLite
AND TD4.IdEvent = TRInfo.IdEvent
AND TRInfo.IdTable = 4
where
TRUL.IdUser = '@myVarInsertedEachTime'
AND TRUL.Status = 0
AND TRInfo.IdEvent IS NULL
UNION ALL
SELECT
TRUL.IDUser,
TRUL.IdLite,
TRUL.IdLiteUser,
5 as IdTable,
TD5.IdEvent,
CONCAT_WS('_',
IFNULL( TD5.Type,''),
IFNULL( TD5.Number,''),
IFNULL( TD5.Supervisor,''),
IFNULL( TD5.PubDate,''),
IFNULL( TD5.Result,'') ) AS Dett
from
TRUserLite TRUL
JOIN TRDetails5 TD5
ON TRUL.IdLite = TD5.IdLite
LEFT JOIN TRInfo
ON TRUL.IdUser = TRInfo.IdUser
AND TRUL.IdLite = TRInfo.IdLite
AND TD5.IdEvent = TRInfo.IdEvent
AND TRInfo.IdTable = 5
where
TRUL.IdUser = '@myVarInsertedEachTime'
AND TRUL.Status = 0
AND TRInfo.IdEvent IS NULL ) All5
JOIN Users U
ON All5.IdUser = U.IdUser
JOIN TRLite TRL
ON All5.IdLite = TRL.IdLite
JOIN TR
ON TRL.IdOffice = TR.IdOffice
ORDER BY
TR.Office,
TRL.`Year`,
TRL.RIFNum,
All5.IdTable
(顺便说一句,我将用户 table 添加到连接中,以防您也需要这些列...可以轻松删除)
了解您的原始查询与此结果的执行时间会很有趣,即使它不能解析您的查询时间。
反馈
您目前正在查找不在 TRInfo table 中的内容。如果您可以重组它,以便将状态列添加到 TRInfo,例如 "IsRecordOpen"(夸大列名)并将其设置为 1,然后插入到 TRDetails table。然后当它完成时,将标志设置为零(不再是开放任务)。因此,这是要完成的每个待处理工作的基础,它通过事件 ID 指向相应的详细信息 table。然后您的查询将被简化为类似..
select
TR.Office,
TRL.`Year`,
TRL.RIFNum,
TRI.IdTable
TRI.IdLite,
TRUL.IdLiteUser,
TRI.IdEvent,
TRI.IdUser,
case when TRI.IdTable = 1 THEN
CONCAT_WS('_',
IFNULL( TD1.TypeT,''),
IFNULL( TD1.In_Date,''),
IFNULL( TD1.Out_Date,'') )
when TRI.IdTable = 2 THEN
CONCAT_WS( '_',
IFNULL( TD2.DocType,''),
IFNULL( TD2.Number,''),
IFNULL( TD2.Side,''),
IFNULL( TD2.InDate,'') )
when TRI.IdTable = 3 THEN
CONCAT_WS('_',
IFNULL( TD3.UdiDate,''),
IFNULL( TD3.UdiType,''),
IFNULL( TD3.UdiResult,''),
IFNULL( TD3.Supervisor,''),
IFNULL( TD3.GroupIn,''),
IFNULL( TD3.ROrder,'') )
when TRI.IdTable = 4 THEN
CONCAT_WS('_',
IFNULL( TD4.Type,''),
IFNULL( TD4.Number,''),
IFNULL( TD4.Supervisor,''),
IFNULL( TD4.PubDate,''),
IFNULL( TD4.UdiDate,''),
IFNULL( TD4.UdiType,''),
IFNULL( TD4.Result,'') )
when TRI.IdTable = 5 THEN
CONCAT_WS('_',
IFNULL( TD5.Type,''),
IFNULL( TD5.Number,''),
IFNULL( TD5.Supervisor,''),
IFNULL( TD5.PubDate,''),
IFNULL( TD5.Result,'') )
END AS Dett,
CONCAT_WS('_',
IFNULL( TRL.Section,''),
IFNULL( TRL.InDate,''),
IFNULL( TRL.Type,''),
IFNULL( TRL.Subject,''),
IFNULL( TRL.DCU_Instance,''),
IFNULL( TRL.DC_Instance,'') ) AS Essential
from
TRInfo TRI
JOIN TRLite TRL
on TRI.IdLite = TRL.IdLite
JOIN TR
on TRL.IdOffice = TR.IdOffice
JOIN TRUserLite TRUL
on TRI.IdUser = TRUL.IdUser
AND TRI.IdLite = TRUL.IdLite
AND TRUL.Status = 0
LEFT JOIN TRDetails1 TD1
ON TRI.TableID = 1
AND TRI.IdEvent = TD1.IdEvent
LEFT JOIN TRDetails2 TD2
ON TRI.TableID = 2
AND TRI.IdEvent = TD2.IdEvent
LEFT JOIN TRDetails1 TD3
ON TRI.TableID = 3
AND TRI.IdEvent = TD3.IdEvent
LEFT JOIN TRDetails1 TD4
ON TRI.TableID = 4
AND TRI.IdEvent = TD4.IdEvent
LEFT JOIN TRDetails1 TD5
ON TRI.TableID = 5
AND TRI.IdEvent = TD5.IdEvent
where
TRI.IdUser = 'the user ID you want'
AND TRI.IsRecordOpen