#sql #sql-server #sql-server-2005
#sql #sql-сервер #sql-server-2005
Вопрос:
Вот выдержка из довольно большой таблицы (SQL Server 2005), к которой я запрашиваю:
id (primary key) | account | phone | employee | address
------------------------------------------------------------------
1 | 123 | Y | Y | N
2 | 456 | N | N | N
3 | 789 | Y | Y | Y
Мне нужно возвращать только те строки, в которых есть хотя бы один Y в phone, employee или address (здесь не показано около 10 других). Затем мне нужно упорядочить эти результаты по количеству Y, которые у них есть в любом из трех.
Я попытался получить «tagTotal» следующим образом:
SELECT
SUM(
CASE WHEN [phone] = 'Y' THEN 1 ELSE 0 END
CASE WHEN [employee] = 'Y' THEN 1 ELSE 0 END
CASE WHEN [address] = 'Y' THEN 1 ELSE 0 END
)
FROM table
GROUP BY id
это возвращает:
tagTotal
---------------
2
0
3
Я в недоумении, как объединить это с моим существующим гигантским запросом и упорядочить по нему, не добавляя каждый столбец в группу by в конце.
Комментарии:
1. ВЫПОЛНИТЕ встроенную сумму, поскольку вам не нужно суммировать по строкам.
Ответ №1:
Поскольку сумма значений, которые вам нужны, находится в одной строке, вам не нужно объединять результаты, тем самым устраняя необходимость в group by ..
SELECT
CASE WHEN [phone] = 'Y' THEN 1 ELSE 0 END
CASE WHEN [employee] = 'Y' THEN 1 ELSE 0 END
CASE WHEN [address] = 'Y' THEN 1 ELSE 0 END as Total
FROM table
Ответ №2:
Вы можете просто выполнить добавление в виде столбца, а затем упорядочить результаты. Агрегирование кажется ненужным, по крайней мере, с образцами данных в вопросе. Для каждого есть только одна строка id
.
SELECT t.*
FROM (SELECT t.*,
((CASE WHEN [phone] = 'Y' THEN 1 ELSE 0 END)
(CASE WHEN [employee] = 'Y' THEN 1 ELSE 0 END)
(CASE WHEN [address] = 'Y' THEN 1 ELSE 0 END)
) as NumYs
FROM table t
) t
WHERE NumYs > 0
ORDER BY NumYs DESC;
Ответ №3:
Попробуйте выбрать идентификатор и упорядочить по сумме?
SELECT id,
SUM(
CASE WHEN [phone] = 'Y' THEN 1 ELSE 0 END
CASE WHEN [employee] = 'Y' THEN 1 ELSE 0 END
CASE WHEN [address] = 'Y' THEN 1 ELSE 0 END
) as numsum
FROM table
ORDER BY numsum
Ответ №4:
Это должно сработать:
select *
from
(
SELECT
id,
SUM(
CASE WHEN [phone] = 'Y' THEN 1 ELSE 0 END
CASE WHEN [employee] = 'Y' THEN 1 ELSE 0 END
CASE WHEN [address] = 'Y' THEN 1 ELSE 0 END
) tagTotal
FROM table
GROUP BY id
) x
where x.tagTotal <> 0
order by x.tagTotal desc
Внутренний запрос в основном ваш, с добавлением идентификатора (который, я полагаю, вам нужен) и присвоением сумме имени. Затем это используется в качестве входных данных для внешнего запроса, исключая запросы с нулевым итогом и сортируя сначала с наибольшей суммой.
(Кстати, это небольшой запрос. Самая большая инструкция select, которую я написал, занимала более 250 строк, выполнялась за 20 минут и выполняла ежедневные отчеты о прибылях и убытках компании, занимающейся торговлей сырьевыми товарами. Это было много …)