我正在尝试搜索数据库中的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;方案是我有一个包含人员详细信息的表,并希望提取它们以发送邮件,但我不想重复。
答案 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 |
+----+-------+-----------+---------+------+