问题描述
我正在使用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 |
+-------+------+-----------+----------+
我想写一个查询来选择所有未被同一公司禁用的重复项。即name
和companyid
相同。
例如
+-------+------+-----------+----------+
| 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;
有关更多详细信息,请参见:PostgreSQL: UPDATE