SQL比较来自其他表的值的表属性

时间:2018-01-30 19:02:17

标签: sql oracle

我想将第一个表 InputStrings 中的值与Sql中第二个表 StringConstraints 中的值进行比较。

InputStrings

sqlobject

StringConstraints

+-----------+------------+-----------+
|   Name    |  Address   |   City    |
+-----------+------------+-----------+
| abcabcabc | xyxyxyxy   | qweqweqwe |
| abbcabc   | xyxxyxy    | qweqwe    |
| abccabc   | xyxyxyxyxy | qwweqwe   |
+-----------+------------+-----------+

我想检查 Name 列中值的长度是否在2到20之间; 地址列中的值长度介于4和10之间; City 列中的值和长度介于5和10之间。

我的表中有68行。 InputString中有40列。我无法为每一行写作。

任何人都可以帮我制作一个通用的解决方案来比较这些值吗?

我是数据库领域的新手。

3 个答案:

答案 0 :(得分:0)

这将返回不良记录:

Select *
from InputStrings
where (len(Name) not between (select minlength from StringContraints where colName = 'Name')
   and
       (select maxlength from StringContraints where colName = 'Name'))
   or
      (len(Address) not between (select minlength from StringContraints where colName = 'Address')
   and
       (select maxlength from StringContraints where colName = 'Address'))
   or
      (len(City) not between (select minlength from StringContraints where colName = 'City')
   and
       (select maxlength from StringContraints where colName = 'City'))

答案 1 :(得分:0)

这是一种动态创建相同内容的方法。请记住,Stack Overflow不是编码服务。

declare @sql varchar(max) =''
    ,@Name varchar(50)
    ,@min int
    ,@max int
    ,@counter int =1;


declare csr cursor
for
select colName, minlength, [maxlength] from (values ('Name',2,20),('Address',4,10),('City',5,10)) a(colName,minlength,[maxlength])

open csr

fetch next from csr
into @Name,@min,@max

set @sql = 'select * from inputstrings where '

while @@FETCH_STATUS = 0
begin
    if(@counter =1 ) set @sql = @sql + '(len('+ @name+') not between ' + cast(@min as varchar(5)) + ' and ' + cast(@max as varchar(5)) + ') '
    else set @sql = @sql + 'or (len('+ @name+') not between ' + cast(@min as varchar(5)) + ' and ' + cast(@max as varchar(5)) + ') '

    set @counter=@counter +1

    fetch next from csr
    into @Name,@min,@max
end

close csr
deallocate csr

print @sql

exec(@sql)

答案 2 :(得分:0)

你没有说明你的DMBS,所以这是Postgres的解决方案:

select *
from (
  select i.id, 
         t.*,
         c.minlength, 
         c.maxlength,
         length(t.value) between c.minlength and c.maxlength as is_valid
  from inputstrings i
    cross join lateral jsonb_each_text(to_jsonb(i) - 'id') as t(colname, value)
    join stringconstraints c on lower(c.colname) = lower(t.colname)
) t
where not is_valid
order by id;

这首先将表inputstrings中的每一行转换为键/值对,并将其结果连接到stringconstraints表。从那里可以很容易地根据约束验证列值。这与inputstrings中的列数无关。结果将是每列一行违反约束。

对于以下设置:

create table inputstrings (id integer, name text, address text, city text);
insert into inputstrings
values
(1, 'Name OK','Some Address that is too long','City Name OK'),
(2, 'N', 'Address OK', 'Cty'),
(3, 'Good Name', 'Good Address', 'Good City');

create table stringconstraints (colname text, minlength int, maxlength int);
insert into stringconstraints
values
('Name', 2, 20),
('Address', 4, 12),
('City', 5, 15);

查询返回此结果:

id | colname | value                         | minlength | maxlength | is_valid
---+---------+-------------------------------+-----------+-----------+---------
 1 | address | Some Address that is too long |         4 |        12 | false   
 2 | name    | N                             |         2 |        20 | false   
 2 | city    | Cty                           |         5 |        15 | false   

我添加了id列,以便可以将无效的列值与实际的源行匹配。

在线示例:http://rextester.com/VVG55773

包含更多列的第二个示例:http://rextester.com/QCKG53573(请注意查询未更改)