MySQL计数未提供正确的结果
我正在尝试创建考勤应用程序,但SQL语句有问题。我需要它来计算有多少人出现,有多少人缺席,并得到每个选区的总数。以下是我的想法: 选择IfNullDiscict,“Totals”作为辖区,COUNTat.member\u id作为代表出席,COUNTab.member\u id作为代表缺席,COUNTat.member\u id+COUNTab.member\u id作为“total”,从出席人数中选择LEFT JOIN members m ON at.member\u id=m.id LEFT JOIN Descence ab ON ab.member\u id=m.id按辖区分组汇总 但是显然,缺席列没有获取任何数据,它应该在10-00行中有一个1。我做错了什么?我似乎不明白 数据集、查询、结果和小提琴:MySQL计数未提供正确的结果,mysql,Mysql,我正在尝试创建考勤应用程序,但SQL语句有问题。我需要它来计算有多少人出现,有多少人缺席,并得到每个选区的总数。以下是我的想法: 选择IfNullDiscict,“Totals”作为辖区,COUNTat.member\u id作为代表出席,COUNTab.member\u id作为代表缺席,COUNTat.member\u id+COUNTab.member\u id作为“total”,从出席人数中选择LEFT JOIN members m ON at.member\u id=m.id LEFT
DROP TABLE IF EXISTS absence;
CREATE TABLE `absence` (
`id` int(11) NOT NULL,
`member_id` varchar(255) NOT NULL,
`member_email` varchar(255) NOT NULL,
`member_phone` varchar(12) NOT NULL,
`absent` tinyint(4) NOT NULL,
`absence_desc` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `absence` (`id`, `member_id`, `member_email`, `member_phone`, `absent`, `absence_desc`) VALUES
(1, '36227 ', '', '', 1, 'Out of town with family');
DROP TABLE IF EXISTS attendance;
CREATE TABLE `attendance` (
`id` int(11) NOT NULL,
`member_id` varchar(255) NOT NULL,
`member_email` varchar(255) DEFAULT NULL,
`member_phone` varchar(12) DEFAULT NULL,
`present` tinyint(4) NOT NULL,
`alternate` tinyint(4) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `attendance` (`id`, `member_id`, `member_email`, `member_phone`, `present`, `alternate`) VALUES
(1, '11698 ', 'jmyrtle@cascosigns.com', '704-788-9055', 1, NULL),
(2, '17698 ', 'parish23@yahoo.com', '704-425-8868', 1, 1),
(3, '36228 ', 'kcrutch@cascosigns.com', '704-309-5076', 1, 1),
(4, '16921 ', 'adcrutch@cascosigns.com', '704-791-2685', 1, NULL),
(5, '1437 ', 'mwcrutch@cascosigns.com', '704-791-7373', 1, 1),
(6, '16922 ', 'bcrutch@cascosigns.com', '123-456-7890', 1, NULL);
DROP TABLE IF EXISTS members;
CREATE TABLE `members` (
`id` int(11) NOT NULL,
`last_name` varchar(20) DEFAULT NULL,
`first_name` varchar(11) DEFAULT NULL,
`middle_name` varchar(17) DEFAULT NULL,
`suffix` varchar(3) DEFAULT NULL,
`residential_address` varchar(48) DEFAULT NULL,
`mailing_address` varchar(64) DEFAULT NULL,
`precinct` varchar(5) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`ethnicity` varchar(2) DEFAULT NULL,
`gender` varchar(1) DEFAULT NULL,
`party` varchar(3) DEFAULT NULL,
`race` varchar(1) DEFAULT NULL,
`phone` varchar(12) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `members` (`id`, `last_name`, `first_name`, `middle_name`, `suffix`, `precinct`) VALUES
(1437, 'CRUTCHFIELD', 'MATTHEW', 'WILLIAM', NULL, '01-04'),
(11698, 'MYRTLE', 'JEREMY', 'ALLEN', NULL, '02-03'),
(16921, 'CRUTCHFIELD', 'ANDREW', 'DAVID', NULL, '02-08'),
(16922, 'CRUTCHFIELD', 'BRITTANY', 'RENEE', NULL, '02-08'),
(17698, 'MOFFITT', 'PARISH', 'HENRY', NULL, '02-08'),
(36227, 'CRUTCHFIELD', 'CHERYL', 'JERMYN', NULL, '10-00'),
(36228, 'CRUTCHFIELD', 'KEVIN', 'ROGER', NULL, '10-00');
SELECT IFNULL(precinct, 'Totals') as precinct,
COUNT(at.member_id) as delegates_present,
COUNT(ab.member_id) as delegates_absent,
COUNT(at.member_id) + COUNT(ab.member_id) as 'total'
FROM attendance at
LEFT JOIN members m ON at.member_id = m.id
LEFT JOIN absence ab ON ab.member_id = m.id
GROUP BY precinct WITH ROLLUP;
+----------+-------------------+------------------+-------+
| precinct | delegates_present | delegates_absent | total |
+----------+-------------------+------------------+-------+
| 01-04 | 1 | 0 | 1 |
| 02-03 | 1 | 0 | 1 |
| 02-08 | 3 | 0 | 3 |
| 10-00 | 1 | 0 | 1 |
| Totals | 6 | 0 | 6 |
+----------+-------------------+------------------+-------+
5 rows in set, 1 warning (0.08 sec)
SHOW WARNINGS;
+---------+------+---------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------+
| Warning | 1052 | Column 'precinct' in group statement is ambiguous |
+---------+------+---------------------------------------------------+
我认为你的加入顺序不对:
FROM members m
LEFT JOIN attendance at ON at.member_id = m.id
LEFT JOIN absence ab ON ab.member_id = m.id
这应该行得通。通过使用考勤表启动联接,您永远不会读取完整的成员表
让我知道它是否有效。您的问题是,您正在加入考勤表和缺勤表,然后计算每个选区有多少行。您只需要计算代理所在的行数 我的建议是取消缺席表,只使用出席表来记录出席和缺席情况。然后您可以得到如下计数:
SELECT
...
SUM(CASE WHEN member_present=1 THEN 1 ELSE 0 END) as delegates_present,
SUM(CASE WHEN member_present=0 THEN 1 ELSE 0 END) as delegates_absent,
...
考勤表中没有memberID=36227。事实上,你的查询在语义上是错误的,这不是计算结果的方式。如果这是一种练习,那么它是不确定的,但是如果是针对真实世界的应用程序,你应该考虑适当地规范化你的数据模型。这似乎应该有一个“事件”表或类似的表格来描述哪些成员可以缺席/参加,因为年龄是int11——以防任何人超过255岁、65535岁或16777215岁——虽然dob可能更有用——它可以工作,但这显示了成员表中的每个选区。我只需要查看基于考勤表中的会员id的辖区。这就是为什么我使用了另一种方式的连接。您可以在GROUP BY之前的末尾添加WHERE条件:precent IN SELECT precent FROM member m internal JOIN attention ON m.id=at.member_id@Jeremy默特尔:如果你只想考虑参加考勤的人,那么你的问题是什么?您的查询正是这样做的;它不显示任何缺勤,因为示例数据中唯一的缺勤是不在考勤表中的成员。@ThorstenKettner这就是重点。由于该成员不在考勤表中,我需要从缺勤表中给他们打电话。此考勤查询将两者结合在一起。它显示了有多少人在场,有多少人缺席。问题是根本没有计算任何缺勤情况,这使得查询不正确。我同意,使用单独的表存储出勤情况是没有帮助的。这实际上是在为您节省一个左加入,并防止数据不一致。如果两个表中都有一名与会者出席或缺席,该怎么办?您的建议没有任何意义。没有理由把它们放在同一张桌子上,也没有人会这么做