I get an execution error in following SQL script:
SELECT TOP 1 PERCENT
a.accode, a.voucherdate, a.credit, a.Debit,
SUM(a.Debit) OVER (ORDER BY [a.accode],[a.voucherdate]) AS rdr
FROM
VoucherMain AS a
ORDER BY
a.accode, a.voucherdate
Error message
Incorrect syntax near 'order'
Can anyone tell me what's wrong with my syntax?
The problem is that you need SQL Server 2012 and above. Okay, I added the "and above" for future visitors, but compare 2008 OVER CLAUSE with 2012 OVER CLAUSE.
The 2008 version has this important note:
When used in the context of a ranking window function, <ORDER BY
Clause> can only refer to columns made available by the FROM clause.
An integer cannot be specified to represent the position of the name
or alias of a column in the select list. <ORDER BY Clause> cannot be
used with aggregate window functions.
In SQL Server 2008, you can only use the OVER clause to partition aggregate functions, not apply an order:
Ranking Window Functions
< OVER_CLAUSE > :: =
OVER ( [ PARTITION BY value_expression , ... [ n ] ]
< ORDER BY_Clause> )
Aggregate Window Functions
< OVER_CLAUSE > :: =
OVER ( [ PARTITION BY value_expression , ... [ n ] ] )
Note that there's no <ORDER BY Clause> for the aggregates.
Related
I am trying to use a CASE statement on the order of a MySQL statement in CakePHP 3.x app. The simple select is as follows:
$articles = $this->Articles->find()
->where($conditions)
->order(function ($exp, $q) {
return $exp->addCase(
[
$q->newExpr()->gt('Articles.modified', (new Time())->subDays(365)) // article has been updated in the last x days
],
['priority'], # values matching conditions
['string'] # type of each value
);
})
->limit(15)
->all();
The following SQL is generated:
SELECT `Articles`.`id` AS `Articles__id`, ....
FROM `articles` `Articles`
WHERE (`publish` < :c0 AND `Articles`.`publish` > :c1)
ORDER BY CASE WHEN `Articles`.`modified` > :c2 THEN :param3 END LIMIT 15
The case statement is not correct because it is missing the DESC order which should come after the 'END' - see this fiddle:
http://sqlfiddle.com/#!9/8df161/5
I'm not sure if this is a limitation with how CakePHP handles CASE?
Further I require a second order after the case statement to order by 'publish' desc.
Expressions passed to Query::order() must generate everything required by the ORDER BY clause, including the direction keyword.
If the expression that you're using doesn't support that, then you can use Query::oderAsc() or Query::oderDesc(), which will append the respective direction keyword accordingly.
$query = $this->Articles->find();
$query
->where($conditions)
->orderDesc(
$query->newExpr()->addCase(/* ... */)
)
// ...
See also
Cookbook > Database Access & ORM > Query Builder > Selecting Data
I have to convert one oracle query to snowflake,which has a where clause LEVEL > 1. Could you please suggest me the best option.
Thanks.
I don't think it's an exact match, but the closest thing is the "start with" clause of Snowflake's connect by:
SELECT <column_list> [ , <level_expression> ]
FROM <data_source>
START WITH <predicate>
CONNECT BY [ PRIOR ] <col1_identifier> = [ PRIOR ] <col2_identifier>
[ , [ PRIOR ] <col3_identifier> = [ PRIOR ] <col4_identifier> ]
...
...
You can provide a where clause on the start with predicate, but without the "where" keyword. You can read more about it here: https://docs.snowflake.com/en/sql-reference/constructs/connect-by.html
There is level in snowflake. The differences from Oracle are:
In snowflake it's neccesary to use prior with connect by expression.
And you can't just select level - there should be any existing column in the select statement.
Example:
SELECT LEVEL, dummy FROM
(select 'X' dummy ) DUAL
CONNECT BY prior LEVEL <= 3;
LEVEL DUMMY
1 X
2 X
3 X
4 X
I am trying to use cascading parameters to filter this Pivot table in SSRS Report Builder.
This is the main dataset query:
SELECT * FROM(
SELECT *,
CASE WHEN PLN=PLN THEN '01. GROSS PREMIUM'
ELSE NULL
END AS PREMIUM
FROM MYI
PIVOT (SUM(GROSS_PREMIUM_1) FOR PERIOD_TYPE IN([MTD],[YTD],[ITD])) pvt
UNION ALL
SELECT *,
CASE WHEN PLN=PLN THEN '02. REFUND'
ELSE NULL
END AS PREMIUM
FROM MYI
PIVOT (SUM(REFUND_2) FOR PERIOD_TYPE IN([MTD],[YTD],[ITD])) pvt
)A
WHERE ACC_PERIOD = #ACC_PERIOD
AND REINSURER IN (#REINSURER)
AND INSURER IN (#INSURER)
AND PLN IN (#PLN)
AND SVC_AGY IN (#SVC_AGY)
These parameters in the WHERE clause each have their own dataset and are cascaded from top to bottom.
Here is the query for the final parameter as an example:
SELECT DISTINCT [fasren_servicingagency]
FROM [FAS_ReinsuranceNumber]
WHERE ACC_PERIOD = #ACC_PERIOD
AND REINSURER IN (#REINSURER)
AND INSURER IN (#INSURER)
AND PLN IN (#PLN)
ORDER BY SVC_AGY
The query runs fine in SSMS, but I keep getting this error when I run it in the SSRS report builder:
An expression of non-boolean type specified in a context where a condition is expected, near ','
It must have something to do with the WHERE clause in either the main query or the parameter dataset queries. I have seen many posts about this error but I could not find a solution that helped with my problem. Any ideas?
NOTE: all parameters are character fields, no integers, no date columns.
EDIT: There is another query that I was successful with;
SELECT [acctyymm],
[retrosummary],
[retroagent],
[coveragedivision],
[policyinsurer],
SUM([NetDue]) AS NET_DUE,
SUM([ActualPayable]) AS PAYABLE
FROM [dbo].[RetroNumberGAAP]
WHERE [acctyymm] IN (#ACC_PERIOD)
AND [retrosummary] IN (#RETSUM)
AND [retroagent] IN (#RETAGT)
AND [coveragedivision] IN (#PLN)
AND [policyinsurer] IN (#INSURER)
AND POWER([fasrtng_NetDue],2)+POWER([ActualPayable],2)<>0
GROUP BY [acctyymm],
[retrosummary],
[retroagent],
[coveragedivision],
[policyinsurer]
How am I successful running the report with cascaded parameters in this second query and not the first query?
I figured out what I did wrong. My Dataset properties were not configured correctly in the Report Builder.
WRONG CONFIGURATION
Dataset properties; Parameters; parameter name: SVC_AGY Parameter Value: [#SVC_AGY]
CORRECTED CONFIGURATION
Dataset properties; Parameters; parameter name: #SVC_AGY Parameter Value: [#SVC_AGY]
Make sure your parameter names match your parameter values, including the # symbol.
Could anybody please explain why NHibernate on MsSql2012Dialect generates query that can not be processed by server? It builds query this way when there is no sorting specified explicitly.
...
ORDER BY CURRENT_TIMESTAMP
OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY
This is unresolved bug registered in jira, based on the suggestions, this is my work around:
public class MyMsSql2012Dialect : MsSql2012Dialect
{
public override SqlString GetLimitString(SqlString querySqlString, SqlString offset, SqlString limit)
{
var result = base.GetLimitString(querySqlString, offset, limit);
return result.Replace("ORDER BY CURRENT_TIMESTAMP", "ORDER BY 1");
}
}
As you said in the question, following query is generated if no ORDER BY is explicitly specified:
SELECT
distinct this_.ColumnName as y0_
FROM
[DB].[dbo].Table this_
ORDER BY
CURRENT_TIMESTAMP OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY;
Error is:
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
Error only occur if BOTH Projections.Distinct and Take(1) is provided and SQL Server version is above 2012 (Dialect is MsSql2012Dialect or above).
The better solution is to provide the ORDER BY column to NHibernate explicitly and include that column in SELECT list.
Session.QueryOver<Entity>()
.Select(
Projections.Distinct(Projections.Property<Entity>(x => x.ColumnName))
)
.Where(....)
.OrderBy(Projections.Property<Entity>(x => x.ColumnName)).Asc()
.Take(1);
I get an execution error in following SQL script:
SELECT TOP 1 PERCENT
a.accode, a.voucherdate, a.credit, a.Debit,
SUM(a.Debit) OVER (ORDER BY [a.accode],[a.voucherdate]) AS rdr
FROM
VoucherMain AS a
ORDER BY
a.accode, a.voucherdate
Error message
Incorrect syntax near 'order'
Can anyone tell me what's wrong with my syntax?
The problem is that you need SQL Server 2012 and above. Okay, I added the "and above" for future visitors, but compare 2008 OVER CLAUSE with 2012 OVER CLAUSE.
The 2008 version has this important note:
When used in the context of a ranking window function, <ORDER BY
Clause> can only refer to columns made available by the FROM clause.
An integer cannot be specified to represent the position of the name
or alias of a column in the select list. <ORDER BY Clause> cannot be
used with aggregate window functions.
In SQL Server 2008, you can only use the OVER clause to partition aggregate functions, not apply an order:
Ranking Window Functions
< OVER_CLAUSE > :: =
OVER ( [ PARTITION BY value_expression , ... [ n ] ]
< ORDER BY_Clause> )
Aggregate Window Functions
< OVER_CLAUSE > :: =
OVER ( [ PARTITION BY value_expression , ... [ n ] ] )
Note that there's no <ORDER BY Clause> for the aggregates.