2016-07-15 39 views
0

我試圖編寫一個select語句,它返回值如果它沒有至少3個聲明的字符,但我不知道如何讓它工作,有人能指引我走向正確的方向嗎? 有一點需要考慮,我不能爲這個練習創建一個臨時表。T-SQL select value其中value包含小於3的聲明字符

我真的沒有任何SQL,因爲我不能想象沒有臨時表的方式。

聲明的字符是a和z之間的任何字母,所以如果db中的值是'1873',那麼它會返回值,因爲它沒有至少3個聲明字符,但是如果值是'abcdefg',那麼它將不會被返回,因爲它至少有3個被聲明的字符。

有人能夠指出我的出發點嗎?

+2

由於這是一個練習,你應該表現出一些自己的努力,不是嗎? :-)可能有助於搜索'CHARINDEX'返回'0',如果搜索的字符是**不包含在字符串中,否則返回它的位置... – Shnugo

+0

我同意,你需要嘗試一些東西首先你自己,這是學習的最佳方式。您可以通過此頁面上的鏈接找到實現此任務所需的一切:https://msdn.microsoft.com/en-GB/library/ms181984.aspx – Tanner

回答

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 
; 
0

這會發現所有sys.objects中帶有X或az:

幾點說明,因爲這是一個練習,您想學習一些東西: 您可以通過將分隔字符串轉換爲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 
0

使用Numbers Table和Joins..I使用聲明字符只有4個用於演示目的

輸入:

12345 
abcdef 
ab 

申報表:只用於演示3

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 
+0

OP狀態*我不允許創建臨時表對於這個練習*? – Shnugo

+0

我沒有創建臨時表,你問的是cte的 – TheGameiswar

+0

也許我沒有正確地得到這個......你的#1沒問題,這應該存在於OP的系統中,但是'#declarecharacters'呢?你可以很容易地避免這與另一個CTE創建'a,b,c'作爲派生表與'VALUES'或'UNION ALL',因爲你正在填充你的臨時表... – Shnugo