#sql #sql-server-2005 #subquery #where-clause #having
#sql #sql-server-2005 #подзапрос #предложение where #наличие
Вопрос:
Хорошо, у меня более миллиона записей, и мне нужно выбрать всю информацию из базы данных, где количество столбцов больше или равно 10.
Я знаю, что, используя having, я должен использовать group by и используя where, я не могу использовать агрегированные функции с операторами, поэтому то, что я хочу в псевдокоде, это
Select column1,column2,column3
From MYdatabase
Where count(column1) > 10
Вот тут я и застрял. Должен ли я использовать подзапрос и добавлять столбец с именем count? Я не уверен, как бы я это запрограммировал, и, поскольку я начинающий пользователь SQL, я, возможно, смотрю в совершенно неправильном направлении.
Весь мой запрос приведен ниже, я хочу изменить, если это так, будут выбраны только записи с count (callid) >=10.
Select
FiscalMonthYear,
'MyCenter' = Case EP.Center
When 'Livermore Call Center' Then 'LCC'
When 'Natomas Call Center' Then 'NCC'
When 'Concord Call Center' Then 'CCC'
When 'Virtual Call Center' Then 'VCC'
When 'Morgan Hill Call Center' Then 'MHCC'
Else Center
End,
ECH.segstart,
ECH.consulttime,
EP.Queue,
(EP.MgrFName ' ' EP.MgrLName)AS Manager,
(EP.SupFName ' ' EP.SupLName)AS Supervisor,
(EP.RepFName ' ' EP.RepLName)As Agent,
EP.RepPERNR,
LEFT(ECH.segstart, 19) as SegmentDateTime,
ECH.origlogin,
ECH.dialed_num,
ECH.segment,
ECH.SegStart_Date,
ECH.callid
FROM CMS_ECH.dbo.CaliforniaECH ECH
INNER JOIN CAPLESQL02.InfoQuest.dbo.IQ_Employee_Avaya_Id A ON ECH.origlogin = A.AvayaID
AND getdate () BETWEEN StartDate AND EndDate
INNER JOIN CAPLESQL02.InfoQuest.dbo.IQ_Employee_Profiles_v3 EP ON A.IQID = EP.RepID
AND getdate () BETWEEN RepToSup_StartDate and RepToSup_EndDate
AND getdate () BETWEEN SupToMgr_StartDate and SupToMgr_EndDate
AND getdate () BETWEEN RepQueue_StartDate and RepQueue_EndDate
INNER JOIN Cal_RemReporting.dbo.udFiscalMonthTable f on ECH.SegStart_Date = f.Tdate
Where dialed_num not like '______'
AND dialed_num not like ''
AND dialed_num not like '_______'
and EP.Center is NOT Null
and EP.Center not like 'Comm Ops'
and EP.Center not like 'Same Day Group'
and MgrLName not like 'Hollman'
and consulttime > 0
and ECH.SegStart_Date between getdate()-90 and getdate()-1
and EP.Queue not IN ('BST','Collections', 'DST','DSR','Escalations','Cable Store')
Я сам решил проблему, используя внутреннее объединение запроса, который выбирает 10 лучших и объединяет все данные в столбце dialed_num. Работает безупречно, спасибо всем за вашу помощь!
Ответ №1:
Сначала определите, какие данные ECH имеют более 10 callid (псевдокод):
select ECH.callid
from CMS_ECH.dbo.CaliforniaECH ECH
group by ECH.callid
having count(*) > 10
Затем вы можете использовать это как подзапрос для фильтрации ваших результатов:
...
from ECH
...
where ECH.callid IN (
select ECH.callid
from CMS_ECH.dbo.CaliforniaECH ECH
group by ECH.callid
having count(*) > 10
)
Комментарии:
1. Спасибо, но ваш запрос возвращает 0 результатов, где должно быть около 140 000. Я столкнулся с этой проблемой ранее. Я использовал предложение HAVING: Having count (callid) >= 10, но тогда мои результаты должны быть сгруппированы. Мне нужны отдельные строки, а не группы. 🙁 Что я могу сделать, чтобы вы помогли мне?
2. Попробуйте устранить некоторую сложность запроса и сначала запустите оператор top: выберите ECH.callid, count( ) из CMS_ECH.dbo.CaliforniaECH ECH group по ECH.callid, имеющему count( ) > 10, Убедитесь, что это дает правильный результат. Как только это будет сделано, выполните простой select из ECH, используя внутренний запрос в качестве фильтра. Если это работает, то проблема связана с какой-то другой частью вашего запроса. Вы можете добавлять предложения joins и where по одному, пока результаты не выпадут, и это поможет вам определить источник проблемы.
Ответ №2:
Вы можете сделать это:
Select column1,column2,column3
From MyTable
Where (Select count(*) From MyTable Group By Column1) > 10
Более конкретно к вашему примеру добавьте:
AND
(SELECT count(*)
FROM CMS_ECH.dbo.CaliforniaECH iECH
WHERE iECH.callid = ECH.callid) > 10
Комментарии:
1. Спасибо за вашу помощь! Добавление этого в нижней части запроса приводит к этой ошибке: подзапрос вернул более 1 значения. Это не разрешено, когда следует подзапрос =, !=, <, <= , >, >= или когда подзапрос используется как выражение.
2. Еще раз спасибо, мой запрос теперь возвращает 0 результатов, и он должен вернуть около 140 000. Интересно то, что я столкнулся с этой проблемой ранее. Я использовал предложение HAVING: Having count (callid) >= 10, но тогда мои результаты должны быть сгруппированы. Мне нужны отдельные строки, а не группы. 🙁 Что я могу сделать, чтобы вы помогли мне?
Ответ №3:
Я сам решил проблему, используя внутреннее объединение запроса, который выбирает 10 лучших и объединяет все данные в столбце dialed_num. Работает безупречно, спасибо всем за вашу помощь!
Комментарии:
1. Я работаю с mysql, у которого нет TOP (использует LIMIT), но, если я хорошо помню, TOP выбирает максимум 10 ЛУЧШИХ результатов, но если результатов меньше 10, он вернет их все, поэтому вы не будете выбирать только вызовы с
callid > 10
, поэтому я думаю, что TOP нельзя использовать, но я могу ошибаться в этом. В любом случае, я думаю, что выполнение объединения с TOP 10 dialed_num ограничит данные 10 наиболее набранными номерами и не удалит данные ниже 10 вызовов.
Ответ №4:
Исправлено:
SELECT * FROM (SELECT
FiscalMonthYear,
'MyCenter' = CASE EP.Center
WHEN 'Livermore Call Center' THEN 'LCC'
WHEN 'Natomas Call Center' THEN 'NCC'
WHEN 'Concord Call Center' THEN 'CCC'
WHEN 'Virtual Call Center' THEN 'VCC'
WHEN 'Morgan Hill Call Center' THEN 'MHCC'
ELSE Center
END,
ECH1.segstart,
ECH1.consulttime,
EP.Queue,
(EP.MgrFName ' ' EP.MgrLName)AS Manager,
(EP.SupFName ' ' EP.SupLName)AS Supervisor,
(EP.RepFName ' ' EP.RepLName)AS Agent,
EP.RepPERNR,
LEFT(ECH1.segstart, 19) AS SegmentDateTime,
ECH1.origlogin,
ECH1.dialed_num,
ECH1.segment,
ECH1.SegStart_Date,
ECH1.callid
FROM CMS_ECH.dbo.CaliforniaECH ECH1 GROUP BY ECH1.dialed_num HAVING COUNT(ECH1.callid) >= 10) ECH
INNER JOIN CAPLESQL02.InfoQuest.dbo.IQ_Employee_Avaya_Id A ON ECH.origlogin = A.AvayaID
AND getdate () BETWEEN StartDate AND EndDate
INNER JOIN CAPLESQL02.InfoQuest.dbo.IQ_Employee_Profiles_v3 EP ON A.IQID = EP.RepID
AND getdate () BETWEEN RepToSup_StartDate AND RepToSup_EndDate
AND getdate () BETWEEN SupToMgr_StartDate AND SupToMgr_EndDate
AND getdate () BETWEEN RepQueue_StartDate AND RepQueue_EndDate
INNER JOIN Cal_RemReporting.dbo.udFiscalMonthTable f ON ECH.SegStart_Date = f.Tdate
WHERE dialed_num NOT LIKE '______'
AND dialed_num NOT LIKE ''
AND dialed_num NOT LIKE '_______'
AND EP.Center IS NOT NULL
AND EP.Center NOT LIKE 'Comm Ops'
AND EP.Center NOT LIKE 'Same Day Group'
AND MgrLName NOT LIKE 'Hollman'
AND consulttime > 0
AND ECH.SegStart_Date BETWEEN getdate()-90 AND getdate()-1
AND EP.Queue NOT IN ('BST','Collections', 'DST','DSR','Escalations','Cable Store')
Комментарии:
1. Спасибо, но это возвращает ошибку: выражение не булевого типа, указанное в контексте, где ожидается условие, рядом с ‘)’.
2. да … извините за AND … это таблица, из которой вы должны выбрать… Я исправляю это и скоро опубликую адаптированное
3. ХОРОШО — выглядит прямо сейчас — не уверен насчет некоторых неправильно написанных вещей, поскольку я не могу запустить запрос для проверки, но я проверил более простую структуру (с меньшим количеством полей и без объединений), и это работает