MySQL nested query won't run, runs on SQL Server - mysql

I'm running multiple queries on both MySQL and SQLServer (same queries on both servers, same db). Almost all of them run fine. I have a problem with this one:
SELECT
`Extent1`.`IdGosc`,
`Extent2`.`Imie`,
`Extent2`.`Nazwisko`
FROM `TGosc` AS `Extent1`
INNER JOIN `TOsoba` AS `Extent2` ON `Extent1`.`IdGosc` = `Extent2`.`IdOsoba`
WHERE EXISTS(
SELECT 1 AS `C1`
FROM (
SELECT `Extent3`.`IdRezerwacja`
FROM `TRezerwacja` AS `Extent3`
(here!) WHERE `Extent1`.`IdGosc` = `Extent3`.`IdGosc`) AS `Project1`
)
It runs on SQL Server just fine, returns correct results, but MySQL says:
Error Code: 1054. Unknown column 'Extent1.IdGosc' in 'where clause'.
Why so? :|
Are there any limitations about MySQL nested queries?
(Please don't offer queries that return the same and work, I can do that as well, but it's not my point)

I have seen this problem on MySQL.
SELECT `Extent1`.`IdGosc`, `Extent2`.`Imie`, `Extent2`.`Nazwisko`
FROM `TGosc` `Extent1` INNER JOIN
`TOsoba` `Extent2`
ON `Extent1`.`IdGosc` = `Extent2`.`IdOsoba`
WHERE EXISTS (SELECT `Extent3`.`IdRezerwacja`
FROM `TRezerwacja` AS `Extent3`
(here!) WHERE `Extent1`.`IdGosc` = `Extent3`.`IdGosc`
)
Fortunately, in this case, you can just eliminate the middle subquery.

