2016-09-07 71 views
1

有没有一种方法可以构建一个SQL语句,它将帮助我根据状态检索活动记录,然后引用另一个字段中存储的oldids?SQL从包含逗号分隔键的字段中选择

假设我想将下面的数据加入到另一个表中。对于ID = 4,意味着暗示ID 1,3和4结合在一起,幸存的记录是4.

所以,当我想要与另一个表一起加入时,如何将scvid 104链接到ID 1,3和4的交易?

select * 
from tbl 
where scvid in (id, oldids)? 

的样本数据:

scvid id oldid status 
------------------------------ 
101  1  NULL  0 
102  2  NULL  1 
103  3  NULL  0 
104  4  [1,3]  1 
+6

不要将数据存储为逗号分隔的项目。这只会导致你很多麻烦。 – jarlh

+2

你使用什么数据库(MSSQL,MySql,....)? – valex

回答

0

你没有提到你的数据库系统。这里是SQL Server(TSQL)的解决方案。您也可以在其他RDBMS有细微的变化

SELECT 
    t1.*, t2.scvid as NEWID 
FROM 
    tbl t1 
JOIN 
    tbl t2 ON 
    -- first case: if the record is main with [1,3] we link it to the the self 
    (t1.scvid = t2.scvid) AND (t2.oldid IS NOT NULL) 
    OR 
    -- second case: we bulid ",1,3," from "[1,3]" 
    -- then we get condition ",1,3," LIKE "%,id,%" 
    -- for the id = 1 and 3 it's TRUE 
    (REPLACE(REPLACE(t2.oldid,'[',','),']',',') 
     LIKE '%,'+CAST(t1.id as VARCHAR(100))+',%') 
    AND (t1.oldid IS NULL) 

结果使用它:

scvid id oldid status NEWID 
101 1 NULL 0   104 
103 3 NULL 0   104 
104 4 [1,3] 1   104 

这本记录输出新列NEWIDId这样你就可以加入或以其他方式使用。

0

对于Postgres,您可以通过将逗号分隔列表转换为数组来完成此操作。

事情是这样的:

样品设置:

create table some_table (id integer); 
insert into some_table values (4), (6), (8); 

create table service (svcid integer, id integer, oldid text, status integer); 
insert into service 
values 
(101, 1, NULL , 0), 
(102, 2, NULL , 1), 
(103, 3, NULL , 0), 
(104, 4, '1,3', 1); 

some_table获得的所有行id要么是service表的id列或任何那些在oldid列中,您可以使用:

select * 
from some_table st 
    join (
    select svcid, id, oldid, status, string_to_array(s.oldid, ',')::int[]||id as all_ids 
    from service s 
) s on st.id = any(s.all_ids) 

返回:

id | svcid | id | oldid | status | all_ids 
---+-------+----+-------+--------+-------- 
4 | 104 | 4 | 1,3 |  1 | {1,3,4} 
0

这适用于SQL Server。
由于LIKE语法支持负数字字符类别为[^0-9]

select 
old.scvid as old_scvid, old.id as old_id, 
new.scvid as new_scvid, new.id as new_id, new.oldid as new_oldids 
from tbl new 
left join tbl old 
    on (old.status = 0 and new.oldid like concat('%[^0-9]',old.id,'[^0-9]%')) 
    where new.status = 1 
    and new.oldid is not null 

糟糕的是,该表没有“newid”字段,而不是带有范围的“oldid”字段。
这会让参与更容易。

+0

(标准)SQL LIKE只支持'_'和'%'作为通配符。 “LIKE”不支持“模式”或类似的“正则表达式”。 –