Change order of MySQL query keywords? - mysql

I'm using this 3rd party report generating software. It has the following steps:
1) insert your SQL statement into a webpage.
2) invoke an API to send the a set of primary keys to the Query
3) A Report is generated.
Unfortunately, the software is dumb, and simply appends the WHERE clause after the SQL statement. However with MySQL the WHERE statement is supposed to be before the GROUP BY. So when the API appends a WHERE it fails because its invalid SQL. Is there some way to tell MySQL to expect the WHERE statement at the end?
select incident.incidentID,
GROUP_CONCAT(moccode2.Description) as MOC2Description
from incident
join incidentmoc on incident.IncidentID = incidentmoc.IncidentID
inner join moccode2 on moccode2.id = incidentmoc.moccodeid
/* WHERE should go here */
group by incident.incidentID
/* I want the WHERE to go here */
Derek Kromm is basically correct in what I asked for, unfortunately I have additional constraints. It's still going to append the WHERE.
So I tried this:
select incident.incidentID,
GROUP_CONCAT(moccode2.Description) as MOC2Description
from incident
join incidentmoc on incident.IncidentID = incidentmoc.IncidentID
inner join moccode2 on moccode2.id = incidentmoc.moccodeid
group by incident.incidentID
HAVING incident.IncidentID > 1
////////////////////////////////////////
now software appends WHERE invalid SQL

Use the HAVING keyword
This link has some details around using it: http://www.mysqltutorial.org/mysql-having.aspx

Related

Not the same result between SqLite and MariaDb SELECT

I have 2 tables on Debian server, rides and steps.
From a Xamarin app I get data from this server (Refit, Newtonsoft Json and SQLite-net PCL packages) to populate local tables.
When I use this query on mariadb:
SELECT 1_steps.*
FROM 1_rides, 1_steps
WHERE 1_rides.id=1_steps.ride_id
AND 1_rides.start=1
GROUP BY 1_rides.id
I got correct results (first step of each ride, then it starts with 1)
But when use equivalent for SqLite:
SELECT Steps.*
FROM Rides,Steps
WHERE Rides.Id=Steps.RideId
AND Rides.Start=1
GROUP BY Rides.Id
In the result, I get the last step of each (same) ride!
Whether on mariadb or sqlite, each table has a primary key (id field).
I checked, the data is sent, received and saved in the same order.
Simply added in mobile app with:
foreach (var step in await App.RestClient.getSteps())
if (dbCon.InsertOrReplace(step) != 1)
....
I tried adding ORDER BY Rides.Id but that does not change anything.
You are relying on something that is not allowed by strict SQL standards: whenever you have a group by clause, the fields in the select clause must either appear in the group by clause as well, or must be aggregations (e.g. min, count), or must be functionally dependent on the group by fields.
In your case those conditions are not met and so if the DB engine allows this, it will have to decide which value to pick within a same group: the first, the last, or still something else.
The way to deal with this, is to be explicit what you want to get in such a case, by specifying an aggregation:
SELECT 1_steps.id,
min(1_steps.step),
max(1_steps.whatever),
avg(1_steps.some_number),
FROM 1_rides
INNER JOIN 1_steps
ON 1_rides.id=1_steps.ride_id
WHERE 1_rides.start=1
GROUP BY 1_rides.id
You did not specify the fields of your table, but the idea should be clear: list the fields separately (not *), and apply the type of aggregation to them you need.
Alternative
If you are not interested in aggregating anything, but just want one particular record from steps per ride, then don't use group by, but specify the condition that filters exactly that one record from steps:
SELECT 1_steps.*
FROM 1_rides
INNER JOIN 1_steps
ON 1_rides.id=1_steps.ride_id
WHERE 1_rides.start=1
AND 1_steps.step = 1
ORDER BY 1_rides.id
Note the condition 1_steps.step = 1: you'll have to decide what that condition should be of course.

An item with the same key has already been added - SQL Server 2012 Subquery Issue

