比较varchar字符串以生成缺少的项目列表

问题描述 投票:0回答:3

我有一个带有列的表。该列使用varchar作为数据类型存储位置。这些地点使用格式-2,7 -25,30等。我正在尝试生成一个缺失位置列表,即我们没有任何客户。

地点从-30,-3030,30。我找不到一种方法来设置循环来运行所有选项。有没有办法做到这一点?

tsql ssms
3个回答
0
投票

生成所有组合。

然后将生成的内容与现有组合进行匹配。

WITH DIGITS AS
(
   SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS val(n)
),
NUMS AS
(
    SELECT (tens.n * 10 + ones.n)-50 AS n
    FROM DIGITS ones
    CROSS JOIN DIGITS tens
),
LOCATIONS AS
(
     SELECT CONCAT(n1.n,',',n2.n) AS location, n1.n as n1, n2.n as n2
     FROM NUMS n1
     JOIN NUMS n2 ON n2.n BETWEEN -30 AND 30
     WHERE n1.n BETWEEN -30 AND 30
)
SELECT loc.location
FROM LOCATIONS loc
LEFT JOIN
(
     SELECT Client_Location, COUNT(*) Cnt
     FROM dbo.Client 
     GROUP BY Client_Location
) cl ON cl.Client_Location = loc.location
WHERE cl.Client_Location IS NULL
ORDER BY loc.n1, loc.n2

2
投票

Microsoft SQL Server 2017

;WITH cte as (
    select -30 as n --anchor member
    UNION ALL
    select n + 1  --recursive member
    from cte
    where n < 31
)
select z.* 
    from ( 
        select CONCAT(y.n,',',x.n) as locations 
        from cte as x CROSS JOIN cte y 
    ) as z
    LEFT OUTER JOIN dbo.Client as cli ON cli.client_location = z.locations
where cli.client_location IS NULL
order by z.locations asc

0
投票

我会选择递归CTE。这是SNR方法的一个细微变化:

with cte as (
      select -30 as n --anchor member
      union all
      select n + 1  --recursive member
      from cte
      where n < 30
     )
select cte.x, cte.y,
       concat(cte_x.n, ',', cte_y.n) as missing_location
from cte cte_x cross join
     cte cte_y left join
     dbo.client c
     on c.client_location = concat(cte_x.n, ',', cte_y.n) 
where c.client_location is null;

或者避免concat()两次:

select cte.x, cte.y, v.location as missing_location
from cte cte_x cross join
     cte cte_y cross apply
     (values (concat(cte_x.n, ',', cte_y.n))
     ) v(location) left join
     dbo.client c
     on c.client_location = v.location
where c.client_location is null;
© www.soinside.com 2019 - 2024. All rights reserved.