2010-11-19 55 views
0

我在SQL Server中有一個與以下示例有點相似的視圖。使用Microsoft Query和ODBC到SQL Server,複雜的查詢

  SELECT * 
      FROM PEOPLE 
LEFT OUTER JOIN (SELECT ID 
        FROM OTHER_TABLE 
        WHERE SOME_FIELD = 'x' 
        OR SOME_FIELD = 'y' 
        OR SOME_FIELD = 'z') AS PEOPLE_TO_EXCLUDE ON PEOPLE.ID = PEOPLE_TO_EXCLUDE.ID 
      WHERE PEOPLE_TO_EXCLUDE.ID IS null 

麻煩:

我完全能夠添加和修改 「OR SOME_FIELD = 'W'」 的時代無數的。但是,我正在通過ODBC爲用戶提供這種視圖。用戶需要能夠根據自己的喜好修改內部選擇,以匹配在當天/周/月/年/當時發生的限制。我需要以一種可以輕鬆限制SOME_FIELD的方式做到這一點。

有沒有人有如何完成此建議?理想情況下,我可以給她一個看法,她可以放置一個逗號分隔的值列表,SOME_FIELD不能。由於OTHER_TABLE中的人可能有多行,因此我不能僅限於此表。例如,某人可能有SOME_FIELD ='x',但在SOME_FIELD ='s'的表中也有一行。這個人應該被排除,因爲他們有'x',即使他們也有''。所以這就是爲什麼內部選擇是必要的。

感謝您的幫助。

回答

2

不要爲EXCEL用戶創建查詢,他們總是打斷它們,然後你必須調試它們。相反,創建一個存儲過程,傳遞一個CSV。在存儲過程中,使用分割函數分割CSV並加入它。用戶將只有一個EXCEL查詢,如:

EXEC YourProcedure 'x,y,z' 

因此,他們不會中斷查詢。

要幫助拆分函數,請參閱:"Arrays and Lists in SQL Server 2008 Using Table-Valued Parameters" by Erland Sommarskog,然後有很多方法可以在SQL Server中拆分字符串。本文涵蓋幾乎所有方法的PRO和CON:

您需要創建一個拆分函數。這是一個分裂的功能如何使用:

SELECT 
    * 
    FROM YourTable        y 
    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value 

I prefer the number table approach to split a string in TSQL但也有許多方法來拆分在SQL Server中的字符串,見前面的鏈接,這說明各的優點和缺點。

對於數字表的方法來工作,你需要做的這一次表的設置,這將創建一個包含從1到10000行的表Numbers

SELECT TOP 10000 IDENTITY(int,1,1) AS Number 
    INTO Numbers 
    FROM sys.objects s1 
    CROSS JOIN sys.objects s2 
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number) 

一旦Numbers表格設置,創建此分割功能:

CREATE FUNCTION [dbo].[FN_ListToTable] 
(
    @SplitOn char(1)  --REQUIRED, the character to split the @List string on 
    ,@List  varchar(8000)--REQUIRED, the list to split apart 
) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT 
     ListValue 
     FROM (SELECT 
        LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue 
        FROM (
          SELECT @SplitOn + @List + @SplitOn AS List2 
         ) AS dt 
         INNER JOIN Numbers n ON n.Number < LEN(dt.List2) 
        WHERE SUBSTRING(List2, number, 1) = @SplitOn 
      ) dt2 
     WHERE ListValue IS NOT NULL AND ListValue!='' 
); 
GO 

您現在可以輕鬆地拆分CSV字符串轉換成表格,並加入就可以了:

Create Procedure YourProcedure 
@Filter VARCHAR(1000) 
AS 
SELECT 
    p.* 
    FROM PEOPLE p 
     LEFT OUTER JOIN (SELECT 
          o.ID 
          FROM OTHER_TABLE o 
           INNER JOIN (SELECT 
               ListValue 
               FROM dbo.FN_ListToTable(',',@Filter) 
              ) f ON o.SOME_FIELD=f.ListValue 
         ) x ON p.ID=x.ID 
    WHERE x.ID IS null 
GO 
+0

太棒了,非常感謝。 – wilbbe01 2010-11-19 19:54:14