我有两张桌子:
users table
+--------+---------+
| id | integer |
+--------+---------+
| phone | string |
+--------+---------+
| active | boolean |
+--------+---------+
statuses table
+---------+---------+
| id | integer |
+---------+---------+
| user_id | integer |
+---------+---------+
| step_1 | boolean |
+---------+---------+
| step_2 | boolean |
+---------+---------+
我正在LEFT OUTER JOIN
表上statuses
users
表WHERE
这样的句子:
SELECT users.id, statuses.step_1, statuses.step_2
FROM users
LEFT OUTER JOIN statuses ON users.id = statuses.user_id
WHERE (users.active='f')
ORDER BY users.id DESC
我的问题
有些用户在users
表格中有相同的电话号码,我想根据电话号码删除重复的用户。
我不想从数据库中删除它们。但只想将它们排除在此查询之外。
例如,约翰(身份证号码1)和莎拉(身份证号码2)分享相同的电话号码(+ 6012-3456789),删除其中一个,约翰或萨拉对我来说没问题。
我尝试了但是没有用?
首先:
SELECT DISTINCT users.phone
FROM users
LEFT OUTER JOIN statuses ON users.id = statuses.user_id
WHERE (users.active='f')
ORDER BY users.id DESC
第二:
SELECT users.phone, COUNT(*)
FROM users
LEFT OUTER JOIN statuses ON users.id = statuses.user_id
WHERE (users.active='f')
GROUP BY phone
HAVING COUNT(users.phone) > 1
答案 0 :(得分:1)
我会在进行连接之前执行此操作。在Postgres中,select distinct on
是一个非常有用的结构:
SELECT u.id, s.step_1, s.step_2
FROM (SELECT distinct on (phone) u.*
FROM users u
WHERE u.active = 'f'
ORDER BY phone
) u LEFT OUTER JOIN
statuses s
ON u.id = s.user_id
WHERE u.active = 'f'
ORDER BY u.id DESC;
distinct on
为括号中的任何内容返回一行。在这种情况下,这将是phone
(基于"我想根据电话号码删除重复的用户")。然后,join
不应将这些显示为重复项。
答案 1 :(得分:0)
这是一种方式
自我加入用户表并使用电话号码加入,并按比较运算符过滤任何一个重复的名称。
SELECT *
FROM (SELECT u.*
FROM users u
JOIN users u1
ON u. u.phone = u1.phone -- to
AND u.name >= u1.name) u
LEFT OUTER JOIN statuses
ON users.id = statuses.user_id
WHERE ( users.active = 'f' )
或使用ROW_NUMBER
为每个电话号码生成行号,并过滤第一个电话号码,行号为1
SELECT *
FROM (SELECT u.*,
Row_number()OVER(partition BY phone ORDER BY name) rn
FROM users u) u
LEFT OUTER JOIN statuses
ON users.id = statuses.user_id
WHERE ( users.active = 'f' )
AND rn = 1