can I use a query like this:
SELECT a AS x, a AS y
FROM table
WHERE x='1' and y='2'
how can I use such as that query...
You have to take main query in temp as follow:
SELECT temp.* FROM (SELECT a AS x, a AS y
FROM table) as temp WHERE temp.x = '1' AND temp.y = '2'
In general, you cannot use column aliases defined in the SELECT in the WHERE clause. This is true in all databases, not only MySQL. One method is to use a subquery (or CTE in databases that support them).
MySQL also extends the HAVING clause. This allows you to do:
SELECT a AS x, a AS y
FROM table
HAVING x ='1' and y = '2';
I assume that this question is made up, because the query can never return any rows.
Related
I have a code like this:
SELECT column1 = (SELECT MAX(column-name21) FROM table-name2 WHERE condition2 GROUP BY id2) as m,
column2 = (SELECT count(*) FROM table-name2 WHERE condition2 GROUP BY id2) as c,
column-names
FROM table-name
WHERE condition
ORDER BY ordercondition
LIMIT 25,50
those internal selects are quite long and complicated.
My question is are there in mysql language contracts, which allow one to avoid duplicating code and computations in this case?
For example, something like this
SELECT (column1, column2) = (SELECT MAX(column-name1) as m, count(*) as c FROM table-name WHERE condition GROUP BY id),
column-names
FROM table-name
WHERE condition
ORDER BY ordercondition
LIMIT 25,50
which of course won't be interpreted by mysql.
I tried this:
SELECT (SELECT MAX(column-name1) as column1, count(*) as column2 FROM table-name WHERE condition GROUP BY id),
column-names
FROM table-name
WHERE condition
ORDER BY ordercondition
LIMIT 25,50
and it also doesn't work.
Such subqueries get cumbersome when you need more than one from the same source. Usually, the "fix" is to us a "derived table" and JOIN:
SELECT x2.col1, x2.col2, names
FROM ( SELECT MAX(c21) AS col1,
COUNT(*) AS col2,
?? -- may be needed for "cond2"
FROM t2
WHERE cond2a ) AS x2
JOIN t1
ON cond2b
WHERE cond1
ORDER BY ??? -- Limit is non-deterministic without ORDER BY
LIMIT 25, 50
If the "condition" in the subquery is "correlated", please specify it; it makes a big difference in how to transform the query.
The construct COUNT(col) is usually a mistake:
COUNT(*) -- the number of rows.
COUNT(DISTINCT col) -- the number of different values in column `col`.
COUNT(col) -- count the number of rows with non-NULL `col`.
Please provide your actual query and provide SHOW CREATE TABLE. I sloughed over several issues; "the devil is in the details".
for Edit 1
INDEX(tool, uuuuId) -- would help performance
Is uuuuId some form of "hash" or "UUID"? If so, that is relevant to seeing how the performance works. Also, how big (approximately) are the tables? What is the value of innodb_buffer_pool_size. (I am fishing for whether you are I/O-bound or CPU-bound.)
WZ needs INDEX(uuuuId, ppppppId, check1) But actually, that Select...=Yes can be turned and EXISTS for some speedup.
Z might benefit from INDEX(check1, uuuuId, ppppppId, check2)
Since Z and WZ are the same table, this might take care of both:
INDEX(ppppppId, uuuuId, check1, check2)
(The order is important.)
I use Chartio to create dashboards. I'm able to use variables with Chartio that can fill in sections of a MySQL query and then pump out a cool looking graph. I have a situation where I need a query that can have any combination of 3 variables X, Y, Z as shown below.
SELECT orderid
FROM orders
WHERE productcode IN (X) AND
status IN (Y) AND
date IN (Z);
I need to have the ability for the query to "determine" that if I only give it X, ignore Y and Z as a condition, for example. Or if I give it X and Y, ignore Z. I could give it any combinations of those three. By "ignore" I mean not use it as a condition in the WHERE clause.
Is this possible using OR? REGEXP? Wildcards? ...? I'm not very well versed in MySQL. Thanks in advance
if it sets the variable to an empty string when the user leaves the field out, you can write:
SELECT orderid
FROM orders
WHERE (X = '' OR productcode = X) AND
(Y = '' OR status = Y) AND
(Z = '' OR date = Z);
I am not a MySQL expert by any means, but after reading the documentation for the SELECT statement, I did not find an answer to my problem.
I have this statement:
SELECT COUNT(*)=x.c FROM someTable,
(SELECT COUNT(*) c
FROM someTable
WHERE firstId <= secondId) x;
And I'm trying to figure out what the x.c means in the context of the query? Specifically, what is with the x that seems to be hanging out there?
I interpret the nested SELECT as SELECT COUNT(*) as c, making an alias for the row count as c, is that what the x is as well? What would it be an alias for?
Thanks!
The x is a table alias - a name for the nested SELECT statement in parentheses.
COUNT(*)=x.c
Is a boolean condition that the total row count of someTable be equal to the row count of someTable where firstId <= secondId
x.c is the column name for the count returned by the subquery.
They name the subquery "x" and in the subquery they name the count(*) "c". So "x.c" means the count returned by the subquery.
The x is an alias to the subquery - you will note that there is an x just after the subquery, denoting the alias name for it.
x is an alias for the table (SELECT COUNT(*) c FROM someTable WHERE firstId <= secondId).
MySQL requires that table subqueries have a unique alias. You'll notice there's an x at the end of the subquery, which makes the sub queries results appear as coming from table x.
In this case, x.c in the outer query means to refer to field c (the count result) in the aliased table x, which is the subquery.
X is an alias for joined someTable and the select you joined someTable with. I guess so :D
I guessed wrong, guys over me are right :P
How can i run mysql and or query together instant of separate query.
e.g.:
And query:
select * form tablename where name='A' and password="A" and id='A';
Or query:
select * form tablename where name='A' or password="A" or id='A';
-These are 2 different query,can i make these query together?what is the syntax??
Use parentheses to group the conditions?
SELECT * FROM table WHERE (X and Y or Z) AND (P and Q or F)
Well, you can just union them but, since one is a subset of the other, it's not strictly necessary:
select * from tablename
where name = 'A' and password = 'A' and id = 'A'
union select * from tablename
where name = 'A' or password = 'A' or id = 'A'
That will give you exactly the same results as if you had just run the second query on its own. That will make sense once you realise that every single row from the first query has a name equal to 'A', so it will match the first part of the where clause in the second query.
If you want duplicate rows for those returned in both queries, just use union all instead of union.
If you were using 'A' as just a placeholder and its values are different in the two queries, then you have two approaches. Use a construct like:
... where (name = 'A' and password = 'B' and id = 'C')
or name = 'D' or password = 'E' or id = 'F'
or use the union solution I gave above, something like:
select * from tablename
where name = 'A' and password = 'B' and id = 'C'
union select * from tablename
where name = 'D' or password = 'E' or id = 'F'
(use union all when you know there is no possibility of duplicates between the two queries, - it will save the DBMS the trouble of removing non-existent duplicates - that's not the case with these queries).
The union may give better performance on a DBMS that can hive off the two selects more easily to separate query engines (something that would be more difficult with a single query with a complex where clause). Of course, as will all optimisations, measure, don't guess.
It is not clear what you expect as the result, but my guess is you want a UNION:
SELECT 1 `query`, `name`, `password`, `id`
FROM `tablename` WHERE `name`='A' and `password`='A' and `id`='A'
UNION
SELECT 2 `query`, `name`, `password`, `id`
FROM `tablename` WHERE `name`='A' or `password`='A' or `id`='A'
Note that the first column query in result is required to separate results from the two queries because union of (X and Y) and (X or Y) is always (X or Y).
Use () for such type of conditions
select * form tablename
where name='A' OR password="A" OR id='A' OR
(name='A' AND password="A" AND id='A')
If you want to check for same string as A here then you will get same o/p using following query
select * form tablename
where name='A' OR password="A" OR id='A'
Just combine the conditions with WHERE
SELECT * FROM tablename WHERE (name='A' AND password='A' AND id='A') OR name='A' OR password='A' OR id='A'
The parentheses ensure that the whole AND expressions "validates" only if ALL the containing conditions are true while the rest macthes the OR
I am writing a select subquery that returns a COUNT. However, I need to use a HAVING clause in the subquery and as a result need to specify that column in my subquery SELECT. So the result is that I have 2 columns: COUNT and column_for_having_clause.
Is there any way that i can tell SQL to take just the first column. I get an error saying
"Operand should contain 1 column(s)". I figure this must be a common problem, does anyone know a way around it?
Also, is there a way you can execute a HAVING clause without specifying the column in your SELECT query?
Thanks!
You could do
SELECT blah FROM foo WHERE bar = (SELECT cnt FROM (SELECT cnt, column_for_having_clause FROM table .... HAVING ... LIMIT 1))
Quite ugly however.
Sure, you can specify virtually any expression you want in the HAVING clause. It doesn't have to be a column from the select-list.
SELECT ...
FROM foo
WHERE x = (SELECT COUNT(*) FROM bar
GROUP BY y HAVING y = MAX(y));
But you can also, if you're comparing the count to something in the outer query, compare tuples.
SELECT ...
FROM foo
WHERE (x, 1) = (SELECT COUNT(*), y = MAX(y) AS is_max FROM bar
GROUP BY y HAVING is_max = 1);