我试图了解一些带有2000个表的xBase类型数据库。我想使用'SELECT INTO tmpDBF'语句逐个导入表,而不是将它们全部导入SQL Server数据库,然后提取我想知道的内容,例如每个列的表结构和值范围。然后,当我导入下一个表时,我希望能够针对结构不同的tmpDBF表运行相同的查询。
我希望使用交叉应用来做到这一点,但我遇到了上述错误消息。
select cols.column_name 'Name', cols.data_type 'Type', mv.minV 'Minimum'
from information_schema.columns cols
cross apply (select MIN(cols.column_name) minV FROM tmpDBF ) mv
where cols.table_name = 'tmpDBF'
有没有办法重新构建查询,还是我变成了一条死胡同?
10月6日添加:
鉴于tmpDBF
Who | Zip
--------|------
Charlie | 97689
Foxtrot | 92143
Delta | 12011
我希望看到以下结果
Name | Type | Minimum | Maximum
-----|---------|---------|--------
who | varchar | Charlie | Foxtrot
Zip | int | 12011 | 96789
我意识到最小和最大列需要转换为varchars。
答案 0 :(得分:2)
由于两个原因,这是不可能的。
但为了得到类似于你所寻找的东西,你可以像这样解决问题:
MS SQL Server 2008架构设置:
CREATE TABLE dbo.a(c1 INT, c2 INT, c3 DATE);
INSERT INTO dbo.a VALUES(1,2,'2013-04-05'),(4,5,'2010-11-10'),(7,8,'2012-07-09');
查询1 :
SELECT
MIN(c1) c1_min,MAX(c1) c1_max,
MIN(c2) c2_min,MAX(c2) c2_max,
MIN(c3) c3_min,MAX(c3) c3_max
FROM dbo.a;
<强> Results 强>:
| C1_MIN | C1_MAX | C2_MIN | C2_MAX | C3_MIN | C3_MAX |
|--------|--------|--------|--------|------------|------------|
| 1 | 7 | 2 | 8 | 2010-11-10 | 2013-04-05 |
它为您提供单行中的所有列最小值和最大值。 (它还没有动态。和我在一起......)
为了使它更具可读性,你可以使用这样的UNPIVOT:
查询2 :
SELECT
CASE X.FN WHEN 1 THEN 'MIN' ELSE 'MAX' END AS FN,
CASE X.FN WHEN 1 THEN c1_min ELSE c1_max END AS c1,
CASE X.FN WHEN 1 THEN c2_min ELSE c2_max END AS c2,
CASE X.FN WHEN 1 THEN c3_min ELSE c3_max END AS c3
FROM(
SELECT
MIN(c1) c1_min,MAX(c1) c1_max,
MIN(c2) c2_min,MAX(c2) c2_max,
MIN(c3) c3_min,MAX(c3) c3_max
FROM dbo.a)AGG
CROSS JOIN (VALUES(1),(2))X(FN)
ORDER BY X.FN;
<强> Results 强>:
| FN | C1 | C2 | C3 |
|-----|----|----|------------|
| MIN | 1 | 2 | 2010-11-10 |
| MAX | 7 | 8 | 2013-04-05 |
现在为了让它变得动态,我们必须动态构建该查询,如下所示:
查询3 :
DECLARE @cmd NVARCHAR(MAX);
SET @cmd =
'SELECT CASE X.FN WHEN 1 THEN ''MIN'' ELSE ''MAX'' END AS FN'+
(SELECT ',CASE X.FN WHEN 1 THEN '+name+'_min ELSE '+name+'_max END AS '+name
FROM sys.columns WHERE object_id = OBJECT_ID('dbo.a')
FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)')+
' FROM(SELECT '+
STUFF((SELECT ',MIN('+name+') '+name+'_min,MAX('+name+') '+name+'_max'
FROM sys.columns WHERE object_id = OBJECT_ID('dbo.a')
FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)'),1,1,'')+
' FROM dbo.a)AGG CROSS JOIN (VALUES(1),(2))X(FN) ORDER BY X.FN;';
EXEC(@cmd);
<强> Results 强>:
| FN | C1 | C2 | C3 |
|-----|----|----|------------|
| MIN | 1 | 2 | 2010-11-10 |
| MAX | 7 | 8 | 2013-04-05 |
此查询在运行时获取表的列,动态构建相应的查询并执行它。它包含三个地方的表名('dbo.a')。如果您希望它与不同的表一起使用,则需要替换所有三个表。
答案 1 :(得分:0)
尝试类似
的内容select cols.column_name 'Name', cols.data_type 'Type', mv.minV 'Minimum'
from information_schema.columns cols
cross apply (select MIN(cols.column_name) minV FROM tmpDBF
WHERE tmpDBF.CommonCol = cols.CommonCol) mv
where cols.table_name = 'tmpDBF'