繁体   English   中英

MySQL查询根据3个字段的不同返回唯一值

[英]MySQL Query to return unique values based on distinct on 3 fields

我正在尝试搜索数据库中的1个表并计算3个字段不匹配的唯一记录的数量。 我有以下内容,但根本无法使用。 我是SQL菜鸟,因此对您的帮助非常感谢!

这就是我到目前为止

<? php
SELECT COUNT(*) 
FROM (
SELECT  DISTINCT field1, field2, field3
FROM table1);
$result = $query;
$row = mysql_fetch_array($result);
echo $row;
?>

谢谢你的帮助!

编辑:我认为这种语法不能满足我的需要。

我需要根据字段“标题”,“名字”,“姓氏”与其他行的内容不匹配来对“表1”中的唯一记录进行计数。 例如下表

+---------+-----------+-----------+-----------+
|   ID    |   Title   | Firstname | Surname   |
+---------+-----------+-----------+-----------+
|    1    |    Mr     |    J      |   Doe     |
|    2    |    Mrs    |    J      |   Doe     |
|    3    |    Mr     |    A      |   James   |
|    4    |    Mr     |    J      |   Doe     |
+---------+-----------+-----------+-----------+

该查询将需要返回答案3。上表中只有1行,其中“标题”,“名字”和“姓”匹配,因此不计算在内。

我希望这一点更加清楚。 我想我对DISTINCT的功能感到困惑!

再次编辑:

“现实世界”场景是我有一个包含人员详细信息的表,并希望提取它们以发送邮件,但我不希望重复。

<?php
    $query = "select distinct field1, field2, field3 from table1"; 
    $results = mysqli_query($link, $query);    
    echo $results->num_rows;
?>

但是,仅在SQL中回答您的问题,

select count(*) from (select distinct field1, field2, field3 from table1) as x;

因为“每个派生表都必须具有自己的别名”。

更新:实际上,您对distinct的理解是准确的。 您也可以使用group by进行类似的工作,但是group by用于按列进行聚合,如下所示:

select count(*) as count, city, state from airports group by city, state;

这将为您提供每个唯一的城市,州组合的行,并为每一个出现的次数提供一列,例如

count    city     state
--------|--------|---------|
3        Boise    ID
1        Marion   OH
24       Chicago  IL
2        Newark   DE
1        Corbin   KY
1        Ames     IA
2        Stuart   FL
...

但是,如果您只是想获取该查询返回的行数,则可以使用子选择来完成该操作,就像您做的一样:

select count(*) as rows from (select count(*) from airports group by city, state) as x;

rows
--------
2324

但是没有理由在子选择中进行聚合。 这家伙说 ,两个“生成相同的查询计划”。

更新2:因此,您的问题的关键问题是您已要求解决您实际上没有的问题。 计算行数不会帮助您将邮件发送给任何人。

因此,您可能要考虑的是要过滤掉的“相同程度”。 假设您的行如下所示:

Piet, J, Mondrian, 123 Main St, Columbus, Ohio, 43209
P, NULL, Mondrian, 123 Main St Apt. 3, Columbus, Ohio, 43209
P, Jan, Mondrian, 123 Main Street #3, Bexley, Ohio 43209

在这三种情况下,假设这个人是同一个人可能是正确的,但是哪个地址是最好的呢? 您上面的查询将发送给所有这三个。 但是,如果您按姓氏和邮政编码分组,则只会为您提供上述三个中的一个。 那是正确的答案吗? 不,这三个都正确。 如果您的数据是脏数据(如果有重复数据,数据就是脏数据),那么只有您知道正确的答案,这取决于数据的脏度和处理方式。 但是我可以告诉你很多:要么冒着发送重复数据的风险,要么要花费大量时间梳理脏数据。 您必须选择哪个优先级更高,您的时间或您的外观,因为没有一个“一刀切”的查询可以解决此问题。 为了创建这样的查询,您需要手动浏览数据以找出问题所在。 显然,如果您这样做了,那么可能还需要在Excel或类似的工具中对其进行过滤。

我不确定您的PHP代码是否正确,但SQL查询是否正确(仅需要别名):

SELECT COUNT(*) 
FROM
  ( SELECT DISTINCT field1, field2, field3
    FROM table1
  ) AS x ;                                 -- you need to alias the derived table

您还可以使用以下命令:

SELECT COUNT(*) 
FROM
  ( SELECT 1                                -- doesn't matter what is here
    FROM table1
    GROUP BY field1, field2, field3
  ) AS x ; 

或此查询:

SELECT COUNT(DISTINCT field1, field2, field3) 
FROM table1 ; 

我想这就是你想要的吗?

SELECT COUNT(*) FROM table1 WHERE field1 != field2 AND field2 != field3 AND field3 != field1;

编辑:哦,等等,这就是你想要的:

SELECT * FROM People GROUP BY title, firstname, surname

您可以在此处进行操作: http : //sqlfiddle.com/#!2/f489e2/3

这是一个线索-就如何提出关于SO的问题以及如何弄清楚这一问题的答案而言...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(ID    INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,Title   VARCHAR(12) NOT NULL
,Firstname CHAR(1) NOT NULL 
,Surname  VARCHAR(12) NOT NULL 
);

INSERT INTO my_table VALUES
(1,'Mr', 'J','Doe'),
(2,'Mrs','J','Doe'),
(3,'Mr', 'A','James'),
(4,'Mr', 'J','Doe');

您提出两个矛盾的要求...

首先,DISTINCT可以做的事情...

SELECT x.*
     , y.id 
  FROM my_table x 
  LEFT 
  JOIN my_table y 
    ON y.id <x.id 
   AND y.title = x.title 
   AND y.firstname = x.firstname 
   AND y.surname = x.surname;
+----+-------+-----------+---------+------+
| ID | Title | Firstname | Surname | id   |
+----+-------+-----------+---------+------+
|  1 | Mr    | J         | Doe     | NULL |
|  2 | Mrs   | J         | Doe     | NULL |
|  3 | Mr    | A         | James   | NULL |
|  4 | Mr    | J         | Doe     |    1 |
+----+-------+-----------+---------+------+

其次,DISTINCT无法做的事情...

SELECT x.*
     , y.id 
  FROM my_table x 
  LEFT 
  JOIN my_table y 
    ON y.id <> x.id 
   AND y.title = x.title 
   AND y.firstname = x.firstname 
   AND y.surname = x.surname;
+----+-------+-----------+---------+------+
| ID | Title | Firstname | Surname | id   |
+----+-------+-----------+---------+------+
|  1 | Mr    | J         | Doe     |    4 |
|  2 | Mrs   | J         | Doe     | NULL |
|  3 | Mr    | A         | James   | NULL |
|  4 | Mr    | J         | Doe     |    1 |
+----+-------+-----------+---------+------+

暂无
暂无

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

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