在postgresql中,当行存在时,显示该行并添加一个额外的列。即使它不存在,也总是显示一行

时间:2016-08-22 23:02:04

标签: sql postgresql

我的意思是Postgresql。

例如,我有一个表格如下:

client    action     date    
 A      search     2016-08-22
 A      search     2016-08-21 
 A      search     2016-08-20
 B      search     2016-06-22
 B       Ads       2016-07-10 
 B       Ads       2016-08-20

我正在分别寻找每个客户。如果我找客户' A'和'广告'在行动中,我想返回一个表格,如:

client   action   status      last_date
 A        --    no existed     --

如果我找客户' B'和'广告'在行动中,

client   action    status    last_date
 B        Ads     existed    2016-08-20

我尝试了case when,但它会返回几行直到action = 'Ads'

出现

我尝试where action like 'Ads',但如果客户端没有此类操作,则无法返回任何内容。

我想总是显示一行来显示数据。

2 个答案:

答案 0 :(得分:0)

使用union all和#34;未找到"排在最后,只选择第一行:

select * from (
    select client, action, 'existed' status, date
    from mytable
    where client = 'A' and action = 'Ads'
    union all
    select 'A', null, 'no existed', null
) x
order by action -- nulls order last by default
limit 1

第一行是找到的行(如果存在),否则是虚拟行。

答案 1 :(得分:0)

WITH cteCross AS(
    SELECT DISTINCT client, c.SearchText
    FROM
       TableName t
       CROSS JOIN (SELECT 'Ads' as SearchText) c
    WHERE t.client = 'A'
)

SELECT
    c.client
    ,t.action
    ,CASE WHEN t.client IS NOT NULL THEN 'existed' ELSE 'No Existed' END as status
    ,MAX(date) AS last_date
FROM
    cteCross c
    LEFT JOIN TableName t
    ON c.client = t.client
    AND c.SearchText = t.action
GROUP BY
    c.client
    ,t.action
    ,CASE WHEN t.client IS NOT NULL THEN 'existed' ELSE 'No Existed' END

你必须知道你不知道的事情......

为此,您必须首先了解可能存在的所有可能组合。这就是您要搜索要搜索的值和DISTINCT客户端的交叉连接的原因。

接下来,您将返回原始表格,查看存在的内容以及不存在的内容。

如果您在cteCross中取出WHERE,它将以您希望的方式为所有客户提供结果。