T-SQL选择值,其中值包含少于3个声明的字符

时间:2016-07-15 08:34:24

标签: sql-server sql-server-2008

我试着编写一个select语句,如果它没有至少3个声明的字符,则返回该值,但是我不能想到如何让它工作,有人能指出我正确的方向吗? 有一点需要考虑,我不允许为此练习创建一个临时表。

到目前为止,我还没有真正得到任何SQL,如果没有临时表,我就无法想到这样做。

声明的字符是a和z之间的任何字母字符,因此如果db中的值是' 1873'然后它将返回该值,因为它没有至少3个声明的字符,但如果该值是' abcdefg'然后它将不会返回,因为它至少有3个声明的字符。

有人能够指出我的起点吗?

3 个答案:

答案 0 :(得分:0)

With 
    SrcTab As (
        Select *
        From (values ('Contains x y z')
                   , ('Contains x and y')
                   , ('Contains y only')) v (SrcField)),
    CharList As (   --< CTE instead of temporary table
        Select *
        From (values ('x')
                   , ('y')
                   , ('z')) v (c))
Select SrcField
From SrcTab, CharList
Group By SrcField
Having SUM(SIGN(CharIndex(C, SrcField))) < 3 --< Count hits
;

如果不希望Distinct,我们只需要检查每一行的计数:

With 
    SrcTab As ( --< Sample Data CTE
        Select *
        From (values ('Contains x y z')
                   , ('Contains x and y')
                   , ('Contains y only')
                   , ('Contains y only')) v (SrcField))
Select SrcField
From SrcTab
Where (
    Select Count(*) --< Count hits
    From (Values ('x'), ('y'), ('z')) v (c)
    Where CharIndex(C, SrcField) > 0
) < 3
;

答案 1 :(得分:0)

这将找到所有带有x或z的sys.object:

一些解释,因为这是一个练习,你想学习一些东西: 您可以通过将分割后的字符串转换为XML来拆分它。 x,z<x>x</x><x>z</x>出现。您可以使用它来创建派生表。

我使用CTE来避免创建或声明的表...

您可以使用CROSS APPLY进行逐行操作。在这里,我使用CHARINDEX来查找您正在寻找的字符的位置。

如果找不到所有这些,则SUM为零。我使用GROUP BYHAVING来检查此内容。

希望这很清楚: - )

DECLARE @chars VARCHAR(100)='x,z';

WITH Splitted AS
(
    SELECT A.B.value('.','char') AS TheChar
    FROM
    ( 
        SELECT CAST('<x>' + REPLACE(@chars,',','</x><x>')+ '</x>' AS XML) AS AsXml
    ) AS tbl
    CROSS APPLY AsXml.nodes('/x') AS A(B)
)

SELECT name
FROM sys.objects
CROSS APPLY (SELECT CHARINDEX(TheChar,name) AS Found FROM Splitted) AS Found
GROUP BY name,Found
HAVING SUM(Found)>0

答案 2 :(得分:0)

使用Numbers Table和Joins..I我将声明的字符仅用于演示目的

输入:

12345  
abcdef  
ab  

声明表:仅用于演示..

a
b
c

输出

12345  
ab  

演示:

---表人口脚本

 Create table #t
    (
    val varchar(20) 
    )

    insert into #t
    select '12345'
    union all
    select 'abcdef'
    union all
    select 'ab'

    create table #declarecharacters
    (
    dc char(1)
    )

    insert into #declarecharacters
    select 'a'
    union all
    select 'b'
    union all
    select 'c'

使用查询

;with cte
    as
    (
    select * from #t
    cross apply
    (
    select substring(val,n,1) as strr from numbers where n<=len(val))b(outputt)
    )
    select val from 
    cte c
    left join
    #declarecharacters dc1
    on 
    dc1.dc=c.outputt
    group by val
    having 
    sum(case when dc is null then 0 else 1 end ) <3