SQL查询以有条件地选择字段值

SQL查询以有条件地选择字段值,sql,postgresql,Sql,Postgresql,我有一个SQL查询,它连接3个表以返回所需的数据。查询如下: SELECT (s.user_created, u.first_name, u.last_name, u.email, s.school_name, p.plan_name, substring( a.message, 11), u.phone1) FROM cb_school s inner join ugrp_user u

我有一个SQL查询,它连接3个表以返回所需的数据。查询如下:

SELECT (s.user_created, 
        u.first_name, 
        u.last_name, 
        u.email, 
        s.school_name, 
        p.plan_name, 
        substring( a.message, 11), u.phone1) 
FROM cb_school s
inner join ugrp_user u 
    on s.user_created = u.user_id 
inner join cb_plan p 
    on s.current_plan = p.plan_id 
inner join audit a 
    on u.user_id = a.user_id
where s.type = 'sample' 
      and a.module_short = 'sample-user' 
      and s.created_time > current_timestamp - interval '10 day';

如果所有属性都存在,查询工作正常。现在,对于我的一些行,下面的值将是
a.module\u short='sample user'
missing。但由于我已将其作为
条件包含在内,因此不会返回这些行。我试图为该字段返回一个空字符串(如果存在),否则返回当前查询的值。有没有办法做到这一点。

我想你可以在陈述时使用CASE,比如:

SELECT CASE WHEN a.module_short = 'sample-user' THEN a.module_short
       ELSE '' END AS a.module_short
FROM TableA

您可以使用
COALESCE
返回第一个NOTNULL

SELECT  COALESCE(a.module_short,'')
FROM TableA  AS a

您希望显示至少有一个模块\u短路的所有用户。 如果模块\u short包含“sample user”,那么它应该显示它,否则它应该作为模块\u short显示NULL。每个用户只需要一行,即使它有多个模块\u短路

对于这个问题,可以使用a和

示例问题

我有三张桌子

  • 用户:具有ID的用户
  • 模块:具有ID的模块
  • 用户模块:用户和模块之间的链接。用户可以有多个模型
我需要一个查询,返回至少有1个模块,其中包含2列UserName和ModuleName的所有用户。 我只为每个用户指定一行。ModuleName只应在用户拥有该模块时显示SQL。否则它将不显示模块

示例表:

with CTE as (
select
    u.name as UserName
    , CASE
        WHEN m.module = 'SQL' THEN 'SQL' ELSE NULL END as ModuleName
    , ROW_NUMBER() OVER(PARTITION BY u.id
                                 ORDER BY (CASE
        WHEN m.module = 'SQL' THEN 'Ja' ELSE NULL END) DESC) as rn
from UserModules as um
    inner join Users as u
        on um.user_id = u.id
    inner join Modules as m
        on um.module_id = m.id
        )
select UserName, ModuleName from CTE
where rn = 1
UserName    ModuleName
Manuel      NULL        
John        SQL         
Doe         SQL         
with UsersWithRownumbersBasedOnModule_short as (
SELECT s.user_created, 
        u.first_name, 
        u.last_name, 
        u.email, 
        s.school_name, 
        p.plan_name, 
        substring( a.message, 11),
        u.phone1)
        CASE    
            WHEN a.module_short = 'sample-user' 
                THEN a.module_short 
            ELSE NULL 
            END AS ModuleShort
        ROW_NUMBER() OVER(PARTITION BY u.user_id ORDER BY (
            CASE    
                WHEN a.module_short = 'sample-user' 
                    THEN a.module_short 
                ELSE NULL 
            END) DESC) as rn
FROM cb_school s
inner join ugrp_user u 
    on s.user_created = u.user_id 
inner join cb_plan p 
    on s.current_plan = p.plan_id 
inner join audit a 
    on u.user_id = a.user_id
where s.type = 'sample' 
      and s.created_time > current_timestamp - interval '10 day';)
select * from UsersWithRownumbersBasedOnModule_short
where rn = 1
用户:

id  name    
1   Manuel  
2   John    
3   Doe     
模块:

id  module
1   StackOverflow
2   SQL
3   StackExchange
4   SomethingElse
用户模块:

id  module_id   user_id
1   1           2
2   1           3
4   2           2
5   2           3
6   3           1
7   3           3
8   4           1
9   4           3
查询示例:

with CTE as (
select
    u.name as UserName
    , CASE
        WHEN m.module = 'SQL' THEN 'SQL' ELSE NULL END as ModuleName
    , ROW_NUMBER() OVER(PARTITION BY u.id
                                 ORDER BY (CASE
        WHEN m.module = 'SQL' THEN 'Ja' ELSE NULL END) DESC) as rn
from UserModules as um
    inner join Users as u
        on um.user_id = u.id
    inner join Modules as m
        on um.module_id = m.id
        )
select UserName, ModuleName from CTE
where rn = 1
UserName    ModuleName
Manuel      NULL        
John        SQL         
Doe         SQL         
with UsersWithRownumbersBasedOnModule_short as (
SELECT s.user_created, 
        u.first_name, 
        u.last_name, 
        u.email, 
        s.school_name, 
        p.plan_name, 
        substring( a.message, 11),
        u.phone1)
        CASE    
            WHEN a.module_short = 'sample-user' 
                THEN a.module_short 
            ELSE NULL 
            END AS ModuleShort
        ROW_NUMBER() OVER(PARTITION BY u.user_id ORDER BY (
            CASE    
                WHEN a.module_short = 'sample-user' 
                    THEN a.module_short 
                ELSE NULL 
            END) DESC) as rn
