could not prepare statement (1 misuse of aggregate function COUNT()) - part 2 - sql

I'm trying to run the following query:
select U1.userEmail, U1.firstname + ' ' + U1.surName as fullname
from tblUser as U1 inner join tblDriver as D on U1.userEmail= D.userEmail
inner join tblGetAsk as GA on GA.userEmail = D.userEmail
where not exists (select 1 from tblRideRating as R where R.userEmail = U1.userEmail)
and count(GA.userEmail) >= 3
But I'm getting the following error:
Error 1: could not prepare statement (1 misuse of aggregate function
COUNT())
What I'm actually want to do is: Select only users who are also a driver and have 0 records in tblRideRating, and have at least 3 records in tblGetAsk.

You can use aggregation.
Group by user and use a HAVING clause:
select U1.userEmail, U1.firstname + ' ' + U1.surName as fullname
from tblUser as U1
inner join tblDriver as D on D.userEmail= U1.userEmail
inner join tblGetAsk as GA on GA.userEmail = U1.userEmail
where not exists (select 1 from tblRideRating as R where R.userEmail = U1.userEmail)
group by U1.userEmail, U1.firstname + ' ' + U1.surName
having count(GA.userEmail) >= 3
If you have duplicate emails for each user in tblGetAsk, maybe you should change to:
having count(distinct GA.userEmail) >= 3
You could also aggregate in tblGetAsk and then join:
select U1.userEmail, U1.firstname + ' ' + U1.surName as fullname
from tblUser as U1
inner join tblDriver as D on D.userEmail= U1.userEmail
inner join (
select userEmail
from tblGetAsk
group by userEmail
having count(*) >= 3
) as GA on GA.userEmail = U1.userEmail
where not exists (select 1 from tblRideRating as R where R.userEmail = U1.userEmail)

Related

Filter based on where condition

I have a query where I am getting data for some tickets.Now I need to put a where condition to get data where timediffsecs <> 0.I am unable to get the correct place to put where conditon..
Below is my code .Please help
WITH CTE
AS
(
SELECT cr.ref_num as 'TicketNumber',
isnull(requestor.last_name,'') + ', ' + isnull(requestor.first_name,'') as 'Requestor'
,ISNULL(cnt.last_name, '') + ', ' + ISNULL(cnt.first_name,'') as 'Created By'
,isnull(aeu.last_name,'') + ', ' + isnull(aeu.first_name,'') as 'Affected End User',
isnull(logagent.last_name,'') + ', ' + isnull(logagent.first_name,'') as 'Reported By'
,dbo.ConvertUnixTime (cr.open_date) as 'Open Date'
,dbo.ConvertUnixTime (cr.last_mod_dt) as 'Last Modified Date'
,dbo.ConvertUnixTime (cr.resolve_date) as 'Resolve Date'
,dbo.ConvertUnixTime (cr.close_date) as 'Close Date'
,dbo.ConvertUnixTime (act.time_stamp) as 'systime',
cr.summary as 'Summary'
,convert(varchar(max),cr.[description]) as 'Description'
,act.[action_desc] as 'System Description'
,acttype.sym as 'Activity Type'
,act.time_spent as 'Time Spent',
ROW_NUMBER() OVER(PARTITION BY cr.ref_num ORDER BY dbo.ConvertUnixTime (act.time_stamp)) RN
-- ROW_NUMBER() OVER(ORDER BY dbo.ConvertUnixTime (act.time_stamp) ) RN
-- ROW_NUMBER generated based on ORDER BY Time DESC
-- You can also add case_id or any other column to generate
--ROW_NUMBER so that the time differences can be calculate
--based on other dimension.
from call_req cr with (nolock)
LEFT OUTER JOIN ca_contact requestor with (nolock) on cr.requested_by = requestor.Contact_uuid
LEFT OUTER JOIN ca_contact aeu with (nolock) on cr.customer = aeu.Contact_uuid
LEFT OUTER JOIN ca_contact logagent with (nolock) on cr.log_agent = logagent.Contact_uuid
INNER JOIN act_log act with (nolock) on cr.persid = act.call_req_id
INNER JOIN ca_contact cnt with (nolock) on act.analyst = cnt.contact_uuid
INNER JOIN act_type acttype with (nolock) on act.[type] = acttype.code
where cr.ref_num in ('23035883',
'23038276')
)
SELECT *,
CASE
WHEN A.RN = 3 THEN
DATEDIFF(
SECOND,
(SELECT systime FROM CTE WHERE RN = 2 AND TicketNumber= A.TicketNumber),
(SELECT systime FROM CTE WHERE RN = 3 AND TicketNumber= A.TicketNumber)
-- By setting RN = 3 and 2, I am calculating
-- Time differences between ROW 3 and 2
-- You can set it to any Row number as per your requirement
)
ELSE 0
END as timediffsecs
FROM CTE A
You just need to nest the current SELECT in a subquery:
WITH cte
....
SELECT *
FROM (
YourCurrentSelect
) q
WHERE q.timediffsecs <> 0

