简体   繁体   English

查找条件满足x在mysql / sql中的次数的记录

[英]Find records where condition met x number of times in mysql/sql

I'm struggling with what is a complicated SQL query for me, although I believe that it is not particularly complicated. 尽管我认为这并不是特别复杂,但我正在为我处理一个复杂的SQL查询。 I'm close to the right answer, but not quite there yet. 我接近正确的答案,但还不完全正确。

My database represents a criminal abstract. 我的数据库代表犯罪摘要。 I have three tables in my database (I've simplified my schema enormously for the purposes of this question): arrest, arrestcharges, and dispositions. 我的数据库中有三个表(出于这个问题的目的,我极大地简化了我的架构):逮捕,逮捕指控和处分。

Each defendant can have multiple arrests (defendant table not included for simplification). 每个被告可以逮捕多个人(为简化起见,不包括被告人表格)。 Each arrest can have multiple charges, which are in the arrestcharges table. 每个逮捕可以有多个指控,这些指控在“逮捕指控”表中。 And each charge has a grade and is associated with a disposition (guilty, not guilty, etc...). 而且每项指控都有其等级,并与处分有罪(有罪,无罪等)相关联。 The dispositions are categorized so that 0=some form of guilt disposition, 1=a non-guilty disposition. 对这些处置进行了分类,以使0 =有罪感处置的某种形式,1 =无罪处置。

I want to find individuals who have been convicted of a charge graded as "M1" on more than one case. 我想找到在多个案件中被定级为“ M1”的个人。 If an individual has been convicted of more than M1, but they are in the same case, that person shouldn't be returned (unless they have another case with an M1 conviction). 如果某人被判犯有M1以上的罪名,但案件属于同一案件,则不应遣返该人(除非他们有另一起M1定罪的案件)。

A sqlfiddle link and the SQL to create and populate the table is below. 下面是sqlfiddle链接和用于创建和填充表的SQL。

I believe that this query should work, but it doesn't: 我相信此查询应该可以,但是不能:

select a.defendantid, count(a.id)  
    FROM `arrest` AS a LEFT JOIN `arrestcharges` AS ac 
          ON a.id=ac.arrestid LEFT JOIN `dispositions` AS d 
          ON ac.dispositionid=d.id 
    WHERE d.dispocategory=0 AND ac.grade="M1"  
        GROUP BY a.id HAVING COUNT(a.id) > 1 ORDER BY a.defendantid;

Based on the sql below, I expect that defendant IDs 1 and 5 should be returned since they are the only two defendants with an M1 conviction in more than one arrest. 根据下面的sql,我希望应返回被告ID 1和ID 5,因为它们是在一次以上逮捕中被M1定罪的仅有的两名被告。 But the actual response I am getting is 2 and 5. 2 should not be returned b/c defendant 2 only has one arrest in the database. 但是我得到的实际答复是2和5。不应退还2。b / c被告2在数据库中只有一个被捕。

Any thoughts on what I am doing wrong? 对我在做什么错有任何想法吗?

SQLFiddle SQLFiddle

CREATE TABLE IF NOT EXISTS `arrest` (
  `id` int(6) unsigned NOT NULL,
  `defendantid` int(6) unsigned NOT NULL,
  `docketno` varchar(21) NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `arrestcharges` (
  `id` int(6) unsigned NOT NULL,
  `arrestid` int(6) unsigned NOT NULL,
  `grade` varchar(2) NOT NULL,
  `dispositionid` int(6) NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `dispositions` (
  `id` int(6) unsigned NOT NULL,
  `disposition` varchar(30) NOT NULL,
  `dispoCategory` int(1) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

INSERT INTO `arrest` (`id`, `defendantid`, `docketno`) VALUES
  ('1', '1', 'MC-51-CR-0000222-1999'),
  ('2', '1', 'MC-51-CR-0000223-1999'),
  ('3', '1', 'MC-51-CR-0000224-1999'),
  ('4', '2', 'MC-51-CR-0002343-2000'),
  ('5', '3', 'MC-51-CR-0002349-2000'),
  ('6', '3', 'MC-51-CR-0002350-2000'),
  ('7', '3', 'MC-51-CR-0002351-2010'),
  ('8', '3', 'MC-51-CR-0002352-2013'),
  ('9', '4', 'MC-51-CR-1209293-2011'),
  ('10', '5', 'MC-51-CR-2389848-1999'),
  ('11', '5', 'MC-51-CR-3893923-1999'),
  ('12', '5', 'MC-51-CR-2393912-1999');

INSERT INTO `dispositions` (`id`, `disposition`, `dispoCategory`) VALUES
  ('1', 'Guilty', '0'),
  ('2', 'Not Guilty', '1'),
  ('3', 'Guilty Plea', '0'),
  ('4', 'Dismissed', '1');

INSERT INTO `arrestcharges` (`id`, `arrestid`, `grade`, `dispositionid`)     VALUES
  ('1', '1', 'M1', '1'),
  ('2', '1', 'M', '2'),
  ('3', '2', 'F', '2'),
  ('4', '2', 'M1', '3'),
  ('5', '3', 'M1', '1'),
  ('6', '4', 'M2', '4'),
  ('7', '4', 'M1', '3'),
  ('8', '4', 'M1', '3'),
  ('9', '4', 'M1', '1'),
  ('10', '5', 'M1', '2'),
  ('11', '6', 'M1', '2'),
  ('12', '7', 'F2', '1'),
  ('13', '8', 'F3', '1'),
  ('14', '9', 'M1', '2'),
  ('15', '9', 'M1', '2'),
  ('16', '9', 'M1', '2'),
  ('17', '9', 'M1', '2'),
  ('18', '10', 'M1', '1'),
  ('19', '10', 'M1', '1'),
  ('20', '11', 'M2', '3'),
  ('21', '12', 'M1', '4'),
  ('22', '12', 'M1', '3');  

Try this query: 试试这个查询:

select a.defendantid, count(distinct(ac.arrestid)) as count
    FROM `arrest` AS a LEFT JOIN `arrestcharges` AS ac 
          ON a.id=ac.arrestid LEFT JOIN `dispositions` AS d 
          ON ac.dispositionid=d.id
    WHERE d.dispocategory=0 AND ac.grade="M1"
    GROUP BY a.defendantid HAVING count>1;

You should count the distinct number as distinct_count of rows you need and make use of having filter such as having distinct_count>1 . 您应该将不重复数计算为所需的行的distinct_count个行,并利用having诸如“ having distinct_count>1过滤器。 This way you can ensure that the count are not getting repeated. 这样,您可以确保计数不会重复。

You appear to be aggregating by the wrong column. 您似乎在汇总错误的列。 You need a.defendantid in the group by : 您需要在group by a.defendantid

SELECT a.defendantid, count(*)  
FROM `arrest` a JOIN
     `arrestcharges` ac 
      ON a.id = ac.arrestid JOIN
     `dispositions` d 
      ON ac.dispositionid = d.id 
WHERE d.dispocategory = 0 AND ac.grade = 'M1'  
GROUP BY a.defendantid
HAVING COUNT(DISTINCT a.id) > 1
ORDER BY a.defendantid;

Note that I also changed the outer joins to inner joins. 请注意,我还将外部联接更改为内部联接。 If charges and dispositions are not available, then your filtering conditions cannot be met. 如果无法提供费用和处置,则无法满足您的过滤条件。 Hence, the appropriate join is an inner join. 因此,适当的join是内部联接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM