Как создать логическое вычисляемое поле в TSQL и присоединиться к этому вычисляемому полю? - PullRequest
3 голосов
/ 06 января 2009

Сначала проверьте этот код. Мне кажется, это должно работать для меня, но это не так! (Сюрприз!)

Во всяком случае, это то, что я попробовал первым:

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

Есть идеи? Редизайн базы данных не вариант. Если бы это было так, я бы сделал это: -)

Ответы [ 3 ]

4 голосов
/ 06 января 2009

Вы можете использовать GROUP BY и SUM, чтобы свернуть строки:

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

Поскольку вы выполняете логическую операцию или между строками, сумма нуля равна false, а любое значение больше 0 будет истинным.

1 голос
/ 06 января 2009
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   
1 голос
/ 06 января 2009

Вам нужно использовать 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,
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...