Expected lexical element not found - sql

Every time I used 'Count()' to count the duplicate PointIDs' on the query I get this error.
I have narrowed down the problem is with Count() function, used MAX() with Group by and didn't have any problem. This is on access database populated using ODBC connection. All the help is appriciated - I have done all the research and this is my last online resort.
SELECT Event1.PointID, Event1.LogTimeStamp, Count(Event1.PointID) AS acount
FROM Event1
GROUP BY Event1.PointID, Event1.LogTimeStamp;

I suspect you actually want to return all duplicate records which is a 2 step operation.
Step 1 get find the ids which are duplicated
SELECT Event1.PointID, Count(*) AS NumOfRecords
FROM Event1
GROUP BY Event1.PointID
HAVING COUNT(*) > 1
Step 2 join that result back to the original table to find the records
SELECT e.*, d.NumOfRecords
FROM
Event1 e
INNER JOIN (
SELECT Event1.PointID, Count(*) AS NumOfRecords
FROM Event1
GROUP BY Event1.PointID
HAVING COUNT(*) > 1
) d
ON e.PointId = d.PointId

This is the standard syntax for what you want to do:
SELECT Event1.PointID, Event1.LogTimeStamp, Count(*) AS acount
FROM Event1
GROUP BY Event1.PointID, Event1.LogTimeStamp;

Related

SQL Help - Think I need a subquery

I have wrote the following query.
SELECT pro.[Id], COUNT(*) AS Count
FROM {Task} tsk
JOIN {profile} pro ON tsk.[ProfileId]=pro.[Id]
GROUP BY
pro.[Id]
HAVING
COUNT(*) > 1
This returns the records I am interested in but it returns the following...
ID Count
12345 3
21254 2
25458 2
I now need to take it a stage further and I think I would need to use the query I have wrote within another query to get what I need.
I basically need to see the underlying data in the count e.g. task-number. So the end result will look something like this based on the above example.
ID Count
12345 123-345
12345 135-564
12345 136-985
21254 124-856
21254 135-854
25458 214-854
25458 365-850
Am I correct in thinking I need a subquery to do this and how would I go about it?
Thanks
You could go with a CTE, count, filter then join
WITH CTE AS (
SELECT pro.[Id], COUNT(*) AS Count
FROM {Task} tsk
JOIN {profile} pro ON tsk.[ProfileId]=pro.[Id]
GROUP BY
pro.[Id]
HAVING
COUNT(*) > 1
)
SELECT tsk.[Id], tsk.[ProfileId] FROM CTE
JOIN {Task} tsk ON CTE.[Id] = tsk.[ProfileId]

Getting 1's and 0's instead of COUNT in this query

In my dataset, I'm trying to find how many Stores have had at least 10 events where the value of each event was greater than $100.
SELECT COUNT(EventId) >=10
FROM Event
WHERE Event.EventValue >100
GROUP BY Site.SiteName
I appear to just be getting 1's and 0's instead of getting the site names that fit this criteria
Should work in your case.
SELECT CASE WHEN COUNT(*) >= 10 THEN 1 ELSE 0 END
FROM (
SELECT COUNT(EventId) AS T
FROM Event
WHERE Event.EventValue >100
GROUP BY Site.SiteName
) DATA
Try this:
SELECT
COUNT(1)
FROM
(
SELECT
eventid
FROM
events
WHERE
eventvalue > 100
GROUP BY
eventid
HAVING
COUNT(1) >= 10
)
Your query is returning 0 and 1 to mean FALSE and TRUE, because your SELECT clause is asking whether the COUNT(EventId) is greater than 10. Instead, try selecting the SiteId and putting your COUNT > 10 criterion in a HAVING clause.
Try this query.
select Site.SiteId, Site.SiteName
from (select SiteId, count(distinct EventId)
from Event
where EventValue > 100
group by SiteId
having count(distinct EventId) >= 10
) EV
join Site
on EV.SiteId = Site.SiteId
;
1/0 are the answer as it is showing True/False as your SELECT cause is asking for the count greater than 10 not the name. It should work if you ask for the SiteID and look at count >10 as it will show names not a true false answer.

Got a error message when I try to find out which patient account have duplicated record.

