ORDER BY items must appear... but I have no ORDER BY clause - sql

I am getting the well-documented error:
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
Here's my SQL statement:
INSERT INTO PropertyList
(PropertyID, Initials)
SELECT DISTINCT P.PropertyID, "vSTEBCodes"
FROM Property AS P INNER JOIN ValiditySTEBCodes AS VC
ON P.ControlNumber=VC.ControlNumber
As you can see there is no ORDER BY statement in sight. Presumably there is an implied ORDER BY in there somewhere, but I can't see it.
I am running this statement against linked tables in MS Access that are linked to a SQL Server 2008 back-end. When I run it from a full version of Access 2002, it runs without issue. If I try to run it from an Access 2000 runtime I receive the error shown.
I know that Access has a tendency to re-write queries in the background before forwarding them to ODBC sources (especially multi-record INSERTs and UPDATEs). I'm thinking that may be the issue.

Compiling from the comments, try:
INSERT INTO dbo.PropertyList(PropertyID, Initials)
SELECT P.PropertyID, Initials = 'vSTEBCodes' -- alias and single quotes
FROM dbo.Property AS P -- always use schema prefix
INNER JOIN dbo.ValiditySTEBCodes AS VC
ON P.ControlNumber = VC.ControlNumber
GROUP BY P.PropertyID -- instead of DISTINCT
ORDER BY P.PropertyID; -- maybe overrides Access stupidity

Related

Shorten the table names

I am using SQL Server and wondering if it's possible to shorten the table names. For example, my current SQL syntax is:
SELECT
t.Titlename
FROM [dbo].[Order] o
JOIN [dbo].[Title] t ON o.titleid=t.TitleId
However, if I just try doing select titlename from order I get an error. Why is this so? What would be the 'shortest' tablename I could reference; and why is it requiring the [dbo] namespace?
It doesn't require the [dbo] namespace, assuming that is the currently selected database. But it does require the Title table to be joined to Order to get the Titlename column:
SELECT
t.Titlename
FROM [Order] o
JOIN Title t ON o.titleid=t.TitleId
Demo on SQLFiddle
Note that Order must be enclosed in [] because it is an SQL reserved keyword.
It's also worth noting the point that is made in the article #GregLow mentions, which indicates that queries cannot be reused if object name resolution needs to occur. So it would generally be preferred to write the query as you originally did.
If your currently selected database be dbo, then it shouldn't be necessary to use the fully qualified object name. However, you have another problem, because ORDER is a reserved SQL Server keyword. The following should work:
SELECT t.Titlename
FROM [Order] o
INNER JOIN [Title] t
ON o.titleid = t.TitleId;
Here, using [Order] instead of Order counts as escaping that table name.

Filtering on a derived column in UniOLEDB

I am working on a piece of SQL for a IBM U2 Rocket database. It's not a flavour of db platform I'm familiar with.
I do not have direct access to this database: I can only access it by composing statements in the calling code and testing it from there. That makes it kind of awkward to figure out where the problem is when there are syntax errors.
I'm trying to compose a query which has a condiational on a dervied column. As far as I can tell from what I've read about the database, this ought to work:
SELECT a.*
FROM (
SELECT dp.NAME
,dp.Code
,dp.BusinessType + ts.BusinessType AS bType
FROM dataPoints dp
LEFT OUTER JOIN trialSuppliers ts
WHERE ts.AccountStatus = 'A'
) a
WHERE a.bType LIKE '%cho%'
However, it throws this error:
Died in UCI::SQLExecDirect() with SQLSTATE 37000, Native error:0
[IBM][SQL Client][UNIDATA]
If you just run the inner query, it works fine. Trying to use any kind of inner select statement causes it to throw the same error, i.e. this:
SELECT *
FROM (
SELECT dp.NAME
,dp.Code
,dp.BusinessType + ts.BusinessType AS bType
FROM dataPoints dp
LEFT OUTER JOIN trialSuppliers ts
WHERE ts.AccountStatus = 'A'
)
Still fails.
What's the correct syntax to be able to filter my query by the derived column?
Just doing some clean-up, did the last comment resolve the issue?
I am not a UniData user but in its half cousin UniVerse the "from clause" has to be a table. You have to do sub-queries in the where clause. I would do what you want to do adding a couple of I-descriptors in the dictionary. I have often found the limited SQL compliance of the U2 products to be somewhat of a hindrance, but when your metadata is external to and separate from your data you are going to lose a bit of structured query sanity. – Van Amburg Sep 21 '17 at 17:31

Access SQL Syntax error: missing operator

I am trying to convert a T-SQL query to MS Access SQL and getting a syntax error that I am struggling to find. My MS Access SQL query looks like this:
INSERT INTO IndvRFM_PreSort (CustNum, IndvID, IndvRScore, IndRecency, IndvFreq, IndvMonVal )
SELECT
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal
FROM
IndvMast
INNER JOIN
OHdrMast ON IndvMast.IndvID = OHdrMast.IndvID
INNER JOIN
MyParameterSettings on 1=1].ProdClass
INNER JOIN
[SalesTerritoryFilter_Check all that apply] ON IndvMast.SalesTerr = [SalesTerritoryFilter_Check all that apply].SalesTerr
WHERE
(((OHdrMast.OrdDate) >= [MyParameterSettings].[RFM_StartDate]))
GROUP BY
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal,
[CustTypeFilter_Check all that apply].IncludeInRFM,
[ProductClassFilter_Check all that apply].IncludeInRFM,
[SourceCodeFilter_Check all that apply].IncludeInRFM,
IndvMast.FlgDontUse
I have reviewed differences between MS Access SQL and T-SQL at http://rogersaccessblog.blogspot.com/2013/05/what-are-differences-between-access-sql.html and a few other locations but with no luck.
All help is appreciated.
update: I have removed many lines trying to find the syntax error and I am still getting the same error when running just (which runs fine using T-SQL):
SELECT
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal
FROM
IndvMast
INNER JOIN
OHdrMast ON IndvMast.IndvID = OHdrMast.IndvID
INNER JOIN
[My Parameter Settings] ON 1 = 1
There are a number of items in your query that should also have failed in any SQL-compliant database:
You have fields from tables in GROUP BY not referenced in FROM or JOIN clauses.
Number of fields in SELECT query do not match number of fields in INSERT INTO clause.
The MyParameterSettings table is not properly joined with valid ON expression.
Strictly MS Access SQL items:
For more than one join, MS Access SQL requires paired parentheses but even this can get tricky if some tables are joined together and their paired result joins to outer where you get nested joins.
Expressions like ON 1=1 must be used in WHERE clause and for cross join tables as MyParameterSettings appears to be, use comma-separated tables.
For above reasons and more, it is advised for beginners to this SQL dialect to use the Query Design builder providing table diagrams and links (if you have the MS Access GUI .exe of course). Then, once all tables connect graphically with at least one field selected, jump into SQL view for any nuanced scripting logic.
Below is an adjustment to SQL statement to demonstrate the parentheses pairings and for best practices, uses table aliases especially with long table names.
INSERT INTO IndvRFM_PreSort (CustNum, IndvID, IndvRScore, IndRecency, IndvFreq, IndvMonVal)
SELECT
i.CustNum, i.IndvID, i.IndvRScore, i.IndRecency, i.IndvFreq, i.IndvMonVal
FROM
[MyParameterSettings] p, (IndvMast i
INNER JOIN
OHdrMast o ON i.IndvID = o.IndvID)
INNER JOIN
[SalesTerritoryFilter_Check all that apply] s ON i.SalesTerr = s.SalesTerr
WHERE
(o.OrdDate >= p.[RFM_StartDate])
GROUP BY
i.CustNum, i.IndvID, i.IndvRScore, i.IndRecency, i.IndvFreq, i.IndvMonVal
And in your smaller SQL subset, the last table does not need an ON 1=1 condition and may be redundant as well in SQL Server. Simply a comma separate table will suffice if you intend for cross join. The same is done in above example:
SELECT
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal
FROM
[My Parameter Settings], IndvMast
INNER JOIN
OHdrMast ON IndvMast.IndvID = OHdrMast.IndvID
I suppose there are some errors in your query, the first (more important).
Why do you use HAVING clause to add these conditions?
HAVING (((IndvMast.IndRecency)>(date()-7200))
AND (([CustTypeFilter_Check all that apply].IncludeInRFM)=1)
AND (([ProductClassFilter_Check all that apply].IncludeInRFM)=1)
AND (([SourceCodeFilter_Check all that apply].IncludeInRFM)=1)
AND ((IndvMast.FlgDontUse) Is Null))
HAVING usually used about conditions on aggregate functions (COUNT, SUM, MAX, MIN, AVG), for scalar value you must put in WHERE clause.
The second: You have 12 parenthesis opened and 11 closed in HAVING clause

