I'm new to MYSQL, and I'm trying to validate the number of data which have the same name from 2 column that occurs more than one time, which I already try to use 'having' statement in this case and it throws me an error like this
Error Code: 3593. You cannot use the window function 'count' in this context.'
below I include an image of what I'm trying to do
you can see there a column named "number_of_same_year" represent the "COUNT OVER PARTITION" output, which has numbers that logically could be validated. I only want to show where the numbers are above 1 (which means occur more than one time)
ps: I'm using MySQL in Windows 10
You cannot use having and a window function. You would want to instead do as follows
select * from (
select unit_name
,month(transaction_date)
,year(transaction_date) as year
,budget
,count(*) over(partition by unit_name,year(transaction_date)) as number_of_same_year
from sql_advertising.history_transaction
)x
where x.number_of_same_year >1
order by x.unit_name
SELECT {fieldset}
FROM {tableset}
WHERE {conditions-1}
GROUP BY {expression-1}
HAVING {conditions-2}
AND {expression-2} = COUNT({expression-3}) OVER ({window})
Window function is applied to output dataset, but HAVING alters it. So window function cannot be used in HAVING. The above code is invalid.
You may solve it by:
WITH `cte` AS ( SELECT {fieldset},
{expression-2} = COUNT({expression-3}) OVER ({window}) AS `criteria`
FROM {tableset}
WHERE {conditions-1}
GROUP BY {expression-1}
HAVING {conditions-2} )
SELECT {fieldset}
FROM `cte`
WHERE `criteria`
Example data to sort:
xy3abc
y3bbc
z3bd
Sort order must be abc, bbc, bd regardless of what is before the numeral.
I tried:
SELECT
*,
LEAST(
if (Locate('0',fcccall) >0,Locate('0',fcccall),99),
if (Locate('1',fcccall) >0,Locate('1',fcccall),99),
if (Locate('2',fcccall) >0,Locate('2',fcccall),99),
if (Locate('3',fcccall) >0,Locate('3',fcccall),99),
if (Locate('4',fcccall) >0,Locate('4',fcccall),99),
if (Locate('5',fcccall) >0,Locate('5',fcccall),99),
if (Locate('6',fcccall) >0,Locate('6',fcccall),99),
if (Locate('7',fcccall) >0,Locate('7',fcccall),99),
if (Locate('8',fcccall) >0,Locate('8',fcccall),99),
if (Locate('9',fcccall) >0,Locate('9',fcccall),99)
) as locationPos,
SUBSTRING(fcccall,locationPos,3) as fccsuffix
FROM memberlist
ORDER BY locationPos, fccsuffix
but locationPos gives me an error on the substring function call
It's not possible to reference that expression by its alias locationPos, within another expression in the same SELECT list.
Replicating the entire expression would be the SQL way to do it. (Yes, it is ugly repeating that entire expression.)
Another (less performant) approach is to use your query (minus the fccsuffix expression) as an inline view. The outer query can reference the assigned locationPos alias as a column name.
As a simple example:
SELECT v.locationPos
FROM ( SELECT 'my really big expression' AS locationPos
FROM ...
) v
This approach of using an inline view ("derived table") can have some serious performance implications with large sets.
But for raw performance, repeating the expression is the way to go:
SELECT *
, LEAST(
if (Locate('0',fcccall) >0,Locate('0',fcccall),99),
if (Locate('1',fcccall) >0,Locate('1',fcccall),99),
if (Locate('2',fcccall) >0,Locate('2',fcccall),99),
if (Locate('3',fcccall) >0,Locate('3',fcccall),99),
if (Locate('4',fcccall) >0,Locate('4',fcccall),99),
if (Locate('5',fcccall) >0,Locate('5',fcccall),99),
if (Locate('6',fcccall) >0,Locate('6',fcccall),99),
if (Locate('7',fcccall) >0,Locate('7',fcccall),99),
if (Locate('8',fcccall) >0,Locate('8',fcccall),99),
if (Locate('9',fcccall) >0,Locate('9',fcccall),99)
) AS locationPos
, SUBSTRING(fcccall
, LEAST(
if (Locate('0',fcccall) >0,Locate('0',fcccall),99),
if (Locate('1',fcccall) >0,Locate('1',fcccall),99),
if (Locate('2',fcccall) >0,Locate('2',fcccall),99),
if (Locate('3',fcccall) >0,Locate('3',fcccall),99),
if (Locate('4',fcccall) >0,Locate('4',fcccall),99),
if (Locate('5',fcccall) >0,Locate('5',fcccall),99),
if (Locate('6',fcccall) >0,Locate('6',fcccall),99),
if (Locate('7',fcccall) >0,Locate('7',fcccall),99),
if (Locate('8',fcccall) >0,Locate('8',fcccall),99),
if (Locate('9',fcccall) >0,Locate('9',fcccall),99)
),3
) AS fccsuffix
FROM memberlist
ORDER BY locationPos, fccsuffix
Unfortunately, with MySQL, it's not possible to reference the result of the locationPos column within an expression in the same SELECT list.
For only one numeral I like:
SELECT *
FROM memberlist
ORDER BY SUBSTRING(fcccall,
LOCATE('0',fcccall)+
LOCATE('1',fcccall)+
LOCATE('2',fcccall)+
LOCATE('3',fcccall)+
LOCATE('4',fcccall)+
LOCATE('5',fcccall)+
LOCATE('6',fcccall)+
LOCATE('7',fcccall)+
LOCATE('8',fcccall)+
LOCATE('9',fcccall),3)
But the sensible approach is not to store two separate bits of information in one field.
I have what appears to be a corrupt index?
Here is what is happening. I have two table-functions which the first is a set of cases and the second is a set of aware dates. These two sets have a 1 (case) to 0 or 1 (aware date) relationship. Normally I query them like;
SELECT c.CaseID, a.AwareDate
FROM Cases(#date) AS c
LEFT JOIN AwareDates(#date) AS a ON c.CaseID = a.CaseID;
The trouble is that not all of the rows from AwareDates which match seem to be JOIN'd. If I add a join hint, they then do. say;
SELECT c.CaseID, a.AwareDate
FROM Cases(#date) AS c
LEFT MERGE JOIN AwareDates(#date) AS a ON c.CaseID = a.CaseID;
What I notice from the query plan is that adding the join hint adds a sort of the AwareDate data before the join which is not there otherwise. Also, the query planner flips the join to a RIGHT OUTER JOIN when there is no hint, and of course keeps the LEFT JOIN where the hint is present.
I've done the following with no errors detected;
DBCC UPDATEUSAGE (0) WITH INFO_MESSAGES, COUNT_ROWS;
EXECUTE sp_updatestats 'resample';
DBCC CHECKDB (0) WITH ALL_ERRORMSGS, EXTENDED_LOGICAL_CHECKS;
I'm stumped... any ideas?
Here are the UDF definitions
ALTER FUNCTION dbo.Cases( #day date ) RETURNS TABLE
WITH SCHEMABINDING
AS RETURN (
SELECT
CaseID -- other 42 columns ommitted
FROM (
SELECT
ROW_NUMBER() OVER (PARTITION BY CaseID ORDER BY UpdateDate DESC, UpdateNumber DESC) AS RecordAge,
CaseID,
Action
FROM
dbo.CaseAudit
WHERE
convert(date,UpdateDate) <= #day
) AS History
WHERE
RecordAge = 1 -- only the most current record version
AND isnull(Action,'') != N'DEL' -- only include cases that have not been deleted
)
ALTER FUNCTION dbo.AwareDates( #day date ) RETURNS TABLE
WITH SCHEMABINDING
AS RETURN (
WITH
History AS (
SELECT row_number() OVER (PARTITION BY CaseID, ContactID ORDER BY UpdateDate DESC, UpdateNumber DESC) AS RecordAge,
CaseID, InfoReceived, ReceiveDate, ResetClock, Action
FROM dbo.ContactLogAudit WITH (NOLOCK)
WHERE convert(date,UpdateDate) <= #day
),
Notes AS (
SELECT
CaseID,
convert(date,ReceiveDate,112) AS ReceiveDate,
ResetClock
FROM History
WHERE RecordAge = 1 -- only the most current record version
AND isnull(Action,'') != N'DEL' -- only include notes that have not been deleted
AND InfoReceived = N'Y' -- only include notes that have Info Rec'd checked
AND len(ReceiveDate) = 8 AND isnumeric(ReceiveDate) = 1 AND isdate(ReceiveDate) = 1 -- only include those with a valid aware date
),
Initials AS (
SELECT CaseID, min(ReceiveDate) AS ReceiveDate
FROM Notes
GROUP BY CaseID
),
Resets AS (
SELECT CaseID, max(ReceiveDate) AS ReceiveDate
FROM Notes
WHERE ResetClock = N'Y'
GROUP BY CaseID
)
SELECT
i.CaseID AS CaseID,
i.ReceiveDate AS InitialAwareDate, -- the oldest valid aware date value (must have AE Info Reveived checked and a received date)
coalesce(r.ReceiveDate,i.ReceiveDate) AS AwareDate -- either the newest valid aware date value with the Reset Clock checked, otherwise the initial aware date value
FROM Initials AS i
LEFT JOIN Resets AS r
ON i.CaseID = r.CaseID
);
I have further found that if I drop the "WITH (NOLOCK)" table hint, I get correct results. Also if add a join hint to the AwareDates UTF or even add a COLLATE Latin1_General_BIN on the LEFT JOIN relation between Initials and Resets.
Query plan row counts -- without join hint (broken)
Cases { Actual: 25,891, Estimate: 19,071.9 }
AwareDates { Actual: 24,693, Estimated: 1,463.09 }
Initials { Actual: 24,693, Estimated: 1,463.09 }
Rests { Actual: 985, Estimated: 33.2671 }
AwareDates matches 8,108 of the Cases rows in the join'd result-set
Query plan row counts -- with join hint (working)
Cases { Actual: 25,891, Estimate: 19,071.9 }
AwareDates { Actual: 24,673, Estimated: 1,837.67 }
Initials { Actual: 24,673, Estimated: 1,837.67 }
Rests { Actual: 982, Estimated: 42.6238 }
AwareDates matches 24,673 of the Cases rows in the join'd result-set
I have further whittled down the scope of the issue. I can;
SELECT * FROM AwareDate(#date);
and
SELECT * FROM AwareDate(#date) ORDER BY CaseID;
With different row counts.
You don't specify the specific version of SQL (##version), but this seems suspiciously like a bug that was fixed in Cumulative Update 6 for SQL 2008 R2 (apparently it also applies to SQL 2008).
KB 2433265
FIX: You may receive an incorrect result when you run a query that uses the
ROW_NUMBER function together with a left outer join in SQL Server 2008
The example in the article specifies DISTINCT. The article, however, is worded ambiguously -- it's not clear whether you NEED a distinct or if DISTINCT is one of the triggers.
Your example doesn't have a distinct like the article, but it appears modified for the sake of asking the question(i.e. 42 columns missing). Is there a distinct? Also in the AwareDates udf by the time i get down to the Initials CTE you do a GROUP BY which could have the same effect as a DISTINCT.
UPDATE
#Dennis from your comment I still can't tell if you're using SQL 20080 or 2008 R2.
If you're running 2008, the KB article says "The fix for this issue was first released in Cumulative Update 11 for SQL Server 2008 Service Pack 1." So, post SP1.
On the other hand, if you're using SQL 2008 R2, you are correct that this was fixed in CU 6, which was part of SP1. But this bug appears to have resurfaced. Look at Cumulative update package 4 for SQL Server 2008 R2 Service Pack 1 -- released post SP1.
970198 FIX: You receive an incorrect result when you run a
query that uses the row_number function in SQL Server 2008
or in SQL Server 2008 R2
In the associated KB article MS dropped the reference to distinct:
Consider the following scenario. You run a query against a table that has a
clustered index in Microsoft SQL Server 2008 or in Microsoft SQL Server 2008
R2. In the query, you use the row_number function. In this scenario, you
receive an incorrect result when a parallel execution plan is used for the
query. If you run the query many times, you may receive different results.
This seems to confirm my earlier reading of KB 2433265 -- the phrasing suggests distinct is just one of many conditions that can cause the behavior. It seems that a parallel execution plan is the culprit this time around.