When I run the script below, I got a error message "Cannot perform an aggregate function on an expression containing an aggregate or a subquery" Please provide some advice. Thanks
SELECT
CONVERT(DECIMAL(18,5),SUM(CASE WHEN PATIENT_ACCOUNT_NO IN (
SELECT PATIENT_ACCOUNT_NO
FROM STND_ENCOUNTER
GROUP BY PATIENT_ACCOUNT_NO
HAVING ( COUNT(PATIENT_ACCOUNT_NO) > 1)) THEN 0 ELSE 1 END)) dupPatNo
FROM [DBO].[STND_ENCOUNTER]
I think the error message is pretty clear. You have a sum() function with a subquery in it (albeit within a case, but that doesn't matter).
It seems that you want to choose patients that have more than one encounter, then add 0 if the patients is in the list and 1 if the patient is not. Hmmm. . . sounds like you want to count the number of patients with only one encounter.
Try using this logic instead:
select count(*)
from (select se.*, count(*) over (partition by PATIENT_ACCOUNT_NO) as NumEncounters
from dbo.stnd_encounter se
) se
where NumEncounters = 1;
As a note, the variable you are assigning is called DupPatientNo. This sounds like the number of patients that have duplicates. In that case, the query is:
select count(distinct PATIENT_ACCOUNT_NO)
from (select se.*, count(*) over (partition by PATIENT_ACCOUNT_NO) as NumEncounters
from dbo.stnd_encounter se
) se
where NumEncounters > 1;
(Or use count(*) if you want the number of encounters on duplicate patients.)
If you want to find number of PATIENT_ACCOUNT_NO that does not have any duplicates then use the following
SELECT COUNT(DISTINCT dupPatNo.PATIENT_ACCOUNT_NO)
FROM (
SELECT PATIENT_ACCOUNT_NO
FROM STND_ENCOUNTER
GROUP BY PATIENT_ACCOUNT_NO
HAVING COUNT(PATIENT_ACCOUNT_NO) = 1
) dupPatNo
If you want to find number of PATIENT_ACCOUNT_NO that have atleast one duplicate then use the following
SELECT COUNT(DISTINCT dupPatNo.PATIENT_ACCOUNT_NO)
FROM (
SELECT PATIENT_ACCOUNT_NO
FROM STND_ENCOUNTER
GROUP BY PATIENT_ACCOUNT_NO
HAVING COUNT(PATIENT_ACCOUNT_NO) > 1
) dupPatNo
Use of DISTINCT will make the query not count same item again and again
Though your query looks for first result, its not clear what you want. Hence giving query for both

Prevent duplicate COUNT in SELECT query

I have the following query which as you can see does multiple Count(CompetitorID) calls. Is this a performance issue, or does SQL Server 2008 'cache' the Count? If this is a performance issue, is it possible to store the Count to prevent the multiple lookups?
SELECT EventID,Count(CompetitorID) AS NumberRunners,
CASE WHEN Count(CompetitorID)<5 THEN 1
WHEN Count(CompetitorID)>=5 AND Count(CompetitorID)<=7 THEN 2
ELSE 3 END AS NumberPlacings
FROM Comps
GROUP BY EventID Order By EventID;
Its always a better practice to get the value once and use it subsequently whenever possible. In your case, you can always use Inner query to get the count only once and compute other (derived) columns off its value as shown below:
SELECT EventID, NumberRunners,
CASE WHEN NumberRunners <5 THEN 1
WHEN NumberRunners >=5 AND NumberRunners <=7 THEN 2
ELSE 3
END AS NumberPlacings
FROM (
SELECT EventID,
NumberRunners = Count(CompetitorID)
FROM Comps
GROUP BY EventID
) t
Order By EventID;
simplest would be this:
SELECT EventID,Count(distinct CompetitorID) AS NumberRunners,
CASE WHEN Count(distinct CompetitorID)<5 THEN 1
WHEN Count(distinct CompetitorID)>=5 AND Count(distinct CompetitorID)<=7 THEN 2
ELSE 3 END AS NumberPlacings
FROM Comps
GROUP BY EventID Order By EventID;

SQL query count divided by a distinct count of same query

Having some trouble with some SQL.
Take the following result for instance:
LOC_CODE CHANNEL
------------ --------------------
3ATEST-01 CHAN2
3ATEST-01 CHAN3
3ATEST-02 CHAN4
What I need to do is get a count of the above query, grouped by channel, but i want that count to be divided by the count that the "LOC_CODE" appears.
Example of the result I am after is:
CHANNEL COUNT
---------------- ----------
CHAN2 0.5
CHAN3 0.5
CHAN4 1
Above explaination is that the CHAN2 appears next to "3ATEST-01", but that LOC_CODE of "3ATEST-01" appears twice, so the count should be divided by 2.
I know I can do this by basically duplicating the query with a distinct count, but the underlying query is quite complex and don't really want to harm performance.
Please let me know if you would like more information!
Try:
select channel,
count(*) over (partition by channel, loc_code)
/ count(*) over (partition by loc_code) as count_ratio
from my_table
SELECT t.CHANNEL, COUNT(*) / gr.TotalCount
FROM my_table t JOIN (
SELECT LOC_CODE, COUNT(*) TotalCount
FROM my_table
GROUP BY LOC_CODE
) gr USING(LOC_CODE)
GROUP BY t.LOC_CODE, t.CHANNEL
Create a index on (LOC_CODE, CHANNEL)
If are no duplicate channels, replace COUNT(*) / gr.TotalCount with 1 / gr.TotalCount and remove the GROUP BY clause
First, find a query that gets you the correct results. Then, see if it can be optimised. My guess is that it's hard to optimise as you require two different groupings, one per Channel and one pre Loc_Code.
I'm not even sure that this fits your description:
SELECT t.CHANNEL
, COUNT(*) / SUM(grp.TotalCount)
FROM my_table t
JOIN
( SELECT LOC_CODE
, COUNT(*) TotalCount --- or is it perhaps?:
--- COUNT(DISTINCT CHANNEL)
FROM my_table
GROUP BY LOC_CODE
) grp
ON grp.LOC_CODE = t.LOC_CODE
GROUP BY t.CHANNEL
Your requirements are still a bit unclear to me when it comes to duplicate CHANNELs, but this should work if you want grouping on both CHANNEL and LOC_CODE to sum up later;
SELECT L1.CHANNEL, 1/COUNT(L2.LOC_CODE)
FROM Locations L1
LEFT JOIN Locations L2 ON L1.LOC_CODE = L2.LOC_CODE
GROUP BY L1.CHANNEL, L1.LOC_CODE
Demo here.