SQL Remove Duplicate header when doing inner join

I'm trying to Remove the Duplicate Header of my Query...
here's my query
Select po.BranchOrderNumber,pod.ItemCode, pod.ItemDescription From RetailPosOrders po
INNER JOIN RetailPosOrderDetails pod
ON po.BranchOrderID = pod.OrderID
my query's result now look's like this.
now what I want is something like this.
thanks in advance. I was planning to use this on Report builder.. I am using Microsoft Sql Server 2014.
This is the type of transformation that is best done at the application level. It is possible in SQL, but do recall that SQL queries and result sets -- by default -- are unordered. Your desired results have an ordering.
But, you can do this using row_number():
Select (case when row_number() over (partition by po.BranchOrderNumber order by pod.ItemCode) = 1
then po.BranchOrderNumber else ''
end) as BranchOrderNumber
pod.ItemCode, pod.ItemDescription
From RetailPosOrders po INNER JOIN
RetailPosOrderDetails pod
ON po.BranchOrderID = pod.OrderID
Order by po.BranchOrderNumber, pod.ItemCode;
This assumes that po.BranchOrderNumber -- despite its name -- is stored as a string (the leading zeroes suggest that this is the case).
Also, a couple of important things:
The outer order by needs to be the same as the fields used in the over clause.
The fields need to uniquely define each row in the result set. The order by in SQL is not stable, meaning that keys with the same value can appear in any order, even for different runs of the same query.
There is no way to do this in Mssql server itself.
I think you have to do it in the application level if you are going to display it using console/ win / web application.

Cross-database queries with numbered database name

I'm a bit of a novice when it comes to SQL Server 2005. I have a database containing most of the stored procedures and tables (we'll call it 'GrandDatabase'). Each user has its own separate database named after the user's numbered ID. So I have a database list as follows, for example:
GrandDatabase
100
101
102
...
I need to join tables across the GrandDatabase and a user's database. I've read elsewhere that the following should work, when executed from GrandDatabase:
SELECT
*
FROM
GrandDatabase.User INNER JOIN
100.dbo.UserInfo ON GrandDatabase.User.UserID = 100.dbo.UserInfo.UserID
This gives me a syntax error, complaining about the '.' right after the first reference to the 100 database. I did a little tweaking and discovered that this code works fine when I use non-numbered databases (for instance, replacing the '100' above with 'User100'). Does anybody know how to make this work with numbered database names?
Thanks!
Chris
Try using [100].dbo.UserInfo instead of just the 100.
Try putting the numbers into square brackets and using aliases, e.g.:
SELECT *
FROM GrandDatabase.User
INNER JOIN [100].dbo.UserInfo u
ON GrandDatabase.User.UserID = u.UserID
Try enclosing the database name with brackets:
SELECT
*
FROM
GrandDatabase.User INNER JOIN
[100].dbo.UserInfo ON GrandDatabase.User.UserID = [100].dbo.UserInfo.UserID