我正在尝试创建一个考勤应用程序,但我遇到了 SQL 语句问题。我需要它来计算有多少人出现和有多少人缺席,并获得每个辖区的总数。这是我设法想出的:
选择 IFNULL(precinct, 'Totals') 作为区域,COUNT(at.member_id) 作为 delegates_present,COUNT(ab.member_id) 作为 delegates_absent,COUNT(at.member_id) + COUNT(ab.member_id) as 'total' FROM 参加 LEFT JOIN 成员 m ON at.member_id = m.id LEFT JOIN 缺勤 ab ON ab.member_id = m.id GROUP BY precinct WITH ROLLUP
但显然,缺席列没有获取任何数据,它应该在 10-00 行中有一个 1。我做错了什么?我似乎无法弄清楚。
数据集、查询、结果和 fiddle :
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 ', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="294344505b5d454c694a485a4a465a404e475a074a4644" rel="noreferrer noopener nofollow">[email protected]</a>', '704-788-9055', 1, NULL),
(2, '17698 ', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5d2d3c2f342e356f6e1d243c353232733e3230" rel="noreferrer noopener nofollow">[email protected]</a>', '704-425-8868', 1, 1),
(3, '36228 ', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cba0a8b9bebfa8a38ba8aab8a8a4b8a2aca5b8e5a8a4a6" rel="noreferrer noopener nofollow">[email protected]</a>', '704-309-5076', 1, 1),
(4, '16921 ', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c1a0a5a2b3b4b5a2a981a2a0b2a2aeb2a8a6afb2efa2aeac" rel="noreferrer noopener nofollow">[email protected]</a>', '704-791-2685', 1, NULL),
(5, '1437 ', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a1ccd6c2d3d4d5c2c9e1c2c0d2c2ced2c8c6cfd28fc2cecc" rel="noreferrer noopener nofollow">[email protected]</a>', '704-791-7373', 1, 1),
(6, '16922 ', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="452726373031262d05262436262a362c222b366b262a28" rel="noreferrer noopener nofollow">[email protected]</a>', '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
这应该有效。通过开始加入出勤表,您无需阅读完整的成员表。
让我知道它是否有效。
关于MySQL COUNT 未提供正确的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59990028/