Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 识别一列中存在但另一列中不存在的不同代码_Sql_Sql Server - Fatal编程技术网

Sql 识别一列中存在但另一列中不存在的不同代码

Sql 识别一列中存在但另一列中不存在的不同代码,sql,sql-server,Sql,Sql Server,我的数据如下表所示。前两列是带有管道分隔符的国家/地区代码列表。有两组行的秩分别为1和2。 我试图识别CountryList1中存在的国家代码,但在给定等级上CountryList1列中不存在。对于排名1的行,HN JP SK和KY在CountryList1中存在,但在CountryList2中不存在。同样,对于秩2行。HN存在于CountryList1中,但不存在于CountryList2中。 我期待像第二个表一样的输出。我不想使用函数或过程,而是尝试使用select语句来完成它 输入 输出

我的数据如下表所示。前两列是带有管道分隔符的国家/地区代码列表。有两组行的秩分别为1和2。 我试图识别CountryList1中存在的国家代码,但在给定等级上CountryList1列中不存在。对于排名1的行,HN JP SK和KY在CountryList1中存在,但在CountryList2中不存在。同样,对于秩2行。HN存在于CountryList1中,但不存在于CountryList2中。 我期待像第二个表一样的输出。我不想使用函数或过程,而是尝试使用select语句来完成它

输入

输出

DistinctCountry1    ||  RAN
====================||========  
HN                  ||  1   
JP                  ||  1   
SK                  ||  1   
KY                  ||  1   
JP                  ||  2   

你的数据结构很糟糕。您应该将列表中的元素作为单独的值存储在行中。但是您可以通过拆分这些值来做一些事情。SQL Server 2016具有
string\u split()
。对于早期版本,您可以在web上找到

with tc as (
      select t.*, s.country1
      from t cross apply
           (string_split(t.countrylist1, '|') s(country1) 
     )
select distinct t.country1, t.rnk
from tc
where not exists (select 1
                  from t t2
                  where tc.rnk = t2.rnk and
                        tc.country in (select value from string_split(t2.country_list))
                 );

这是没有效率的。而且,使用现有的数据结构,几乎没有提高性能的余地。

您的数据结构很糟糕。您应该将列表中的元素作为单独的值存储在行中。但是您可以通过拆分这些值来做一些事情。SQL Server 2016具有
string\u split()
。对于早期版本,您可以在web上找到

with tc as (
      select t.*, s.country1
      from t cross apply
           (string_split(t.countrylist1, '|') s(country1) 
     )
select distinct t.country1, t.rnk
from tc
where not exists (select 1
                  from t t2
                  where tc.rnk = t2.rnk and
                        tc.country in (select value from string_split(t2.country_list))
                 );

这是没有效率的。而且,对于现有的数据结构,几乎没有提高性能的余地。

这里有一个很好的循环,您可以使用它:

declare @holding table (country1 varchar(max), country2 varchar(max), rank int)
declare @iterator int=1
declare @countrylistoriginal1 varchar(max) 
declare @countrylistoriginal2 varchar(max) 
declare @countrylist1  varchar(max) 
declare @countrylist2  varchar(max) 
declare @rank  int 
while @iterator<=(select max(rowid) from #temp2)
begin
select @countrylistoriginal1=countrylist1+'|',  @rank=[rank] 
from yourtable where rowid=@iterator
while @countrylistoriginal1<>''  
begin
set @countrylist1=left(@countrylistoriginal1,(charindex('|',@countrylistoriginal1)))
set @countrylistoriginal1=replace(@countrylistoriginal1, @countrylist1,'')
select @countrylistoriginal2=countrylist2+'|'  
from yourtable where rowid=@iterator
while @countrylistoriginal2<>''   
begin 
set @countrylist2=left(@countrylistoriginal2,(charindex('|',@countrylistoriginal2)))
set @countrylistoriginal2=replace(@countrylistoriginal2, @countrylist2,'')
insert @holding
select replace(@countrylist1,'|',''), replace(@countrylist2,'|',''), @rank
end
end
set @iterator=@iterator+1
end

select distinct  a.country1,  a.rank from @holding a
left join @holding b on a.country1=b.country2 and a.rank=b.rank where b.country2 is null
declare@holding table(country1 varchar(max)、country2 varchar(max)、rank int)
声明@iterator int=1
声明@countrylistoriginal1 varchar(最大值)
声明@countrylistoriginal2 varchar(最大值)
声明@countrylist1 varchar(最大值)
声明@countrylist2 varchar(最大值)
声明@rank int

@iterator这里有一个很好的循环,您可以使用它:

declare @holding table (country1 varchar(max), country2 varchar(max), rank int)
declare @iterator int=1
declare @countrylistoriginal1 varchar(max) 
declare @countrylistoriginal2 varchar(max) 
declare @countrylist1  varchar(max) 
declare @countrylist2  varchar(max) 
declare @rank  int 
while @iterator<=(select max(rowid) from #temp2)
begin
select @countrylistoriginal1=countrylist1+'|',  @rank=[rank] 
from yourtable where rowid=@iterator
while @countrylistoriginal1<>''  
begin
set @countrylist1=left(@countrylistoriginal1,(charindex('|',@countrylistoriginal1)))
set @countrylistoriginal1=replace(@countrylistoriginal1, @countrylist1,'')
select @countrylistoriginal2=countrylist2+'|'  
from yourtable where rowid=@iterator
while @countrylistoriginal2<>''   
begin 
set @countrylist2=left(@countrylistoriginal2,(charindex('|',@countrylistoriginal2)))
set @countrylistoriginal2=replace(@countrylistoriginal2, @countrylist2,'')
insert @holding
select replace(@countrylist1,'|',''), replace(@countrylist2,'|',''), @rank
end
end
set @iterator=@iterator+1
end

select distinct  a.country1,  a.rank from @holding a
left join @holding b on a.country1=b.country2 and a.rank=b.rank where b.country2 is null
declare@holding table(country1 varchar(max)、country2 varchar(max)、rank int)
声明@iterator int=1
声明@countrylistoriginal1 varchar(最大值)
声明@countrylistoriginal2 varchar(最大值)
声明@countrylist1 varchar(最大值)
声明@countrylist2 varchar(最大值)
声明@rank int
当@iterator尝试这个

表架构和数据

CREATE TABLE [tableName](
    [CountryList1] [nvarchar](50) NULL,
    [CountryList2] [nvarchar](50) NULL,
    [RANK] [int] NULL
) 

INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'HN|IN|US', N'GB|CA|CH|CA', 1)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'JP|CH ', N'IN|US|LU', 1)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'HN|SK|KY', N'GB|CA', 1)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'FI', N'IN|MO', 1)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'HN|IN|US', N'HN ', 2)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'JP|CH', N'CH|IN|US', 2)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'HN', N'NO', 2)
SQL查询

