SQL Server根据返回的数据动态更改SELECT中的WHERE子句

时间:2014-08-28 11:05:55

标签: sql sql-server dynamic

我主要是一个演示/逻辑层开发人员,并且不会乱用SQL,但我有一个问题,我想知道它是否在SQL中是不可能的,因为它'不是一种完整的编程语言。

  • 我有一个字段ContactID,其上附有CompanyID
  • 在另一个表格中,CompanyID附加到CompanyName
  • 我正在尝试创建一个SELECT语句,该语句返回ONE CONTACT ID并在单独的列中,是连接到此联系人的所有公司的聚合(按名称)。

E.G

ContactID - CompanyID - CompanyName
***********************************
1           001         Lol
1           002         Haha
1           003         Funny
2           002         Haha
2           004         Lmao

我想返回

ContactID - Companies
*********************
1           Lol, Haha, Funny
2           Haha, Lmao

我已经找到了一次使用ONE Con​​tactID执行此操作的逻辑:

SELECT x.ContactID, substring(
  (
        SELECT ', '+y.CompanyName AS [text()]
        FROM TblContactCompany x INNER JOIN TblCompany y ON x.CompanyID = y.CompanyID WHERE x.ContactID = 13963
        For XML PATH (''), root('MyString'), type 
        ).value('/MyString[1]','varchar(max)') 
        , 3, 1000) 
        [OrgNames] from TblContact x WHERE x.ContactID = 13963

正如你在这里看到的,我正在使用ContactID 13963进行硬编码,这只需要返回这个人所链接的公司。

问题是当我想要在更大规模的SELECT(在整个桌子上充满ContactID' s)上返回这个聚合信息PER ROW时。

我希望x.ContactID = (this.ContactID),但我无法弄明白!

如果失败了,我可以运行一个语句来返回ContactID列表,然后在同一个StoredProc中运行另一个LOOPS通过此ContactID列表的语句(基本上执行第二个语句x次,其中x =没有.Contact ID' s)

任何帮助非常赞赏。

4 个答案:

答案 0 :(得分:4)

您想要一个相关的子查询:

SELECT ct.ContactID,
       stuff((SELECT ', ' + co.CompanyName AS [text()]
                  FROM TblContactCompany cc INNER JOIN
                       TblCompany co
                       ON cc.CompanyID = co.CompanyID
                  WHERE cc.ContactID = ct.ContactId
                  For XML PATH (''), root('MyString'), type 
             ).value('/MyString[1]', 'varchar(max)'),
             1, 2, '')
        [OrgNames]
from TblContact ct;

请注意内部子查询上的where子句。

我还做了两个其他的改变:

  1. 我更改了表别名以更好地表示表名。这使查询更容易理解。 (另外,由于您在外部查询和内部查询中使用x,因此必须更改别名。)
  2. 我将substring()替换为stuff(),这完全符合您的要求。

答案 1 :(得分:1)

您可以使用表变量来存储所需的x.ContactID,并在主查询中使用WHERE子句使用IN子句,如下所示

WHERE
...
x.ContactID IN (SELECT ContactID FROM @YourTableVariable)

答案 2 :(得分:1)

我想你需要做的就是在子查询中使用唯一表标识符,并将子查询中的表与外表x连接:

SELECT x.ContactID, substring(
  (
        SELECT ', '+z.CompanyName AS [text()]
        FROM TblContactCompany y, TblCompany z WHERE y.CompanyID = z.CompanyID AND y.ContactId = x.ContactId
        For XML PATH (''), root('MyString'), type 
        ).value('/MyString[1]','varchar(max)')
        , 3, 1000) 
        [OrgNames] from TblContact x

答案 3 :(得分:0)

不要循环或者你会遇到性能问题(通过痛苦行RBAR排队)。而是设置基于查询。

这是未经测试的,但应该让您知道它是如何工作的:

SELECT 
    x.ContactID, 
    substring(
        (SELECT ', '+y.CompanyName AS [text()]
        FROM TblContactCompany y
        WHERE x.CompanyID = y.CompanyID 
        For XML PATH (''), root('MyString'), type).value('/MyString[1]','varchar(max)') 
    , 3, 1000) 
    [OrgNames] 
FROM TblContact x

我觉得你可以使用CONCAT代替子串