【问题标题】:Using Microsoft Query and ODBC to SQL Server, complicated query使用 Microsoft Query 和 ODBC 到 SQL Server,复杂的查询
【发布时间】:2010-11-19 17:13:41
【问题描述】:

我在 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 提取 excel。用户需要能够根据自己的喜好修改内部选择,以匹配她在一天/周/月/年/等的那个时间碰巧限制的任何内容。我需要以一种允许她轻松限制 SOME_FIELD 的方式进行此操作。

是否有人对如何完成此任务有建议?理想情况下,我可以给她一个视图,她可以放置一个逗号分隔的值列表,而 SOME_FIELD 不能。由于人们可能在 OTHER_TABLE 中有多行,因此我不能专门限制她对该表的限制。例如,某人可能有 SOME_FIELD = 'x',但在表中也有 SOME_FIELD = 's' 的行。这个人应该被排除在外,因为他们有'x',即使他们也有's'。所以这就是为什么内部选择是必要的。

感谢您的帮助。

【问题讨论】:

    标签: sql sql-server excel odbc


    【解决方案1】:

    不要为 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 中拆分字符串的方法有很多。本文涵盖了几乎所有方法的优缺点:

    您需要创建一个拆分函数。这就是拆分函数的使用方式:

    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 中有多种拆分字符串的方法,请参阅上一个链接,其中解释了每种方法的优点和缺点。

    要使 Numbers Table 方法起作用,您需要执行此一次时间表设置,这将创建一个包含 1 到 10,000 行的表 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      • 1970-01-01
      相关资源
      最近更新 更多