I too have faced this sort of error in mysql.What I have done at tht tym is :
mysql remember only current table so try to do it may b it would work
replace
FROM `TRezerwacja` AS `Extent3
with
FROM `TRezerwacja` AS `Extent3`,`TGosc` AS `Extent1`

Ok. It turns out to be the problem with MySQL.
I'm using Entity Framework's query, that later turns into db specific SQL. I this case MySQL. So, the query in EF is:
var query3a = from TGosc gosc in context.TGosc
where gosc.TRezerwacja
.Any(x => x.TPlatnosc
.Any(y => y.Kwota > 100000))
select new { gosc.IdGosc, gosc.TOsoba.Imie, gosc.TOsoba.Nazwisko };
Now, the provider in my app is Connector NET 6.7.4. It includes MySQL.Data and MySQL.Data.Entities, both in version 6.7.4.
However, I also installed MySQL for Visual Studio 1.0.2 to be able to use more GUI than code in Visual Studio. But this thing comes with same dlls, just in different (older) versions 6.6.5. And these took precedence over the newer ones when application was running. (It's weird in the first place that in the same MySQL Installer there are two somehow conflicting versions of the same dlls.)
Anyway, I removed MySQL for Visual Studio 1.0.2, which left me with the newer dlls and see what happens to the very same LINQ to Entities query, when it's being translated to db sql:
--old 6.6.5
SELECT
Extent1.IdGosc,
Extent2.Imie,
Extent2.Nazwisko
FROM TGosc AS Extent1
INNER JOIN TOsoba AS Extent2 ON Extent1.IdGosc = Extent2.IdOsoba
WHERE EXISTS(
SELECT 1 AS C1
FROM (
SELECT Extent3.IdRezerwacja
FROM TRezerwacja AS Extent3
WHERE Extent1.IdGosc = Extent3.IdGosc) AS Project1
WHERE EXISTS(
SELECT 1 AS C1
FROM TPlatnosc AS Extent4
WHERE (Project1.IdRezerwacja = Extent4.IdRezerwacja)
AND (Extent4.Kwota > 100000)))
vs
-- new 6.7.4
SELECT
Extent1.IdGosc,
Extent2.Imie,
Extent2.Nazwisko
FROM TGosc AS Extent1
INNER JOIN TOsoba AS Extent2 ON Extent1.IdGosc = Extent2.IdOsoba
WHERE EXISTS(
SELECT 1 AS C1
FROM TRezerwacja AS Project1
WHERE EXISTS(
SELECT 1 AS C1
FROM TPlatnosc AS Extent4
WHERE (Project1.IdRezerwacja = Extent4.IdRezerwacja)
AND (Extent4.Kwota > 100000))
AND Extent1.IdGosc = Project1.IdGosc)
It's similar to what Gordon Linoff answered in this post. The middle subquery dissapears.
And of course the new query works fine!
Summing up, I guess the MySQL provider for .NET got better over these versions. I still have some queries that cause similar problems but now I think I know why that is - provider. I'm ok with that.
The annoying thing is that there are two different versions of dlls, one overriding another, in MySQL Installer. I'm using mysql-installer-community-5.6.13.0.

Related

MySQL syntax checking if parameter is null

I am looking for the way to execute MySQL statement checking if given parameter exists. As I remember I can do the following in Oracle to achieve that:
select s.* from Site s
where s.study = :study
and (:enabled is null or s.enabled = :enabled)
is anything like that possible in MySQL too? The same code executes without error but never return any records.
My goal here is to avoid multiple lfs and elses in my java code. It should work the way that the query looks like that when enabled parameter is null:
select s.* from Site s
where s.study = :study
and like that if the parameter is not null:
select s.* from Site s
where s.study = :study
and s.enabled = :enabled
and I want to do that with a single query
I believe this is what you are asking:
SELECT s.* from Site s
WHERE s.study = "some_study"
AND (s.enabled IS NULL OR s.enabled = '' OR s.enabled = "enabled");
Unfortunately it is highly dependent on database driver. My initial query works when run in database tools but doesn't have to when it comes to run it by JPA. So I'm to close this question as it doesn't require further answers. I'm sorry lads for wasting your time.

SSDT - CROSS APPLY OPENJSON

Trying to write a stored procedure in SSDT like below:
CREATE PROCEDURE Response.TransformHotel
#RequestIDs Request.RequestIDs READONLY
AS
BEGIN
INSERT INTO response.Hotel
SELECT EventID,
JSON_VALUE(x.[value], '$.Id') AS HotelID,
JSON_VALUE(x.[value], '$.HasSpecialOffer') AS HasSpecialOffer,
JSON_VALUE(x.[value], '$.HasClosedUserGroupSpecialOffer') AS HasClosedUserGroupSpecialOffer,
JSON_VALUE(x.[value], '$.ReviewSummary.AverageScore') AS AvarageScore,
JSON_VALUE(x.[value], '$.PercentageScore') AS PercentageScore,
JSON_VALUE(x.[value], '$.NumberOfReviews') AS NumberOfReviews
FROM Search.[Event] E
INNER JOIN #RequestIDs R ON R.RequestID = E.EventID
CROSS APPLY OPENJSON(E.MessageEvent, '$.Response.SearchResults') AS x
END
But it is giving me error "SQL46010: Incorrect Syntax near E."
However, if I write this on SSMS and execute it I get no issues.
I tried with another stored procedure and it seems OPENJSON is not available in SSDT.
CREATE PROCEDURE Request.TestOpenJSON
AS
SELECT * FROM
OPENJSON( (SELECT E.MessageEvent FROM search.Event E WHERE E.EventID = 1))
Visual Studio Profesional 2015
Version 14.0.25123.00 Update 2
.NET Framework Version 4.6.010555
Project Settings:
Target Platform: SQL Server 2016
Has anyone got any ideas? Rather not refactor the query to resolve a SSDT problem if possible.
I have used JSON VALUE and JSON QUERY throughout the project and not had any issues.
Ideas passed around is to add this as a post deploy script which also isn't great as it's a workaround rather than a solution.
Maybe too late to answer but I had the same problem with the openjson instruction when I found this post, so here my results. If you restore a database from Sql Server 2012 (for example, without support of openjson) into a Sql Server 2016, the compatibility level remains in Sql Server 2012. You have to upgrade the database (not the engine) to level 130 or better:
ALTER DATABASE database_name
SET COMPATIBILITY_LEVEL = 130
https://msdn.microsoft.com/es-es/library/bb510680.aspx

CI active record style sql queries

I am new in Code Igniter and like its active record feature now is there any useful steps or tips or any guidness how do i convert my pervoiusly written simple SQL Queries in CI style like this is my perviouly written simple query
SELECT *
FROM hs_albums
WHERE id NOT IN (SELECT album_id
FROM hs_delete_albums
WHERE user_id = 72
AND del_type = 1)
AND ( created = 72
OR club_id IN (SELECT cbs.id
FROM hs_clubs cbs
INNER JOIN hs_club_permissions cbp
ON cbs.id = cbp.club_id
WHERE cbp.user_id = 72
AND cbp.status = 2)
OR group_id IN (SELECT gps.id
FROM hs_groups gps
INNER JOIN hs_group_permissions grp
ON gps.id = grp.group_id
WHERE grp.user_id = 72
AND grp.status = 2)
OR comp_id IN (SELECT cmp.id
FROM hs_companies cmp
INNER JOIN hs_comp_permissions comp
ON cmp.id = comp.comp_id
WHERE comp.user_id = 72
AND comp.status = 2) )
The short answer is: You don't.
CodeIgniter's Active Record implementation is basically a layer on top of SQL that makes writing queries easier by:
Automatically escaping values
Automatically generating the appropriate query syntax for the database, so that the application can be more easily ported between databases (for instance, if you didn't use Active Record to write a query, and then wanted to move from MySQL to PostgreSQL, then you might well need to rewrite the query to make it work with PostgreSQL)
Providing a syntax for queries in PHP directly, thus avoiding the context switching between PHP and SQL.
However, it can't do everything SQL can do, and while I would always try to use ActiveRecord where possible, there comes a point where you're better off forgetting about using it and just using $this->db->query() to write your query directly. In this case, as mamdouh alramadan has said, CodeIgniter doesn't support subqueries so you can't replicate this query using ActiveRecord anyway.
The thing to remember is that ActiveRecord is a tool, not a requirement. If you're using CodeIgniter and aren't using an ORM instead, you should use it for the reasons mentioned above. However, once it starts getting in the way, you should consider whether it would be better practice to write your query manually instead.

MySQL statement failing on local machine but not deployment machine?

As part of work, I have been assigned to a massive Java EE project that has hundreds of SQL statements strewn throughout it. I set up the project on my computer and have been able to deploy the website just fine and use 99% of it without issue. I came across one odd case though, and that's when I try to create an entry on the website (its a government-based form sort of project). MySQL throws an exception when the program tries to execute the query:
SELECT d.id, ..., dol.weight, d.status
FROM DeliveryOrderEJB d, InbondEJB_DeliveryOrderEJB_link lnk
LEFT JOIN DOLineEJB dol
ON dol.id=(
SELECT MIN(dol2.id)
FROM DOLineEJB dol2
WHERE d.id=dol2.DeliveryOrderEJB_lines
)
WHERE d.id=lnk.DeliveryOrderEJB_id
AND lnk.InbondEJB_itNo='...'
ORDER BY d.id
The exception it gives me is Unknown column 'd.id' in 'where clause'
The part that I am confused about is why it seems to work fine on the production machine, and this appears to be the only one failing on my machine. The column clearly exists in the DeliveryOrderEJB table.
Thank you!
The failure is referring to the d.id in the nested subquery:
ON dol.id=(
SELECT MIN(dol2.id)
FROM DOLineEJB dol2
WHERE d.id=dol2.DeliveryOrderEJB_lines
)
You can fix the query:
SELECT d.id, ..., dol.weight, d.status
FROM DeliveryOrderEJB d join
InbondEJB_DeliveryOrderEJB_link lnk
on d.id=lnk.DeliveryOrderEJB_id left join
DOLineEJB dol
ON dol.id=(
SELECT MIN(dol2.id)
FROM DOLineEJB dol2
WHERE d.id=dol2.DeliveryOrderEJB_lines
)
WHERE lnk.InbondEJB_itNo='...'
ORDER BY d.id
I believe the problem is because you have different versions of MySQL on the machines. MySQL changed the semantics of the , around version 5.0.

How do I manipulate a VARCHAR field in SQL to simplify a collection of roadmaps in a Bugzilla to Redmine migration?

As per an earlier question, I'm migrating from Bugzilla to Redmine and in doing so, I'd like to make use of the road-maps which Redmine offers.
In bugzilla, bugs were always logged against the version of software which caused the issue to be raised and although I've now preserved this information in a custom field (see the earlier question mentioned above), I now need to reduce the roadmaps down to something more manageable i.e:
Change versions of all bugs which are closed to a simplified equivalent which fits with the roadmap (e.g 0.1234 becomes 0.1 and 2.9876 becomes 2.9). This allows any one road-mapped version to have up to 999 sub-versions which is what we tended to do with Bugzilla already.
Change all bugs which are open to a new 'Unplanned' version.
Remove all of the current unused version numbers
I imagine this could be achieved with the following steps:
Getting all current versions available
For each version retrieved, strip off all but the first three characters
Check whether a version number for that product already exists.
If the version number is new, add it as a new version.
Running through every issue in the database and (a) if the issue is closed, assign it to the shortened version number or (b) if the issue is still open, assign it to a 'Unplanned' version.
...but alas, my lack of SQL knowledge is letting me down. Does anyone have any idea how to solve this?
This query gets you all the 3-character version names of all existing versions, by project:
SELECT DISTINCT v.project_id, Left(v.name, 3) newversionname
FROM issues i
INNER JOIN versions v ON i.fixed_version_id=v.id
You'll need a list of all 3-character version names which do not yet exist:
SELECT f.project_id, f.newversionname
FROM (
SELECT DISTINCT v.project_id, Left(v.name, 3) newversionname
FROM issues i INNER JOIN versions v ON i.fixed_version_id=v.id
) f
LEFT OUTER JOIN versions v2 ON f.project_id = v2.project_id and f.newversionname=v2.name
WHERE v2.project_id is null
You'll need to insert new version for each result of the above query (I'll leave the adaptation of the above query as an INSERT query to you...).
EDIT: Updated query to add version details
SELECT f.project_id, f.newversionname, v3.description, v3.created_on, v3.updated_on
FROM (
SELECT v.project_id, Left(v.name, 3) newversionname, MIN(v.id) minversionid
FROM issues i INNER JOIN versions v ON i.fixed_version_id=v.id
GROUP BY v.project_id
) f
LEFT OUTER JOIN versions v2 ON f.project_id = v2.project_id and f.newversionname=v2.name
INNER JOIN versions v3 ON f.minversionid=v3.id
WHERE v2.project_id is null
This will simply select the details of the version with the lowest id for each new version.
Note: This will break if you have version bigger than 9 (ie 11.234 becomes 11.).
Now we now that for every issue associatted with an old version, there exists a new 3-character version. The following query shows which one:
SELECT DISTINCT i.id, v.id oldversionid, v.name oldversionname, v2.id newversionid, v2.name newversionname
FROM issues i
INNER JOIN versions v ON i.fixed_version_id=v.id
INNER JOIN versions v2 ON LEFT(v.name, 3) = v2.name and v.project_id = v2.project_id
WHERE v.id <> v2.id
You may use this query and adapt it as an UPDATE query after a sanity check. You'll still need to add the criteria to distinguish between the open and closed issues (status_id).
Hope this helps with your migration, have fun with redmine!