选择SELECT的最佳方法是什么?
我有这张桌子:
t_department ID 名称
t_users ID 名称 输入
*类型可以是: 1超级用户 2 normalUser
t_department_superuser (一个部门可以有很多超级用户)
-idSuperUser -idDepartment
t_superuser_normaluser (一个超级用户可以拥有许多normalusers)
-idSuperUser -idNormalUser
最后
t_actions
-id(自动数字) -idUser(这可以是superUser或normalUser的id) -action
给出一个部门名称,例如" mainDepartment" 我需要从所有normalusers和该部门的所有超级用户的t_actions获取所有记录
我有这个,它有效,但我不是SQL专家(我使用MySQL),我认为这不是选择的最佳方法,而且t_actions将有大量行:
SELECT id,idUser,action
FROM t_actions
WHERE (idUser IN (
SELECT DISTINCT t_department_superuser.idSuperUser FROM t_department
RIGHT JOIN t_department_superuser ON t_department_superuser.idDepartment = t_department.id
LEFT JOIN t_superuser_normaluser ON t_superuser_normaluser.idSuperUser = t_department_superuser.idSuperUser
WHERE name='mainDepartment'
UNION ALL
SELECT DISTINCT t_superuser_normaluser.idNormalUser
FROM t_department
RIGHT JOIN t_department_superuser ON t_department_superuser.idDepartment = t_department.id
LEFT JOIN t_superuser_normaluser ON t_superuser_normaluser.idSuperUser = t_department_superuser.idSuperUser
WHERE name='mainDepartment')
ORDER BY id;
有什么建议让这更好吗?谢谢!!
答案 0 :(得分:1)
因为你正在使用左右连接,所以会有空记录,这就是你需要UNION的原因......你可以通过一个简单的空检查来删除UNION
SELECT id, idUser, action
FROM t_actions
WHERE idUser IN
( SELECT DISTINCT COALESCE(tsn.idNormalUser, tds.idSuperUser)
FROM t_department td
RIGHT JOIN t_department_superuser tds ON tds.idDepartment = td.id
LEFT JOIN t_superuser_normaluser tsn ON tsn.idSuperUser = tds.idSuperUser
WHERE td.name='mainDepartment'
)
ORDER BY id;
注意我还在表名中添加了别名,因此更容易写出并读取您尝试选择和加入的列。
修改
使用此表格设计的唯一可行方法是使用数据
SELECT id, idUser, action
FROM t_actions
WHERE idUser IN
((SELECT tds.idSuperUser
FROM t_department td
JOIN t_department_superusers tds ON tds.idDepartment = td.id
WHERE td.name='MAIN')
UNION
(SELECT tsn.idNormalUser
FROM t_department td
JOIN t_department_superusers tds ON tds.idDepartment = td.id
JOIN t_superuser_normaluser tsn ON tsn.idSuperUser = tds.idSuperUser
WHERE td.name='MAIN')
)
ORDER BY id;
答案 1 :(得分:0)
SELECT DISTINCT COALESCE(tsn.idNormalUser, tds.idSuperUser)
FROM t_department td
RIGHT JOIN t_department_superusers tds ON tds.idDepartment = td.id
LEFT JOIN t_superuser_normaluser tsn ON tsn.idSuperUser = tds.idSuperUser
WHERE td.name='MAIN'
返回normalusers列表:2,3,4和5,但不是超级用户(1和6)。 我正在尝试的是让所有超级用户和MAIN部门的normalusers在一列返回。
这是带有我拥有的数据(INSERTS)的表的MySQL Dump。 sqlfiddle给了我错误:\
-- MySQL dump 10.13 Distrib 5.6.17, for Win32 (x86)
--
-- Host: localhost Database: cdcol
-- ------------------------------------------------------
-- Server version 5.5.32
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `t_department`
--
DROP TABLE IF EXISTS `t_department`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_department` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) COLLATE latin1_general_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_department`
--
LOCK TABLES `t_department` WRITE;
/*!40000 ALTER TABLE `t_department` DISABLE KEYS */;
INSERT INTO `t_department` VALUES (1,'MAIN');
/*!40000 ALTER TABLE `t_department` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_department_superusers`
--
DROP TABLE IF EXISTS `t_department_superusers`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_department_superusers` (
`idDepartment` int(11) NOT NULL,
`idSuperUser` int(11) NOT NULL,
PRIMARY KEY (`idDepartment`,`idSuperUser`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_department_superusers`
--
LOCK TABLES `t_department_superusers` WRITE;
/*!40000 ALTER TABLE `t_department_superusers` DISABLE KEYS */;
INSERT INTO `t_department_superusers` VALUES (1,1),(1,6);
/*!40000 ALTER TABLE `t_department_superusers` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_superuser_normaluser`
--
DROP TABLE IF EXISTS `t_superuser_normaluser`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_superuser_normaluser` (
`idSuperUser` int(11) NOT NULL,
`idNormalUser` int(11) NOT NULL,
PRIMARY KEY (`idSuperUser`,`idNormalUser`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_superuser_normaluser`
--
LOCK TABLES `t_superuser_normaluser` WRITE;
/*!40000 ALTER TABLE `t_superuser_normaluser` DISABLE KEYS */;
INSERT INTO `t_superuser_normaluser` VALUES (1,2),(1,3),(1,4),(1,5),(6,2),(6,3),(6,4),(6,5);
/*!40000 ALTER TABLE `t_superuser_normaluser` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_users`
--
DROP TABLE IF EXISTS `t_users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_users`
--
LOCK TABLES `t_users` WRITE;
/*!40000 ALTER TABLE `t_users` DISABLE KEYS */;
INSERT INTO `t_users` VALUES (1,1),(2,2),(3,2),(4,2),(5,2),(6,1);
/*!40000 ALTER TABLE `t_users` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2014-12-23 18:47:03