我对SQL非常陌生,并且已经给了一个家庭作业练习,当翻译成这样时听起来是这样的:“For each column type find the number of tables that do not contain this type of column”.我知道如何找到包含至少一种列类型的表的数量:
SELECT Data_Type, COUNT(Table_schema || '.' || table_name)
FROM Information_schema.Columns
GROUP BY Data_Type;
但是,我花了好几个小时才弄清楚如何做与此相反的事情。我试过使用WHERE:
WHERE Data_Type IS NULL
但它给出了相同的结果查询没有这一行.我已经看到解决方案时,计数表与具体命名的列(使用'join'和'not in'),但我不认为这将为这项任务工作.我认为NOT EXISTS可能会工作,但不知道如何实现它.提前感谢!
3条答案
按热度按时间i7uq4tfw1#
你可以这样做:
这里CTE
dtypes
包含数据库中存在的所有类型作为列类型。然后,对于每一种类型,我们会找到一些表,这些表至少没有一个这种类型的列。
演示here
dfddblmv2#
下面是解决这个问题的另一种方法:
这并没有提出任何优于其他方法的主张,而只是作为额外技术的演示。
查询使用公共表表达式(CTE)来确定表集。表达式
COUNT(*) OVER (PARTITION BY NULL)
同时获得成员的计数,从而避免了额外的子查询。在主查询中,
MAX(tc.total_table_cnt)
将总表计数 Package 在聚合函数中,以便它的值可以在分组查询中使用。也可以使用MIN
,因为该值对于 tc 中的所有行都是相同的。COUNT(DISTINCT (c.table_schema, c.table_name))
获取至少有一列属于该组数据类型的表的计数。行构造函数
(tc.table_schema, tc.table_name) = (c.table_schema, c.table_name)
用于连接条件。在这种情况下,与为每列使用单独的相等比较相比,没有明显的优势,但是当IN
操作符或子查询需要多列时,行构造函数非常有用。ubof19bj3#
这个问题确实需要更仔细地界定。
varchar(25)
与varchar
不同吗?在我看来,这个查询比基于信息模式的查询快50倍左右:
基本的方法是计算每种数据类型的 * 现有 * 表,然后从表的总数中减去。
我排除了系统列,并将查询限制在
public
模式。有各种不同!
值得注意的是,对information_schema的查询将所有的“ARRAY”类型合并在一起,而我的查询将
text[]
、int[]
等作为不同的类型处理。此外,信息架构不包括分区表(正确地)。您可能希望也可能不希望这样。
关于信息架构与系统目录:
相关: