I have a select statement running in a jsp against SQL Server (previously using MySql without issues).
the TOP 1 was added because otherwise SQL Server moans about order by clauses (but only when displaying a result in a jsp, not when running the query inside SQL Server Management Studio).
This query runs fine in SQL Server Management Studio
SELECT TOP 1
alerts.id,
alerts.ts,
asset_firstname,
asset_lastname,
assetid,
alerttype.name,
node.zonename,
node.ipaddress,
node.zonegroupid
from
alerts, asset, alerttype, node, alertrules
where
ack=0 and
alerts.nodeid = node.id and
alerts.alerttypeid = alerttype.id and
alertrules.alerttypeid = alerts.alerttypeid and
alerts.assetid = asset.id and
alerts.alerttypeid = 1 and
asset.id=1157 and
alertrules.userid = 1
order by alerts.ts desc
but, when run in the jsp it returns "Column alerts.ts is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause".
I don't want alerts.ts aggregated or grouped by, hence the 'correct' select statement.
If I remove TOP 1 or alerts.ts desc the query returns the wrong row (earliest rather than latest record)
Converting what should be straightforward basic SQL commands so they run properly with SQL Server is proving a nightmare.
Any thoughts appreciated.
Regards
Ralph
(I wrote this as an answer because as a comment would be a mess)
You are using old style joins, and have redundant checks. Maybe this could make a difference (not sure, as it seems to be a problem related to JSP):
SELECT TOP(1)
alerts.id, alerts.ts,
asset_firstname,
asset_lastname,
assetid,
alerttype.name,
node.zonename,
node.ipaddress,
node.zonegroupid
from alerts
inner join asset on alerts.assetid = asset.id
inner join alerttype on alerts.alerttypeid = alerttype.id
inner join node on alerts.nodeid = node.id
inner join alertrules on alertrules.alerttypeid = alerts.alerttypeid
where ack=0 and
alerts.alerttypeid = 1 and
asset.id=1157 and
alertrules.userid = 1
order by alerts.ts desc;
Related
Going from MYSQL 5.1.73cll to MYSQL 10.1.19-MariaDB (and now running in PHP 7) this query goes from returning GOOD results to returning NO results.
SELECT t.eventid, t.tname, t.tdate, t.tyear, a.aname, t.ttour FROM
gs_tournaments as t LEFT JOIN gs_active as a ON a.eventid = t.eventid LEFT
JOIN gs_stats as s ON s.tid = t.tid WHERE s.pid = 34062 && a.active = 'y'
GROUP BY t.eventid ORDER BY t.tid ASC
I have searched other MYSQL upgrade posts but don't see an answer.
Any help would be appreciated.
Thw answer is to carefully walk back the query until you find what is breaking it, or in this case returning no results. In my case it was narrowing it down to the 'WHERE s.pid = 34062' which was a condition that was never met. This was due to the value 34062 being calculated incorrectly in another part of the code.
So lesson learned - carefully eliminate conditions or tests until you find the cuplprit. -- Ed
I have a query that is returning two different results from two MySql servers i'm running.
This is the query (generated by Entity Framework, I run it directly in MySql to ensure the results are coming back from each server differently):
SELECT
CASE WHEN Project1.C1 IS NULL THEN '5' ELSE Project1.data_entered END AS C1
FROM ( SELECT 1 AS X) AS SingleRowTable1
LEFT OUTER JOIN (SELECT
Extent1.data_entered,
1 AS C1
FROM rta_option_data AS Extent1
INNER JOIN rta_option_field AS Extent2 ON Extent1.rta_option_field_id = Extent2.rta_option_field_id
WHERE (Extent1.customer_id = 1546) AND (Extent2.Name = 'txtAdverseDelay') ) AS Project1 ON 1 = 1
Server A is running MySql 5.5.28 and returns 5 which is the correct and expected value.
Server B is running MySql 5.7.12-log and returns null which is the incorrect and unexpected value.
I'm at a complete loss of how to resolve this, I was planning a server upgrade this weekend but i'm super worried about other similar queries that could be impacted by this.
Additional notes:
They are both using the exact same data.
When I run the inner query on both servers they return the same results data_entered = null and C1 = null. This is the inner query i'm talking about:
SELECT
Extent1.data_entered,
1 AS C1
FROM rta_option_data AS Extent1
INNER JOIN rta_option_field AS Extent2 ON Extent1.rta_option_field_id = Extent2.rta_option_field_id
WHERE (Extent1.customer_id = 1546) AND (Extent2.Name = 'txtAdverseDelay')
Would appreciate any guidance/advice on how to possibly fix this - not sure if there is a setting in MySql or what.
I have quite a complex query to essentially select the cheapest delivery service price per delivery service.
In order to get unique records per delivery service, I utilise the DISTINCT function in SQL. This query provides correct results:
DeliveryServicePrice.active.select('DISTINCT ON (delivery_service_id) *').order('delivery_service_id, price ASC')
(only a part of the query)
However, this query only seems to work with PostgreSQL (which I think is strange considering PostgreSQL is a lot more strict with SQL standards); it does not work with MySQL and SQLite. I receive the following error:
Mysql2::Error: You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to
use near 'ON (delivery_service_id) * FROM `delivery_service_prices`
WHERE `delivery_servi' at line 1: SELECT DISTINCT ON
(delivery_service_id) * FROM `delivery_service_prices` WHERE
`delivery_service_prices`.`active` = 1 AND (2808.0 >= min_weight AND
2808.0 <= max_weight AND 104.0 >= min_length AND 104.0 <= max_length AND 104.0 >= min_thickness AND 104.0 <= max_thickness) ORDER BY delivery_service_id, price ASC
The application I'm building is open source, so it's required to support all 3 database types.
How do I create DISTINCT ON queries for MySQL and SQLite in the Rails framework syntax?
I'm using Rails 4.1.
Resources
My previous problem for reference:
How to select unique records based on foreign key column in Rails?
File and line number for where the query is being used.
Finished answer
DeliveryServicePrice.select('delivery_service_prices.id').active.joins('LEFT OUTER JOIN delivery_service_prices t2 ON (delivery_service_prices.delivery_service_id = t2.delivery_service_id AND delivery_service_prices.price > t2.price)').where('t2.delivery_service_id IS NULL')
DISTINCT ON is a Postgres specific extension to the standard SQL DISTINCT. Neither of them is a "function", both are SQL key words - even though the parentheses required after DISTINCT ON make it look like a function.
There are a couple of techniques to rewrite this with standard-SQL, all of them more verbose, though. Since MySQL does not support window-functions row_number() is out.
Details and more possible query techniques:
Select first row in each GROUP BY group?
Fetch the row which has the Max value for a column
Rewritten with NOT EXISTS:
SELECT *
FROM delivery_service_prices d1
WHERE active = 1
AND 2808.0 BETWEEN min_weight AND max_weight
AND 104.0 BETWEEN min_length AND max_length
AND 104.0 BETWEEN min_thickness AND max_thickness
AND NOT EXISTS (
SELECT 1
FROM delivery_service_prices d2
WHERE active = 1
AND 2808.0 BETWEEN min_weight AND max_weight
AND 104.0 BETWEEN min_length AND max_length
AND 104.0 BETWEEN min_thickness AND max_thickness
AND d2.delivery_service_id = d1.delivery_service_id
AND d2.price < d1.price
AND d2.<some_unique_id> < d1.<some_unique_id> -- tiebreaker!
)
ORDER BY delivery_service_id
If there can be multiple rows with the same price for the same delivery_service_id, you need to add some unique tie-breaker to avoid multiple results per delivery_service_id. At least if you want a perfectly equivalent query. My example would select the row with the smallest <some_unique_id> from each set of dupes.
Unlike with DISTINCT ON, ORDER BY is optional here.
DeliveryServicePrice.active.select(:delivery_service_id).distinct.order('delivery_service_id, price ASC')
I have a script that checks for duplicate pairs in a database and selects all entries that need to be deleted except for one.
I have this script that selects the first 100 entries that need to be deleted and works fine:
SELECT*
FROM vl_posts_testing
INNER JOIN (
SELECT max(ID) AS lastId, `post_content`,`post_title`
FROM vl_posts_testing WHERE vl_posts_testing.post_type='post'
GROUP BY `post_content`,`post_title`
HAVING count(*) > 1) duplic
ON duplic.`post_content` = vl_posts_testing.`post_content`
AND duplic.`post_title` = vl_posts_testing.`post_title`
WHERE vl_posts_testing.id < duplic.lastId
AND vl_posts_testing.post_type='post'
LIMIT 0,100
However when I try to delete this set of data using:
DELETE vl_posts_testing
FROM vl_posts_testing
INNER JOIN (
SELECT max(ID) AS lastId, `post_content`,`post_title`
FROM vl_posts_testing WHERE vl_posts_testing.post_type='post'
GROUP BY `post_content`,`post_title`
HAVING count(*) > 1) duplic
ON duplic.`post_content` = vl_posts_testing.`post_content`
AND duplic.`post_title` = vl_posts_testing.`post_title`
WHERE vl_posts_testing.id < duplic.lastId
AND vl_posts_testing.post_type='post'
LIMIT 100
I receive the fallowing error:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'LIMIT 10' at line 8
The script has been constructed using this answer https://stackoverflow.com/a/6108860/1168944
Actually the script works just fine on a small amount of data without the limits set, however due to the fact that I run it on a big table (some 600k entries) I need to split this script in a routine that processes only a limited amount of data due to server limits like processor, memory etc.
Also took into consideration this example: MySQL LIMIT on DELETE statement but the result is different since no modification is executed no matter how small is the limit.
After several retries I have found a way to make it work:
DELETE vl_posts_testing
FROM vl_posts_testing
INNER JOIN (
SELECT max(ID) AS lastId, `post_content`,`post_title`
FROM vl_posts_testing WHERE vl_posts_testing.post_type='post'
GROUP BY `post_content`,`post_title`
HAVING count(*) > 1
LIMIT 0,100 ) duplic
ON duplic.`post_content` = vl_posts_testing.`post_content`
AND duplic.`post_title` = vl_posts_testing.`post_title`
WHERE vl_posts_testing.id < duplic.lastId
AND vl_posts_testing.post_type='post'
Actually what I did is set an inner limit to the first set of data and compare it to the rest of the database in order to make it work. It work but I am not sure this is the correct way ot do it.
I have a query that's generated by LINQ and generates a time out error.
But when I run the generated query in SQL server management studio it executes in less than one second.
Here's the query:
exec sp_executesql N'SELECT COUNT(*) AS [value]
FROM [dbo].[Document] AS [t0]
INNER JOIN [dbo].[Document_Search_order_nummer](#p0) AS [t1] ON [t0].[DocumentID] = [t1].[Key]
LEFT OUTER JOIN [dbo].[DocType] AS [t2] ON [t2].[Id] = [t0].[DocumentTypeIDOut]
LEFT OUTER JOIN [dbo].[DocTypeFormat] AS [t3] ON [t3].[Id] = [t2].[FormatId]
LEFT OUTER JOIN [dbo].[DocTypeType] AS [t4] ON [t4].[Id] = [t2].[TypeId]
INNER JOIN [dbo].[OriginalDocument] AS [t5] ON [t5].[OriginalDocID] = [t0].[OriginalDocID]
INNER JOIN [dbo].[User] AS [t6] ON [t6].[User_ID] = [t0].[DocumentFrom]
INNER JOIN [dbo].[User] AS [t7] ON [t7].[User_ID] = [t0].[DocumentTo]
WHERE ([t0].[DocumentID] <> #p1)',N'#p0 nvarchar(4000),#p1 int',#p0=N'"*+11110001+*" ',#p1=270675
Below is the log from SQL server profiler:
Using LINQ:
Eventclass= RPC:Completed
ApplicationName= .Net SqlClient Data Provider
CPU= 12625
Reads= 1137844
Writes = 0
Duration = 29989
Using SQL Server Management Studio:
Eventclass= SQL:BatchCompleted
ApplicationName= Microsoft SQL Server Management Studio - Query
CPU= 78
Reads= 31645
Writes = 0
Duration = 99
What's the cause of this big performance difference with an equal query and how can I solve this issue?
We had exactly the same problem once.
One possible cause could be the parameters type mismatching that causes this.
But, this wasn't the issue in our case. Turned out that in some cases the query just takes longer time to execute. So we isolated the query and ran it trough ADO.NET SqlCommand class. Believe it or not when we added extra white spaces between the sql commands caused the query to execute much faster.
So we took the query and created a view from it. It solved our problem.