可以在case语句中使用count()吗?

时间:2019-12-27 19:29:51

标签: python sql postgresql

我已将数据从csv文件复制到表stage_table中,其列为:

aid
a_name
addrid
addr1
addr2
city
pstate
country
postalcd
contactnumber
attendancekey
attendancedate
attendedyesno
action_indicator

当同一表中的action_indicator存在多次时,我试图将表中的aid列设为“ Y”(默认情况下,该列设置为“ N”)。

我尝试了此查询,但不起作用

update_address_query = ("update public.address set active_ind=case    
                         when count(aid)>1 then 'Y' end from address")    
cur.execute(update_address_query)

我收到以下错误消息:

  

psycopg2.errors.DuplicateAlias:多次指定表名“地址”

这可以通过其他任何方式纠正吗?

此地址表中的列是

  

addrid

     

addr1

     

addr2

     

城市

     

pstate

     

国家

     

postalcd

     

联系电话

     

active_indicator

示例输出应为:

  

99801,No-13 4rthcrossst,GandiNagar,班加罗尔,印度卡纳塔克邦,456009,7800912345,N

     

99802,第14交叉路5号,内鲁·纳加尔,海得拉巴,印度特兰加纳州,556001,6800612345,N

     

99803,第16交叉路15号,SardarNagar,艾哈迈达巴德,古吉拉特邦,印度,356009,9800912345,N

     

99804,第16号第7十字路口,PatelNagar,班加罗尔,卡纳塔克邦,印度,456009,5800912345,N

     

99805,第17交叉路8号,安娜·纳加尔,钦奈,泰米尔纳德邦,印度,456009,4800912345,N

     

99801,No-13 4rthcrossst,GandiNagar,Bangalore,Karnataka,印度,456009,7800912345,Y

     

99802,第14交叉路口5号,内鲁·纳加尔,海得拉巴,特伦纳纳,印度,556001,6800612345,Y

     

99803,第16交叉路15号,SardarNagar,艾哈迈达巴德,古吉拉特邦,印度,356009,9800912345,Y

     

99804,第16号第7十字路口,PatelNagar,班加罗尔,卡纳塔克邦,印度,456009,5800912345,Y

     

99805,第17交叉路8号,安娜·纳加尔,金奈,泰米尔纳德邦,印度,456009,4800912345,是

     

99801,No-13 4rthcrossst,GandiNagar,Bangalore,Karnataka,印度,456009,7800912345,Y

     

99802,第14交叉路口5号,内鲁·纳加尔,海得拉巴,特伦纳纳,印度,556001,6800612345,Y

     

99803,第16交叉路15号,SardarNagar,艾哈迈达巴德,古吉拉特邦,印度,356009,9800912345,Y

     

99804,第16号第7十字路口,PatelNagar,班加罗尔,卡纳塔克邦,印度,456009,5800912345,Y

     

99805,第17交叉路8号,安娜·纳加尔,金奈,泰米尔纳德邦,印度,456009,4800912345,是

3 个答案:

答案 0 :(得分:3)

如果我正确无误,则希望且仅当表中同一行中的active_ind存在多次时才将aid设置为'Y'。您可以使用相关子查询来获取count()

UPDATE public.address a1
       SET active_ind = CASE
                          WHEN (SELECT count(*)
                                       FROM public.address a2
                                       WHERE a2.aid = a1.aid) > 1 THEN
                            'Y'
                        END;

顺便说一句:这是CASE 表达式,而不是陈述。


编辑:

如果您不想触摸其他行的active_ind,也可以在WHERE子句中添加这样的子查询。

UPDATE public.address a1
       SET active_ind = 'Y'
       WHERE (SELECT count(*)
                     FROM public.address a2
                     WHERE a2.aid = a1.aid) > 1;

答案 1 :(得分:0)

使用row_number()来考虑window function

with sub as (
   select *, 
          row_number() over(partition by aid order by pk_id) AS rn  --- USE PRIMARY KEY
   from public.address
)

update public.address a
set active_ind = 'Y'
from sub
where a.pk_id = sub.pk_id        --- USE UNIQUE IDENTIFIER OR PRIMARY KEY
  and sub.rn > 1

Online Demo

答案 2 :(得分:0)

您的问题与您想要的输出不符。您的所有记录均已更新,因为您的所有记录在aid上都有重复项。 因此,这种情况类似于数据库问题的设计。如果您的Postgres版本小于12(当前),则可以尝试使用OIDS列查找最旧的行,并用'N'标记为active_indicator。其余的将标记为“ Y”。 代码将如下所示:

UPDATE test_so SET active_indicator = 'Y';

UPDATE test_so SET active_indicator = 'N'
FROM (SELECT *, oid, row_number() over (partition by addrid order by oid) AS rank
        FROM test_so) a
WHERE a.rank = 1
AND test_so.oid = a.oid;

但是为此目的最好使用时间戳。