;WITH cte AS
(   SELECT DISTINCT * 
    FROM   (SELECT [value] AS DistinctCountry1, 
                   [rank], 
                   Rtrim(Ltrim([value])) + Cast([rank] AS NVARCHAR(max)) AS colX 
            FROM   tablename 
                   CROSS apply String_split([countrylist1], '|')) tmp 
    WHERE   colx NOT IN (SELECT Rtrim(Ltrim([value])) + Cast([rank] AS NVARCHAR(max)) AS colX 
                         FROM   tablename 
                                CROSS apply String_split([countrylist2], '|')) 
) 


SELECT [distinctcountry1], [rank] 
FROM   cte 
ORDER  BY [rank]
输出

+------------------+------+
| distinctcountry1 | rank |
+------------------+------+
| FI               |    1 |
| HN               |    1 |
| JP               |    1 |
| KY               |    1 |
| SK               |    1 |
| JP               |    2 |
+------------------+------+
演示:

注意:正如其他人已经提出的,你确实应该考虑修复你的表,或者在处理数据时必须额外花费时间。p> 试试这个

表架构和数据

CREATE TABLE [tableName](
    [CountryList1] [nvarchar](50) NULL,
    [CountryList2] [nvarchar](50) NULL,
    [RANK] [int] NULL
) 

INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'HN|IN|US', N'GB|CA|CH|CA', 1)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'JP|CH ', N'IN|US|LU', 1)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'HN|SK|KY', N'GB|CA', 1)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'FI', N'IN|MO', 1)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'HN|IN|US', N'HN ', 2)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'JP|CH', N'CH|IN|US', 2)
INSERT [tableName] ([CountryList1], [CountryList2], [RANK]) VALUES (N'HN', N'NO', 2)
SQL查询

;WITH cte AS
(   SELECT DISTINCT * 
    FROM   (SELECT [value] AS DistinctCountry1, 
                   [rank], 
                   Rtrim(Ltrim([value])) + Cast([rank] AS NVARCHAR(max)) AS colX 
            FROM   tablename 
                   CROSS apply String_split([countrylist1], '|')) tmp 
    WHERE   colx NOT IN (SELECT Rtrim(Ltrim([value])) + Cast([rank] AS NVARCHAR(max)) AS colX 
                         FROM   tablename 
                                CROSS apply String_split([countrylist2], '|')) 
) 


SELECT [distinctcountry1], [rank] 
FROM   cte 
ORDER  BY [rank]
输出

+------------------+------+
| distinctcountry1 | rank |
+------------------+------+
| FI               |    1 |
| HN               |    1 |
| JP               |    1 |
| KY               |    1 |
| SK               |    1 |
| JP               |    2 |
+------------------+------+
演示:


注意:正如其他人已经提出的,你确实应该考虑修复你的表,或者在处理数据时必须额外花费时间。p> 修复您的数据结构,使其不令人讨厌。在一列中存储多个值的形式不好。正确,但我现在无法更改数据。您是否使用

数组
类型?您应该规范化数据库。SQL与您正在使用的数据结构变得错综复杂。@TheImpler。SQL Server有一个数组数据类型?'FI'应该在您的最终输出中,并修复您的数据结构,使其不令人讨厌。在一列中存储多个值的形式不好。正确,但我现在无法更改数据。您是否使用
数组
类型?您应该规范化数据库。SQL与您正在使用的数据结构变得错综复杂。@TheImpler。SQL Server有一个数组数据类型?'FI'也应该在最终输出中