SQL query to conditionally select a field value

I have an SQL query that joins 3 tables to return me the required data. The query is as follows:
SELECT (s.user_created,
u.first_name,
u.last_name,
u.email,
s.school_name,
p.plan_name,
substring( a.message, 11), u.phone1)
FROM cb_school s
inner join ugrp_user u
on s.user_created = u.user_id
inner join cb_plan p
on s.current_plan = p.plan_id
inner join audit a
on u.user_id = a.user_id
where s.type = 'sample'
and a.module_short = 'sample-user'
and s.created_time > current_timestamp - interval '10 day';
The query works fine if all the attributes are present. Now for few of my rows, the following value would be a.module_short = 'sample-user' missing. But since I have included it as an AND condition, those rows will not be returned. I am trying to return an empty string for that field if it is present, else the value as per my current query. Is there any way to achieve this.
Think you could possibly use a CASE WHEN statement, like this:
SELECT CASE WHEN a.module_short = 'sample-user' THEN a.module_short
ELSE '' END AS a.module_short
FROM TableA
you can use COALESCE it returns the first not null.
SELECT COALESCE(a.module_short,'')
FROM TableA AS a
SELECT (s.user_created,
u.first_name,
u.last_name,
u.email,
s.school_name,
p.plan_name,
substring( a.message, 11), u.phone1)
FROM cb_school s
INNER JOIN ugrp_user u
ON s.user_created = u.user_id
INNER JOIN cb_plan p
ON s.current_plan = p.plan_id
INNER JOIN audit a
ON u.user_id = a.user_id
AND a.module_short = 'sample-user'
WHERE s.type = 'sample'
AND s.created_time > current_timestamp - interval '10 day';
You want to show all users that have at least one module_short.
If the module_short contains 'sample-user' then it should show it, else it should show NULL as module_short. You only want 1 row per user, even if it has multiple module_shorts.
You can use a CTE, ROW_NUMBER() and the CASE clause for this question.
Example Question
I have 3 tables.
Users: Users with an ID
Modules: Modules with an ID
UserModules: The link between users and modules. You user can have multiple models.
I need a query that returns me all users that have at least 1 module with 2 columns UserName and ModuleName.
I only one 1 row for each user. The ModuleName should only display SQL if the user has that module. Else it should display no module.
Example Tables:
Users:
id name
1 Manuel
2 John
3 Doe
Modules:
id module
1 StackOverflow
2 SQL
3 StackExchange
4 SomethingElse
UserModules:
id module_id user_id
1 1 2
2 1 3
4 2 2
5 2 3
6 3 1
7 3 3
8 4 1
9 4 3
Example Query:
with CTE as (
select
u.name as UserName
, CASE
WHEN m.module = 'SQL' THEN 'SQL' ELSE NULL END as ModuleName
, ROW_NUMBER() OVER(PARTITION BY u.id
ORDER BY (CASE
WHEN m.module = 'SQL' THEN 'Ja' ELSE NULL END) DESC) as rn
from UserModules as um
inner join Users as u
on um.user_id = u.id
inner join Modules as m
on um.module_id = m.id
)
select UserName, ModuleName from CTE
where rn = 1
Example Result:
UserName ModuleName
Manuel NULL
John SQL
Doe SQL
Your query would look like this:
with UsersWithRownumbersBasedOnModule_short as (
SELECT s.user_created,
u.first_name,
u.last_name,
u.email,
s.school_name,
p.plan_name,
substring( a.message, 11),
u.phone1)
CASE
WHEN a.module_short = 'sample-user'
THEN a.module_short
ELSE NULL
END AS ModuleShort
ROW_NUMBER() OVER(PARTITION BY u.user_id ORDER BY (
CASE
WHEN a.module_short = 'sample-user'
THEN a.module_short
ELSE NULL
END) DESC) as rn
FROM cb_school s
inner join ugrp_user u
on s.user_created = u.user_id
inner join cb_plan p
on s.current_plan = p.plan_id
inner join audit a
on u.user_id = a.user_id
where s.type = 'sample'
and s.created_time > current_timestamp - interval '10 day';)
select * from UsersWithRownumbersBasedOnModule_short
where rn = 1
PS: I removed a lose bracket after SELECT and your SUBSTRING() is missing 1 parameter, it needs 3.