I am writing code within SQL server 2012 to transfer into the query designer of Report Builder 3.0.
My code works perfect within Management studio, and it works within the actualy query designer, but once I press Okay within the query designer, it throws me the error:
"Could not update a list of fields for the query. Verify that you can connect to the data source and that your query syntax is correct"
Under details:
"An item with the same key has already been added"
This is the code I am using:
Select *
from
(Select distinct srt.Name,
percentile_disc(.5) WITHIN GROUP(ORDER BY (sr.price)) OVER(PARTITION BY srt.Name) AS MedianSpend
from ServiceReq sr inner join ServiceReqTemplate srt
on srt.RecId = sr.SvcReqTmplLink_RecID Where Name like '%') medQuery
inner join
(select distinct srt.Name,
cast(sum(sr.price) as int) as AvgCost,cast(sum(sr.cost) as int) as
AvgTransCost,cast(avg(sr.TotalTimeSpent) as int) as TotalTimeSpent
from ServiceReq sr, ServiceReqTemplate srt
where sr.SvcReqTmplLink_RecID = srt.RecId
group by srt.Name) avgQuery
on medQuery.Name LIKE avgQuery.Name
I think that the problem is there would be two columns both called "Name" in one table, which is not allowed. I was thinking I could add another column in the same table, and call it "Name_2" and then copy and paste all the data from the "Name" table into "Name_2" and then use it. Would this be the easiest way of successfully implementing this code into Report Builder?
You add AS Name2 to the 2nd query and then call it after avgQuery at the end.

AS clause in influx DB

How to use AS clause in influxDB?
SELECT os_family AS OsName, os_Image AS PlatformIcon FROM statistics
When I run this query I got following error.
ERROR: syntax error, unexpected AS, expecting FROM SELECT os_family AS OsName, os_Image AS PlatformIcon FROM statistics ^^
How to use SQL like AS clause in influx DB?
The AS clause in InfluxDB is meant to be used in two cases (described below). That said we can definitely add this as a new feature if this is a common use case. I don't know if that's necessary though, if you want to get back the columns as OsName then why did you name it os_family to begin with. We can discuss this further on the mailing list (you can find information about the mailing list among other means to reach us here http://influxdb.com/community/)
The two use cases are for joining multiple time series:
select * from foo as f inner join bar as b where f.somecolumn > 0`
and to alias aggregators:
select count(value) as c from foo where foo.value > 100

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 developer here -- Nesting with select * finicky in Oracle 10g?

I'm writing a simple diagnostic query then attempting to execute it in the Oracle 10g SQL Scratchpad. EDIT: It will not be used in code. I'm nesting a simple "Select *" and it's giving me errors.
In the SQL Scratchpad for Oracle 10g Enterprise Manager Console, this statement runs fine.
SELECT * FROM v$session sess, v$sql sql WHERE sql.sql_id(+) = sess.sql_id and sql.sql_text <> ' '
If I try to wrap that up in Select * from () tb2 I get an error, "ORA-00918: Column Ambiguously Defined". I didn't think that could ever happen with this kind of statement so I am a bit confused.
select * from
(SELECT * FROM v$session sess, v$sql sql WHERE sql.sql_id(+) = sess.sql_id and sql.sql_text <> ' ')
tb2
You should always be able to select * from the result set of another select * statement using this structure as far as I'm aware... right?
Is Oracle/10g/the scratchpad trying to force me to accept a certain syntactic structure to prevent excessive nesting? Is this a bug in scratchpad or something about how oracle works?
When Oracle parses a SELECT *, it expands it out to an actual list of the columns to be selected. Since your inline view contains two columns named SQL_ID, this results in an ambiguous reference.
Interestingly, using ANSI join syntax seems to cause it to alias the duplicate column names automatically, and therefore avoids the error.
select * from
(select * from v$session sess left outer join v$sql sql on sql.sql_id=sess.sql_id and sql.sql_text <> ' ')
Incidentally, it's not clear to me why you chose that condition on sql_text. I don't expect that column would ever contain a single space. Are you really trying to filter out NULLs? If so, why use an outer join at all?
One of the general rules of thumbs at my place of employment is that SELECT * is never allowed. Explicitly define what columns you need; not only is it more readable, but less likely to have issues down the road