【问题标题】:How do I make a boolean calculated field in TSQL and join on that calculated field?如何在 SQL 中创建布尔计算字段并加入该计算字段?
【发布时间】:2009-01-06 17:12:48
【问题描述】:

首先查看此代码。我似乎应该对我有用,但事实并非如此! (惊喜!)

无论如何,这是我首先尝试的:

SELECT
Status as status,
Address as ip,
PCName as pc_name,
(Numbers.Phone = 'CPU/' + PCName) as cpu_contact,
(Numbers.Phone = 'PC/' + PCName) as pc_contact,
(Numbers.Phone = 'LOGIN/' + PCName) as login_contact,
FROM IPAddress
WHERE $where  --Generated In code
JOIN Numbers
  ON ('CPU/' + PCName = Numbers.Phone) 
  OR ('PC/' + PCName = Numbers.Phone) 
  OR ('LOGIN/' + PCName = Numbers.Phone)

所以我想要的是一些布尔计算字段并在类似条件下加入。我还希望结果折叠成单行。例如,我认为当前的设置会做这样的事情:

status ip  cpu_contact pc_contact login_contact
-----------------------------------------------
foo    bar true        false      false
foo    bar false       true       false
foo    bar false       false      true

显然我更愿意

status ip  cpu_contact pc_contact login_contact
-----------------------------------------------
foo    bar true        true       true

有什么想法吗?数据库重新设计不是一种选择。如果是的话,我会这样做:-)

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    您可以使用GROUP BYSUM 折叠行:

    SELECT
      Status as status, Address as ip, PCName as pc_name,
      cast(sum(case when (Numbers.Phone = 'CPU/' + PCName) then 1 else 0 end) as bit)
        as cpu_contact,
      cast(sum(case when (Numbers.Phone = 'PC/' + PCName) then 1 else 0 end)) as bit)
        as pc_contact,
      cast(sum(case when (Numbers.Phone = 'LOGIN/' + PCName) then 1 else 0 end) as bit)
        as login_contact,
    FROM
      IPAddress
        JOIN Numbers ON 
          ('CPU/' + PCName = Numbers.Phone) OR ('PC/' + PCName = Numbers.Phone) OR 
          ('LOGIN/' + PCName = Numbers.Phone)
    WHERE
      $where  --Generated In code
    GROUP BY
      Status, Address, PCName
    

    由于您在行之间进行逻辑或,因此零和为假,而任何大于 0 的值都为真。

    【讨论】:

    • 哇,这太复杂了!那好吧。我认为它会完成工作;它也很糟糕,因为我们有很多我没有列出的列,但我宁愿程序的一部分比所有部分都复杂。谢谢!
    【解决方案2】:

    您需要使用 Case/When 进行比较。在这种情况下,我将硬编码为 1 或 0,但 T-SQL 会将硬编码的数字转换为 int。如果你想要布尔(位),你需要手动转换,像这样......

    Convert(Bit, Case When Numbers.Phone = 'CPU/' + PCName Then 1 Else 0 End) as cpu_contact,
    Convert(Bit, Case When Numbers.Phone = 'PC/' + PCName Then 1 Else 0 End) as pc_contact,
    Convert(Bit, Case When Numbers.Phone = 'LOGIN/' + PCName Then 1 Else 0 End) as login_contact,
    

    【讨论】:

      【解决方案3】:
      SELECT
      Status as status,
      Address as ip,
      PCName as pc_name,
      case when sum(case when Numbers.Phone = 'CPU/' + PCName then 1 end) > 0 then 'true' else 'false' end as cpu_contact,
      case when sum(case when Numbers.Phone = 'PC/' + PCName then 1 end) > 0 then 'true' else 'false' end as pc_contact,
      case when sum(case when Numbers.Phone = 'LOGIN/' + PCName then 1 end) > 0 then 'true' else 'false' end as login_contact
      FROM IPAddress
      JOIN Numbers
        ON ('CPU/' + PCName = Numbers.Phone) 
        OR ('PC/' + PCName = Numbers.Phone) 
        OR ('LOGIN/' + PCName = Numbers.Phone)
      WHERE -- your condition goes here
      group by status, address, pc_name   
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-12
        • 1970-01-01
        • 2014-10-12
        • 1970-01-01
        • 2021-12-25
        • 1970-01-01
        • 1970-01-01
        • 2011-03-28
        相关资源
        最近更新 更多