SQL Moving SUBSTRING select into INNER JOIN

I have this query
SELECT ID,
SUBSTRING(( SELECT DISTINCT ',' + CONVERT(varchar(10), CC.CompanyId)
FROM Company CC
INNER JOIN CompanyProducts NP2
ON CC.CompanyId = NP2.CompanyId
WHERE NP.CompanyProducts Id = NP2.PrimaryCompanyProducts Id
AND NP2.CompanyProducts Id <> NP2.CompanyProducts Id
FOR XML PATH('')),2,200000) AS CompanyIdList
FROM CompanyProducts NP
I would like to add the SELECT into an INNER JOIN which I will add to my select to check if the return is null or zero
it will be something like this
SELECT ID,
SUBSTRING(( SELECT DISTINCT ',' + CONVERT(varchar(10), CC.CompanyId)
FROM Company CC
INNER JOIN CompanyProducts NP2
ON CC.CompanyId = NP2.CompanyId
WHERE NP.CompanyProducts Id = NP2.PrimaryCompanyProducts Id
AND NP2.CompanyProducts Id <> NP2.CompanyProducts Id
FOR XML PATH('')),2,200000) AS CompanyIdList,
CompanyIdCount --this will be null or a real value
FROM cmp.CompanyProducts NP
INNER JOIN(SELECT DISTINCT A.CompanyProductsId,
(SELECT DISTINCT ',' + CONVERT(varchar(10), CC.CompanyId)
FROM Company CC
INNER JOIN CompanyProducts NP2
ON CC.CompanyId = NP2.CompanyId
WHERE NP.CompanyProducts Id = NP2.PrimaryCompanyProducts Id
AND NP2.CompanyProducts Id <> NP2.CompanyProducts Id ) AS CompanyIdCount
FROM cmp.CompanyProducts A
)E ON NP.CompanyNotificationId = E.CompanyNotificationId
How can I get the inner JOIN to incident null for no records or 1 record or more? THanks

MSSQL Query get latest value from two tables faster

This query pulls the timestamp (DT_CREATED) from two different tables and selecting the most recent timestamp. The INCIDENT_AUDIT_HISTORY table is quite large and even though I've improved performance by 10 seconds by adding indexes my query still takes over 20 seconds to run, which is longer than desired for the application. I'm wondering if there is a more efficient way to write this query?
SELECT i.NUMBER, i.PROBLEM, st.LABEL AS STATUS, i.ID_ASSIGNEE, r.LNAME + ', ' + r.FNAME AS ASIGNEE, c.LNAME + ', ' + c.FNAME AS CUST_NAME,
p.LABEL AS PRIORITY, i.DT_CREATED,
(SELECT MAX(DT_CREATED) AS LAST_WORK
FROM (SELECT TOP (1) DT_CREATED
FROM dbo.REP_WORK_HISTORY AS b
WHERE (i.NUMBER = INCIDENT_NUMBER) AND (ID_OWNER = r.ID)
ORDER BY DT_CREATED DESC
UNION
SELECT TOP (1) DT_CREATED
FROM dbo.INCIDENT_AUDIT_HISTORY AS c
WHERE (i.NUMBER = INCIDENT_NUMBER) AND (ID_OWNER = r.ID)
ORDER BY DT_CREATED DESC) AS a) AS LAST_HISTORY, g.GROUP_NAME FROM dbo.REPS AS r RIGHT OUTER JOIN
dbo.GROUPS AS g ON r.ID_DEFAULT_GROUP = g.ID RIGHT OUTER JOIN
dbo.INCIDENTS AS i ON r.ID = i.ID_ASSIGNEE LEFT OUTER JOIN
dbo.CUSTOMERS AS c ON i.ID_CUSTOMER = c.ID LEFT OUTER JOIN
dbo._PRIORITIES AS p ON i.PRIORITY = p.ID LEFT OUTER JOIN
dbo.INCIDENT_STATUSES AS st ON i.ID_STATUS = st.ID WHERE (st.TYPE <> 2) AND (st.TYPE <> 16)

