Given table:
+---+-------+------+---+ |id | attr | fker |did| +---+-------+------+---+ |1 | attr1 | 5 | 1| |2 | attr1 | 17 | 1| |3 | attr1 | 3 | 2| |4 | attr2 | 31 | 2| |5 | attr2 | 7 | 2| |6 | attr2 | 6 | 2| |7 | attr3 | NULL | 1| |8 | attr3 | NULL | 2| |9 | attr3 | NULL | 1| |10 | attr4 | NULL | 1| |11 | attr4 | NULL | 1| |12 | attr4 | NULL | 1| +---+-------+------+---+
I need an SQL query that would list ALL and ONLY attr’s that have ALL their fker=NULL
and all of their did=1
In this example,
- only attr4 satisifies this condition, because
- attr1 has no fker=NULL,
- attr2 doesn’t have all of its did=1 (none in fact),
- attr3 doesn’t have all of its fekr=NULL (even if it had, it has did=2).
In other words, the query’s result set should only have ‘attr4’ in its result set.
Using the following example on http://sqlfiddle.com:
CREATE TABLE IF NOT EXISTS `ha_example` ( `id` int(6) unsigned NOT NULL, `attr` varchar(200) NOT NULL, `fker` int null, `did` int(3) unsigned NOT NULL, PRIMARY KEY (`id`) ) DEFAULT CHARSET=utf8; INSERT INTO `ha_example` (`id`, `attr`, `fker`, `did`) VALUES ('1', 'attr1', '5', '1'), ('2', 'attr1', '17', '1'), ('3', 'attr1', '3', '2'), ('4', 'attr2', '31', '2'), ('5', 'attr2', '7', '2'), ('6', 'attr2', '6', '2'), ('7', 'attr3', NULL, '1'), ('8', 'attr3', NULL, '2'), ('9', 'attr3', NULL, '1'), ('10', 'attr4', NULL, '1'), ('11', 'attr4', NULL, '1'), ('12', 'attr4', NULL, '1');
I tried this SQL (with the help of a similar question here — similar but not identical):
SELECT COUNT(fker), SUM(CASE WHEN did = 1 THEN 1 ELSE 0 END), attr, he.* FROM ha_example he group by attr,did HAVING COUNT(fker) = SUM(CASE WHEN did = 1 THEN 1 ELSE 0 END)
But I am unable to come up with TOTAL count of all rows of an attr
, without giving up the group by two fields, not one.
How do I accomplish that?
Advertisement
Answer
You can use group by
and having
:
select attr from ha_example he gropu by attr having count(fker) = 0 and max(did) = min(did) and max(did) = 1;
You could also use:
having sum( fker is not null or did <> 1 ) = 0
or if you prefer:
having sum( not (fker is null and did = 1) ) = 0