Сохранить результаты предложения select в запросе для повторного использования в том же запросе? - PullRequest
0 голосов
/ 27 сентября 2019

Я хочу создать запрос, который показывает количество столбцов, которые равны определенному значению, но показывают результаты только в том случае, если это число равно 2 (в Microsoft SQL Server).

Это то, чтоУ меня так далеко:

SELECT Menu.id,
       (
        select count(*)
        from (values (Menu.item1, Menu.item2, Menu.item3) as v(col)
        where v.col = 'banana'
       ) as numBananas
FROM Menu
WHERE (
       select count(*)
       from (values (Menu.item1, Menu.item2, Menu.item3) as v(col)
       where v.col = 'banana'
      ) = 2;

Есть ли способ избежать избыточного оператора select count (*) в предложении SELECT и предложении WHERE?Я пробовал ниже, но это не работает:

SELECT Menu.id,
       (
        select count(*)
        from (values (Menu.item1, Menu.item2, Menu.item3) as v(col)
        where v.col = 'banana'
       ) as numBananas
FROM Menu
WHERE
    numBananas = 2;

Ответы [ 3 ]

3 голосов
/ 27 сентября 2019

Помимо использования производной таблицы / внешнего запроса в качестве Дейла, как показано, вы также можете использовать CROSS APPLY

SELECT  Menu.id, numBananas
FROM    Menu
CROSS APPLY
(
    select  count(*)
    from (
        values (Menu.item1), (Menu.item2), (Menu.item3)
    ) as v(col)
    where v.col = 'banana'
) bananacount (numBananas)
where numBananas    = 2

Кстати, ваш исходный запрос v(col) не верен.Я думаю, что это должно быть так

from (
    values (Menu.item1), (Menu.item2), (Menu.item3)
) as v(col)

Или, если вы предпочитаете CTE подход

; with cte as
(
    SELECT  Menu.id,
        (
            select  count(*)
            from (
                values (Menu.item1), (Menu.item2), (Menu.item3)
            ) as v(col)
            where   v.col = 'banana'
        ) as numBananas
    FROM    Menu
) 
select  *
from    cte
WHERE   numBananas = 2
2 голосов
/ 27 сентября 2019

Просто добавьте дополнительный уровень запроса, чтобы использовать любые результаты подзапроса, например

Также я исправил синтаксическую ошибку на as v(col)

select id, NumBananas
from (
  select Menu.id, (
      select count(*)
      from (values (Menu.item1), (Menu.item2), (Menu.item3)) as v(col)
      where v.col = 'banana'
    ) NumBananas
  from Menu
) X
where X.NumBananas = 2;
1 голос
/ 27 сентября 2019

Почему отключить?Просто выполните:

select m.*
from menu m
where ((case when m.item1 = 'banana' then 1 else 0 end) +
       (case when m.item2 = 'banana' then 1 else 0 end) +
       (case when m.item3 = 'banana' then 1 else 0 end)
      ) = 2;

Если вы хотите отменить поворот, вы можете использовать подзапрос:

select m.*
from menu m cross apply
     (select count(*) as cnt
      from (values (m.item1), (m.item2), (m.item3)) v(item)
      where item = 'banana'
     ) x
where cnt = 2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...