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

时间:2014-05-17 00:04:09

标签: mysql sql

我正在尝试搜索数据库中的1个表,并计算3个字段不匹配的唯一记录数。我有以下但它根本不起作用。我是一个SQL菜鸟所以任何帮助真的很感激!

这是我到目前为止所拥有的

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

感谢您的帮助!

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

我需要计算&#34;表1和#34;中的唯一记录。在字段&#34; title&#34;,&#34; firstname&#34;,&#34; surname&#34;的基础上不匹配其他行内容。例如下表

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

查询需要返回答案3.上表中只有一行&#34; title&#34;,&#34; firstname&#34; &安培; &#34;姓&#34;匹配,因此不计算在内。

我希望这更清楚一点。我想我必须对DISTINCT的作用感到困惑!

再次编辑:

现实世界&#34;方案是我有一个包含人员详细信息的表,并希望提取它们以发送邮件,但我不想重复。

4 个答案:

答案 0 :(得分:2)

<?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;

因为"every derived table must have its own alias."

更新:您对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

但是没有理由在subselect中进行聚合的开销。根据{{​​3}},这两个“生成相同的查询计划。”

更新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或类似的东西中过滤它。

答案 1 :(得分:2)

我不确定您的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 ; 

答案 2 :(得分:0)

我认为这就是你想要的?

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

答案 3 :(得分:0)

这里有一条线索 - 关于如何就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 |
+----+-------+-----------+---------+------+