Minimal example
select a.order_id as X from orders as a
WHERE
X > 8000
query will fail as X is not a column, any solution?
other example
select (if (E.size > 0, E.Size, (B.height x B.width)) as sizeX from
orders as a, report as E, size as B
where
(E.id = a.id and B.id = a.id)
and
sizeX > 100
my query may contain typos, but I hope my question is clear
You have 2 options:
1) Use HAVING (not very efficient since the conditions from having clause are applied AFTER the results are returned and thus NO indexes are used)
select a.order_id as X from orders as a
HAVING
X > 8000
2) Use the column name (efficient if you have a index an the column used in where clause)
select a.order_id as X from orders as a
WHERE
a.order_id > 8000
Standard SQL disallows references to column aliases in a WHERE clause see the doc here
Related
I have an SQL query as follows:
SELECT p.Id1,p.Id2,p.Id3
FROM dataset1 p
WHERE p.Id2 IN (
SELECT r.Id4
FROM dataset1 r
WHERE r.Id5=125 AND r.Id6>=100000000000000 AND r.Id6<1000000000000000
)
ORDER BY p.Id1 DESC, p.Id2 DESC
However there appears to be huge amounts of data with Id6 in this range and thus, it takes a quite long time to compute. But I only have one hour to compute the query. I thus, am wondering if someone could help me to improve the performance of this query.
Thanks.
Since the filtering seems to be done on r, arrange for it to be looked at first:
SELECT p.Id1, p.Id2, p.Id3
FROM ( SELECT id4
FROM dataset1 AS r
WHERE r.id5 = 125
AND r.Id6 >= 100000000000000
AND r.Id6 < 100000000000000 ) AS x
JOIN dataset1 AS p ON p.id2 = x.id4
ORDER BY p.Id1 DESC, p.Id2 DESC;
For that, these indexes should be beneficial:
INDEX(id5, id6, id4) -- covering
INDEX(id2, id1, id3) -- covering
You have a "range" test on id6, yet the range is empty. I assume that was a mistake. Please don't simplify a query too much; we might give you advice that does not apply. I am assuming that the range is really a range.
IN tend to optimize poorly when the subquery returns a lot of data. You can try using EXISTS instead:
SELECT p.Id1, p.Id2, p.Id3
FROM dataset1 p
WHERE EXISTS (
SELECT 1
FROM dataset1 r
WHERE
r.Id4 = p.Id2
AND r.Id5 = 125
AND r.Id6 >= 100000000000000
AND r.Id6 < 100000000000000
)
ORDER BY p.Id1 DESC, p.Id2 DESC
Then, consider a multi-column index on (Id4, Id5, Id6) to speed up the subquery. The idea is to put the more restrictive criteria first - so obviously you want Id6 last, but you might want to try inverting the first two columns to see if any combination performs better than the other.
Side note: both the lower and upper bound for Id6 have the same value in your query. I take this as a typo (otherwise your query would always return no row).
To improve performance don't use an inner query. You can get you desired result by using an inner join too:
SELECT
p.Id1, p.Id2, p.Id3
FROM
dataset1 p
INNER JOIN
dataset1 r ON p.Id2 = r.Id4
AND r.Id5 = 125
AND r.Id6 >= 100000000000000
AND r.Id6 < 100000000000000
ORDER BY
p.Id1 DESC, p.Id2 DESC
I think the title explain very well my issue, I looked at a lot of subject in forum and else about this but I am still stuck. I don't really understand how to do it, and maybe someone here will be able to make me understand. (I hope)
My query is here:
SELECT Name, A, B, C, D, E, F
FROM Data
INNER JOIN User_Access ON Data.Name = User_Access.Name
WHERE User_Access.Channel = 'TEST'
I know that I have to use an alias for "Name" but I can not do it.
For now, I think my best almost-answer to my issue is this :
SELECT Name AS N, A, B, C, D, E, F
FROM Data
INNER JOIN User_Access ON Data.N = User_Access.Name
WHERE User_Access.Channel = 'TEST'
But it's not working and I have an invalid name error.
Thank's in advance for your help !
SELECT User_Access.Name, A, B, C, D, E, F
FROM Data
INNER JOIN User_Access ON Data.N = User_Access.Name
WHERE User_Access.Channel = 'TEST'
I have replaced the Name (as is key word) with User_Access.Name (changing the column name that is appending with the actual table's name).
Where a column name is common between n tables you need to qualify it so that sql knows which one you mean.This will work
SELECT data.Name, A, B, C, D, E, F
FROM Data
INNER JOIN User_Access ON Data.Name = User_Access.Name
WHERE User_Access.Channel = 'TEST'
as will
SELECT d.Name, A, B, C, D, E, F
FROM Data d
INNER JOIN User_Access ON d.Name = User_Access.Name
WHERE User_Access.Channel = 'TEST'
From Logical Processing Order of the SELECT statement:
The following steps show the logical processing order, or binding
order, for a SELECT statement. This order determines when the objects
defined in one step are made available to the clauses in subsequent
steps. For example, if the query processor can bind to (access) the
tables or views defined in the FROM clause, these objects and their
columns are made available to all subsequent steps. Conversely,
because the SELECT clause is step 8, any column aliases or derived
columns defined in that clause cannot be referenced by preceding
clauses. However, they can be referenced by subsequent clauses such as
the ORDER BY clause. The actual physical execution of the statement is
determined by the query processor and the order may vary from this
list.
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
Notice that the SELECT is in position 8, where as JOIN and ON are in positions 3 and 2 respectively. Therefore you cannot reference a column by it's alias defined in the SELECT in the ON; as the SELECT hasn't been processed yet. Effectively, the only place you can reference a column by it's alias (in the same scope) is in the ORDER BY.
If you really wanted to to this, you could use as CROSS APPLY and VALUES operator, but (honestly) you wanting to type N instead of Name in the ON is more laziness:
SELECT V.N, D.A, D.B, D.C, D.D, D.E, D.F --I assume there are all from the Data table
FROM Data D
CROSS APPLY (VALUES(D.[Name])) V(N)
INNER JOIN User_Access UA ON V.N = UA.Name
WHERE UA.Channel = 'TEST';
Name is a reserved word, you need to enclose that in square bracket
SELECT [Name], A, B, C, D, E, F
FROM Data
INNER JOIN User_Access ON Data.N = User_Access.Name
WHERE User_Access.Channel = 'TEST'
For the following command below
Does MySQL do the joins before or after getting the 100 rows from
the table A?
Is there a way to rewrite the query to get the rows
from table A before the joins are made?
SELECT
A.START_TIME, A.F1, A.F2, B.STRING
FROM
A INNER JOIN B ON A.B_ID=B.ID
WHERE
A.START_TIME>= '2015-03-22 05:23:44'
LIMIT 0, 100;
No, the limit is applied after the join on the combined dataset.
If you want to apply the limit on table A only before the join, then you need to use a subquery:
SELECT
T.START_TIME, T.F1, T.F2, B.STRING
FROM
(select A.START_TIME, A.F1, A.F2 from A WHERE A.START_TIME>= '2015-03-22 05:23:44' limit 0, 100) T INNER JOIN B ON T.B_ID=B.ID;
MySQL query execution engine applies LIMIT by counting the result set rows and stopping once the target count has been reached. Generally if you have a key on START_TIME in A and on ID in B, and the records found in A usually have a match in B, this query should be very fast. If the join order is A,B (which should happen with the above keys), then the result rows are produced as the execution works its way through A going through the index, then if a match is found in B, the row is output and immediately becomes available to check against the counter from LIMIT.
1-It gets all of rows then makes JOIN
2- SELECT
A.START_TIME, A.F1, A.F2, B.STRING
FROM
A **!LEFT!** JOIN B ON A.B_ID=B.ID
WHERE
A.START_TIME>= '2015-03-22 05:23:44'
LIMIT 0, 100;
I have been trying the following query using group by and inner join clause in asp.net:
SELECT tblVendorItem.Name AS Product,
tblEventItem.Quantity * tblEventItem.Price AS Sale
FROM
tblEventService
INNER JOIN tblEventItem ON
tblEventService.EventServiceID = tblEventItem.EventServiceID
INNER JOIN tblVendorItem ON
tblVendorItem.VendorItemID = tblEventItem.VendorItemID
WHERE
(tblEventService.VendorID = 2)
GROUP BY
tblVendorItem.Name, tblEventItem.Quantity, tblEventItem.Price
On executing this, what I get is:
What I really want is, Product should be not repeated and the total sales should come!
For eg: Mercedes 75
Can any one help me out?
I am attaching the database also:
INNER JOIN tblEventItem ON
tblEventService.EventServiceID = tblEventItem.EventServiceID
GROUP BY
tblVendorItem.Name, tblEventItem.Quantity, tblEventItem.Price
In the group by clause, remove tblEventItem.Quantity, tblEventItem.Price. Hence your query should be changed in two places.
First, SUM(price*quantity) and second:
GROUP BY
tblVendorItem.Name
The reason is this:
Group By X means put all those with the same value for X in the one group.
Group By X, Y means put all those with the same values for both X and Y in the one group.
Group By X means put all those with the same value for X in the one group.
Group By X, Y, Z means put all those with the same values for both X ,Y and Z in the one group.
I hope this helps.Using group by on multiple columns
Kudos! :)
Since you can't use a calculated column in a where-clause in MySQL like this:
SELECT a,b,c,(a*b+c) AS d FROM table
WHERE d > n
ORDER by d
you have to use
SELECT a,b,c,(a*b+c) AS d FROM table
WHERE (a*b+c) > n
ORDER by d
Is the calculation (in that example "(a*b+c)" executed once per row or twice? Is there a way to make it faster? I find it strange it's possible to ORDER on the column but not to have a WHERE-clause.
You can use HAVING to filter on a computed column:
SELECT a,b,c,(a*b+c) AS d, n FROM table
HAVING d > n
ORDER by d
Note that you need to include n in the SELECT clause for this to work.
You could do this:
SELECT a,b,c,d FROM
(SELECT a,b,c,(a*b+c) AS d) AS tmp
WHERE d > n
ORDER BY d
But I am not sure what performance implications it could have.