SQL禁用重复的行Postgres

问题描述

我正在使用Postgres数据库,并具有下表。

                  LOB
+-------+------+-----------+----------+
| lobid | name | companyid | disabled |
+-------+------+-----------+----------+
|   1   | abc  |    101    | false    |
+-------+------+-----------+----------+
|   2   | abc  |    101    | false    |
+-------+------+-----------+----------+
|   3   | def  |    102    | false    |
+-------+------+-----------+----------+
|   4   | def  |    103    | false    |
+-------+------+-----------+----------+
|   5   | ghi  |    103    | false    |
+-------+------+-----------+----------+

我想写一个查询来选择所有未被同一公司禁用的重复项。即namecompanyid相同。

例如

+-------+------+-----------+----------+
| lobid | name | companyid | disabled |
+-------+------+-----------+----------+
|   1   | abc  |    101    | false    |
+-------+------+-----------+----------+
|   2   | abc  |    101    | false    |
+-------+------+-----------+----------+

然后,我想用一条UPDATE sql语句将所有重复项更新为禁用的true。但是,它应保留一(任意)行。也就是说,只有单打,没有重复。

例如

+-------+------+-----------+----------+
| lobid | name | companyid | disabled |
+-------+------+-----------+----------+
|   1   | abc  |    101    | false    |
+-------+------+-----------+----------+
|   2   | abc  |    101    | true     |
+-------+------+-----------+----------+
|   3   | def  |    102    | false    |
+-------+------+-----------+----------+
|   4   | def  |    103    | false    |
+-------+------+-----------+----------+
|   5   | ghi  |    103    | false    |
+-------+------+-----------+----------+

我尝试了以下方法,但这是不正确的。我仍然在结果集中看到穹顶单打:

select l.* 
from lob l 
where l.disabled = false  
and l.companyid in (
select companyid
  from lob 
  group by name,companyid,disabled
  having count(*) > 1 and disabled = false)
order by l.companyid,l.name

更新

感谢下面的Rory O'Connells回答,我运行了以下SQL:

UPDATE lob SET disabled = true WHERE lobid IN 
(select l.lobid 
from lob l 
join ( 
    select min(lobId) as lobId,name,companyid
    from lob 
    where disabled = false
    group by name,disabled
    having count(*) > 1
) k on l.name = k.name and l.companyid = k.companyid
where l.disabled = false  
and l.lobId > k.lobId
order by l.companyid,l.name)

解决方法

好的,因此您需要确定存在问题的公司/标识(如您所做的那样):

import docx

inp = input('inp: ')


def write_docx_header():
    document = docx.Document('Test.docx')
    section = document.sections[0]
    header = section.header
    paragraph = header.paragraphs[0]
    paragraph.text = inp + "\t" + inp + "\t" + inp
    paragraph.style = document.styles["Header"]
    document.save('Test.docx')


write_docx_header()

通过这些,您只想保留1条禁用= false的公司记录,对吗?因此,您需要更新不等于最小行ID(或最大行ID,请选择一个)的那些。

所以在这里使用联接。获得最小值(这还将筛选出没有记录可更新的公司)。

select min(lobId) as keepId,name,companyid
from lob 
where disabled = false
group by name,companyid,disabled
having count(*) > 1

然后,当您感到高兴时,基于l.lobId禁用更新= true

,

对于Postgres版本> 9.1(我认为),您可以使用类似以下的内容:

;WITH src as
(
  SELECT lobid,disabled,ROW_NUMBER() OVER(PARTITION BY companyid,name ORDER BY disabled) rn
  FROM lob
)
UPDATE lob
SET disabled = 'true'
FROM src 
WHERE lob.lobid = src.lobid AND src.rn>1;

SELECT *
FROM lob
ORDER BY lobid;

DbFiddle

有关更多详细信息,请参见:PostgreSQL: UPDATE

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...