Date comparison function in SQL Server

I am trying to display records which are created after Oct 1 2010. But my query doesn't seem to work. It also display records from 2004 - Sept 2010 which is not wanted.
What is wrong with the query below?
select Distinct app.app_id,
(convert(varchar, creation_date,101) + ' ' + convert(varchar,creation_date ,108)) as creation_date,
dbo.oea_fn_get_amc_mem_name(app.app_id,primary_msn,getdate(), 'EN', 30000) PIName,
dbo.oea_fn_get_pid_countyname(app.app_id,primary_msn,'OC')as PIpid,
primary_msn,
zip,
home_tel,
work_tel,
work_extn,
other_contact,
other_ext,
cell_tel,
dbo.oea_fn_get_amc_mem_name(app.app_id,mem.msn,getdate(), 'EN', 30000)as Kname,
dbo.oea_fn_get_pid_countyname(app.app_id,mem.msn,'OC')as Knamepid,
mem.msn as Kmsn,
(select count(reminder_id) from reminders (nolock) where app_id=app.app_id) as reminder
from app_application app (nolock)
inner join app_member mem with (nolock) on app.app_id=mem.app_id
--left outer join Oea_App_Program_Disposition disp with (nolock) on mem.app_id = disp.app_id and mem.msn=disp.msn
inner join app_address aadd with (nolock) on app.app_id=aadd.app_id
--inner join app_calc_results calc with (nolock) on mem.app_id=calc.app_id and calc.msn=mem.msn
left outer join app_member_benefits ben with (nolock) on mem.app_id = ben.app_id and mem.msn=ben.msn
where
isnull(mem.coverage_required,0) = 1
and app.app_status = 's'
and ben.ins_end_date < getdate()
and app.client_id = 30000
and app.app_id not in (select app_id from app_renewal)
and (mem.msn in (select calc.msn from app_calc_results calc
inner join app_application app on calc.app_id = app.app_id and calc.prog_id = 'CK' and calc.opt_out = 1))
and (mem.msn in (select msn from app_calc_results where app_id=app.app_id and status not in ('A','X')))
or (mem.msn in (select msn from Oea_App_Program_Disposition where app_id=app.app_id and disp_status not in ('A','P')) )
and app.creation_date >= '10/01/2010'
Thanks for all the help.
You probably want this:
and (
(mem.msn in (select calc.msn from app_calc_results calc
inner join app_application app on calc.app_id = app.app_id and calc.prog_id = 'CK' and calc.opt_out = 1))
or (mem.msn in (select msn from app_calc_results where app_id=app.app_id and status not in ('A','X')))
or (mem.msn in (select msn from Oea_App_Program_Disposition where app_id=app.app_id and disp_status not in ('A','P')) )
)
and app.creation_date >= '10/01/2010'
The problem is with the logic behind the or in the where clause.
As others have stated, the problem is likely the Or clause in the Where clause. In effect, your query is:
Select ...
From ..
Where (A And B And C
And D And E
And F And G
And app.creation_date >= '10/01/2010'
)
Or mem.msn In (
Select msn
From Oea_App_Program_Disposition
Where app_id=app.app_id
And disp_status not in ('A','P')
)
Thus, if for any row, if the Or is true, the rest of the "Ands" are ignored. I would assume that the Or is supposed to be paired with one of the And clauses.