SQL Server:如何从选择值使用变量tablename

Y.D*_*ean 0 sql-server

 SELECT
 (
     SELECT SUM(ISNULL(Volume,0))
       FROM Order_?a1.Login?
      WHERE Login = a1.Login
 ) AS SelfVolume
 FROM dbo.Account a1
Run Code Online (Sandbox Code Playgroud)

我希望子选择(【a1.Login】)中的表名匹配a1.Login外部select语句(Login表的字段Account)中的值.我怎样才能得到这个结果?

Hei*_*nzi 11

技术的答案是:通过使用动态SQL.它很复杂,容易出错且有潜在危险(谨防Bobby Tables).您的SQL将变得不可读且无法维护.你正在进入痛苦的世界.

正确的答案是:你不知道.不要为每个用户创建单独的Orders表.使用您的Account表的外键创建一个 Orders表.


如果您仍然希望继续使用这个破坏的数据库设计(请记住:您正在进入一个痛苦的世界,而您刚刚开始),您将需要以某种方式动态构建以下SQL:

 SELECT SUM(ISNULL(Login_Volume,0)) FROM
 (
     SELECT SUM(ISNULL(Volume,0)) AS Login_Volume FROM Order_SomeUser WHERE Login = 'SomeUser'
     UNION ALL
     SELECT SUM(ISNULL(Volume,0)) AS Login_Volume FROM Order_SomeOtherUser WHERE Login = 'SomeOtherUser'
     UNION ALL
     ...
 ) AS AllSums
Run Code Online (Sandbox Code Playgroud)

您可以使用目标语言(C#,Java,PHP等)以您选择的语言执行此操作,这可能是最简单和最易维护的解决方案,或者直接在T-SQL中使用T-SQL游标和循环(=艰难的方式).无论您选择哪种语言,算法都是直截了当的:

  • 循环通过你的Account桌子,得到Logins.
    • 清理该值并验证相应的Order_表是否存在.
    • 为每个帐户创建一个SQL语句.
    • 加入他们吧UNION ALL.
  • SELECT如上图所示,将它们包裹在外面.

还是那句话:如果有任何修复你的破DB的设计,而不是机会,做到这一点,它从长远来看还清.