FROM cb_school s
inner join ugrp_user u 
    on s.user_created = u.user_id 
inner join cb_plan p 
    on s.current_plan = p.plan_id 
inner join audit a 
    on u.user_id = a.user_id
where s.type = 'sample' 
      and s.created_time > current_timestamp - interval '10 day';)
select * from UsersWithRownumbersBasedOnModule_short
where rn = 1
示例结果:

with CTE as (
select
    u.name as UserName
    , CASE
        WHEN m.module = 'SQL' THEN 'SQL' ELSE NULL END as ModuleName
    , ROW_NUMBER() OVER(PARTITION BY u.id
                                 ORDER BY (CASE
        WHEN m.module = 'SQL' THEN 'Ja' ELSE NULL END) DESC) as rn
from UserModules as um
    inner join Users as u
        on um.user_id = u.id
    inner join Modules as m
        on um.module_id = m.id
        )
select UserName, ModuleName from CTE
where rn = 1
UserName    ModuleName
Manuel      NULL        
John        SQL         
Doe         SQL         
with UsersWithRownumbersBasedOnModule_short as (
SELECT s.user_created, 
        u.first_name, 
        u.last_name, 
        u.email, 
        s.school_name, 
        p.plan_name, 
        substring( a.message, 11),
        u.phone1)
        CASE    
            WHEN a.module_short = 'sample-user' 
                THEN a.module_short 
            ELSE NULL 
            END AS ModuleShort
        ROW_NUMBER() OVER(PARTITION BY u.user_id ORDER BY (
            CASE    
                WHEN a.module_short = 'sample-user' 
                    THEN a.module_short 
                ELSE NULL 
            END) DESC) as rn
FROM cb_school s
inner join ugrp_user u 
    on s.user_created = u.user_id 
inner join cb_plan p 
    on s.current_plan = p.plan_id 
inner join audit a 
    on u.user_id = a.user_id
where s.type = 'sample' 
      and s.created_time > current_timestamp - interval '10 day';)
select * from UsersWithRownumbersBasedOnModule_short
where rn = 1
您的查询如下所示:

with CTE as (
select
    u.name as UserName
    , CASE
        WHEN m.module = 'SQL' THEN 'SQL' ELSE NULL END as ModuleName
    , ROW_NUMBER() OVER(PARTITION BY u.id
                                 ORDER BY (CASE
        WHEN m.module = 'SQL' THEN 'Ja' ELSE NULL END) DESC) as rn
from UserModules as um
    inner join Users as u
        on um.user_id = u.id
    inner join Modules as m
        on um.module_id = m.id
        )
select UserName, ModuleName from CTE
where rn = 1
UserName    ModuleName
Manuel      NULL        
John        SQL         
Doe         SQL         
with UsersWithRownumbersBasedOnModule_short as (
SELECT s.user_created, 
        u.first_name, 
        u.last_name, 
        u.email, 
        s.school_name, 
        p.plan_name, 
        substring( a.message, 11),
        u.phone1)
        CASE    
            WHEN a.module_short = 'sample-user' 
                THEN a.module_short 
            ELSE NULL 
            END AS ModuleShort
        ROW_NUMBER() OVER(PARTITION BY u.user_id ORDER BY (
            CASE    
                WHEN a.module_short = 'sample-user' 
                    THEN a.module_short 
                ELSE NULL 
            END) DESC) as rn
FROM cb_school s
inner join ugrp_user u 
    on s.user_created = u.user_id 
inner join cb_plan p 
    on s.current_plan = p.plan_id 
inner join audit a 
    on u.user_id = a.user_id
where s.type = 'sample' 
      and s.created_time > current_timestamp - interval '10 day';)
select * from UsersWithRownumbersBasedOnModule_short
where rn = 1

PS:我在SELECT之后删除了一个lose括号,您缺少1个参数,它需要3个。

您没有选择
module\u short
,因此我不知道空字符串指的是什么。@Gordon Linoff,module\u short会有条件地检查其值,因此如果该行没有指定的module\u short值,我将丢失一行。我需要所有剩余的数据,即使模块short值不是指定的值,也需要将“AND a.module_short='sample user'”移动到“ON u.user_id=a.user_id”@GeoThomas之后的内部联接中。然后只需删除该条件。或者至少提供示例数据和所需结果。这种情况下,对于指定的用户id,我可以为module_short设置多个值,但只有当module_short值='sample user'时,我才需要它的值。在所有其他情况下,我希望将该字段设置为空。我已尝试过您的解决方案,并得到一个错误:错误:语法错误位于或接近“as”行3:ELSE NULL as.message,^My bad,ELSE NULL是不必要的,如果您离开ELSE,它将使所有与大小写不匹配的字段都为空。你需要用end结束这个案子。我还删除了第一个答案,因为这不是您的问题。这种方法对我不起作用,因为模块_short的所有其他值都会多次返回所有行。我不想要这些行。这对我来说是重复的数据。请提供一个示例,说明从中检索数据的表的外观。因为它决定了如何编辑查询以避免数据“落后”。由于未选择任何字段,您还需要从审核表中选择哪些字段。