Sql 如何在视图中不显示空列

Sql 如何在视图中不显示空列,sql,Sql,我已经设置了一个视图,它将多个表中的所有数据合并在一起。是否有一种写入方法,以便只显示包含非空数据的列,而不包括包含所有空值的列 增加: 对不起,我还在学习和做我的第一个大项目,所以每天似乎都是一种新的体验。我不是很清楚,这部分是因为我不确定我做事情的方式是否正确!客户是一个学院图书馆,数据库记录具体藏品的详细信息。我提到的视图是显示关于一个项目的所有数据,因此它将关于出版物、副本、作者、出版商、语言等的表放在一起。馆藏中的少数项目是论文,因此除了标准书目细节之外,还有其他细节。我不想让用户得到

我已经设置了一个视图,它将多个表中的所有数据合并在一起。是否有一种写入方法,以便只显示包含非空数据的列,而不包括包含所有空值的列

增加: 对不起,我还在学习和做我的第一个大项目,所以每天似乎都是一种新的体验。我不是很清楚,这部分是因为我不确定我做事情的方式是否正确!客户是一个学院图书馆,数据库记录具体藏品的详细信息。我提到的视图是显示关于一个项目的所有数据,因此它将关于出版物、副本、作者、出版商、语言等的表放在一起。馆藏中的少数项目是论文,因此除了标准书目细节之外,还有其他细节。我不想让用户得到与论文相关的所有空字段,如果返回的只是书籍,那么论文表字段都是空的。所以我想也许有一种方法可以不显示这些。有人评论说,这是客户机应用程序的工作,而不是数据库本身,所以我可以在进入项目的那个阶段之前一直这样做

CREATE VIEW dbo.YourView
AS
  SELECT (list of fields)
  FROM dbo.Table1 t1
  INNER JOIN dbo.Table2 t2 ON t1.ID = t2.FK_ID
  WHERE t1.SomeColumn IS NOT NULL
  AND t2.SomeOtherColumn IS NOT NULL
在视图定义中,可以包括WHERE条件,这些条件可以排除某些列为NULL的行

更新:您无法真正筛选出-您在视图定义中定义了属于视图一部分的列列表,并且此列表是固定的,不能动态更改

您可以使用
ISNULL(列“”)
构造将这些null替换为空字符串。或者,您需要处理排除显示前端中的那些列-而不是SQL视图定义中的列

我看到您可以做的唯一一件事是确保只从视图中选择那些您知道不为NULL的列:

SELECT (list of non-null fields) FROM dbo.YourView
WHERE (column1 IS NOT NULL) 

等等,但是没有简单或神奇的方法可以在一个select语句中选择所有非空的列。

通常,在查询中添加WHERE子句,例如

WHERE a IS NOT NULL AND b IS NOT NULL AND c IS NOT NULL
这里,a b c是您的列名

如果要在可能为空的列上将表连接在一起,则使用内部连接,并且不包括空值

编辑:我可能误解了-上述过滤掉行,但您可能要求过滤掉列,例如,您有多个列,并且您只希望在返回的所有行中显示至少包含一个空值的列。使用动态SQL提供了一个解决方案,因为集合列会因数据而异

下面是一个SQL查询,它构建了另一个包含适当列的SQL查询。您可以运行此查询,然后将其结果作为另一个查询提交。它假设“pk”是一个总是非空的列,例如主键-这意味着我们可以用逗号作为其他行名称的前缀

SELECT CONCAT("SELECT pk"
   CASE (count(columnA)) WHEN 0 THEN '' ELSE ',columnA' END,
   CASE (count(columnB)) WHEN 0 THEN '' ELSE ',columnB' END,
   // etc..
   ' FROM (YourQuery) base')
FROM 
   (YourQuery) As base
查询使用Count(column)工作-聚合函数忽略NULL值,因此对于完全由NULL组成的列返回0。查询生成器假定您的查询使用别名来确保没有重复的列名


虽然不能将其放入视图中,但可以将其包装为存储过程,将数据复制到另一个表(结果表)中。您还可以设置触发器,以便在基表更改时更新结果表。

在sql中无法做到这一点。

如果我们正确阅读了您的问题,则在sql中无法做到这一点。视图的输出必须是关系——在(过度)简化的术语中,它必须是矩形的。也就是说,每行必须具有相同的列数


如果您能告诉我们有关您的数据的更多信息,并让我们了解您希望对输出执行的操作,我们或许可以提供更积极的建议。

您不能在视图中执行此操作,但可以在存储过程中使用动态SQL相当轻松地执行此操作

当然,对于使用数据的客户机来说,拥有一个移位的模式并不一定是好的,但是如果您有非常稀疏的数据,并且使用数据的客户机理解不同的模式,那么这种模式可能是有效的

如果您必须拥有一个视图,您可以在视图中放置一个“header”行,您可以在循环的第一行上检查客户端,以查看您是否不想麻烦处理网格中的列或其他内容,您可以执行以下操作:

SELECT * FROM (
    -- This is the view code
    SELECT 'data' as typ
           ,int_col
           ,varchar_col
    FROM TABLE

    UNION ALL

    SELECT 'hdr' as typ
           -- note that different types have to be handled differently
           ,CASE WHEN COUNT(int_col) = 0 THEN NULL ELSE 0 END
           ,CASE WHEN COUNT(varchar_col) = 0 THEN NULL ELSE '' END
    FROM TABLE
) AS X
-- have to get header row first
ORDER BY typ DESC -- add other sort criteria here

我怀疑发生的情况是最终用户正在运行CrystalReports并抱怨所有必须手动删除的空列

实际上,可以创建一个存储过程来动态创建一个视图,而不使用无数据列。但是,在使用视图之前,您必须运行此过程


这可以接受吗?

如果格式根据内容而变化,则可能会误读表格数据……因此,如果记录1的A列有值,但记录2的A列值为空,那么该列是否应在视图中可见?这听起来像是GUI中的逻辑,而不是数据库中的逻辑。这不符合适当的数据库检索契约,因为布局可能随时发生变化。我认为她试图做的是抑制无用列。海报是这样问的吗?这将过滤掉某些列中包含空值的所有行,这与我认为海报所追求的略有不同。一个相当奇怪的要求——但你们似乎是对的。。。。隐马尔可夫模型。。。想不出任何方法来实现这一点。。。。。至少不是在SQL级别。。。。或者这只是一个不幸的词语选择,OP的真正意思是过滤掉行?我不确定……我很想这样回答,但这取决于数据库系统。我曾经认为使用临时表是可能的,但逻辑会相当复杂。这是可能的