M2014 is a text field in the DB table.
This statement works correctly (returns count = 368)
SELECT count(*) FROM arealist WHERE M2014 = 'Yes'
However, I having problems with this statement (returns count = 0) All I have changed
is the concat
SELECT count(*) FROM arealist WHERE concat('M','2014') = 'Yes'
What could be the cause and solution?
You are comparing two strings in the second SELECT statement. The second statement is appending two strings 'M' and '2014' which results in the query comparing 'M2014' to 'Yes' two strings, not the value of the column. Making a statement like this:
SELECT COUNT(*)
FROM AreaList
WHERE M2014 = CONCAT('Y','es')
That statement would return 368 rows. What are you ultimately trying to do with this statement?
You can't generate a dynamic column name for the where clause in MySQL. There are a number of Stack Overflow articles to that effect. Normally, I would arrange my data so that there was some sort of date or timestamp associated with the row, rather than using date specific columns. (I'm assuming M2014 has something to do with the year 2014). When arranged this way you can select what you need based on whatever date requirements you have.
That said, if your data model is fixed, then you're best bet is probably to use another language, C#, python, whatever, to create the column names you need dynamically and then send the entire query to MySQL. Alternatively, you could write a series of SQL statements, one for date column you're interested in.
The following query in google turned up a number of relevant results: https://www.google.com/search?client=opera&q=dynamic+column+names+in+sql&sourceid=opera&ie=utf-8&oe=utf-8&channel=suggest&safe=active#channel=suggest&q=dynamic+column+names+in+mysql+where+clause&safe=active
you can do it in php like that
$year = 2014;
SELECT count(*) FROM arealist
WHERE M$year = 'Yes'
Related
I have a condition that I need to query Couchbase database field with two different where clauses in the same query.
for example:
for 'sales' field in a database entity, I want to have one query to get the sales in a single hour and whole day
output example:
`{`
`hourly_sales = 500`
`total_day_sales = 5000
`}`
I know that I can use 2 different queries, but requirement is to use one query for both
You can achieve that using case when statement. For example -
SELECT SUM(CASE WHEN `TIME` BETWEEN "13:00:00" AND "14:00:00" THEN `SALES`) AS HOURLY_SALES,
SUM(CASE WHEN `TIME` BETWEEN "00:00:00" AND "23:59:59" THEN `SALES`) AS TOTAL_DAY_SALES
FROM `BUCKET_NAME`
Make use of the time format according to your need.
I have a table with more then 2 million records,
I need to find duplication records in column with string type additionaly I have index for this field.
I have next query:
select m.* from member as m
where lower(m.username) in
(select lower(b.username) from member as b
where b.Username like 'a%'
group by b.username
having count(b.username) >= 2);
sub-query return only 4 records less then 0.2 seconds, but if I use them in where conditions section, this query working very long time and never return results....
I have tried to run next query, that theoretically the same logic:
select * from member as m where lower(Username) in (lower('a1'),
lower('a2'),lower('a3'),lower('a4'));
and it works fine and fast.
what is the issues ?
additionally I would like to run query with out where b.Username like 'a%' part?
In common case MySQL can not use index for IN subqueries
This is sad, but, actually, MySQL can not recognize "constant subqueries". What does it mean? It means that if you have a subquery that returns static list of values - and you use that in IN within another query, MySQL will not use index (by range).
Why it is so?
Actually, the most correct point is - because MySQL treats following queries:
.. WHERE `field` IN ('foo', 'bar', 'baz')
and
.. WHERE `field` IN (SELECT `col` FROM t)
-as different queries (I'm assuming that column col in table t in second query have same values, i.e. 'foo', 'bar', 'baz'). First query is equivalent for it's "expected" case, i.e. for range of values. But second query is equal for = ANY subquery - and so MySQL will not use index for that.
What to do
Actually, your case and cases similar to it - are cases when it's better to split your query into two parts. First part will be retrieve static list of values from your table. Second part will substitute result of your first part into IN clause and then you'll get index using.
Alternative - you can use JOIN syntax for table to itself. That may seems useful if you want to resolve an issue with one query (or if your list is too long)
I have a SELECT query that I am expecting millions of results from. I need to randomize these results in MySQL. Doing it in my script after the query obviously uses too much RAM. Can someone please rework this query so that the results are all random without using order by rand()? I have seen some examples and tried to use them but they don't work for me since they all seem to depend on returning the whole table rather than using a WHERE clause. Here is my query:
SELECT * FROM pool
WHERE gender = 'f'
AND (`location` = 'united states' OR `location` = 'us' OR `location` = 'usa');
If you have 10 million lines with id's, are they in a contiguous range?
Get the lowest id from the range you want via a quick select.
Get the largest id as well.
generate random numbers in this range using php
once you have your numbers "SELECT * FROM table1 WHERE id IN (the numbers you generated)" or something like that
If you can use other language, for example php you can use its rand() function to generate ids and add the to the query like
$ids = range($mini, $maxid);
shuffle($ids);
array_slice($ids, 0, $quantity);
Or something similar in any language you are using.
If you need to do this in pure mysql query then here are some alternaties: http://www.electrictoolbox.com/msyql-alternative-order-by-rand/
Is there a way in MySql to use an either or in a select column. For instance
select left(columnA,2) or right(columnA,1) as columnAlias, sum(columnB)
from table
where ((left(columnA,2) in ('aa','bb','cc')) or (right(columnA,1) in ('a,','b','c')))
group by columnAlias
what I have is a table where either the first 2 characters of the column or the last character of the column indicates the facility. I need to sum the values by facility. A union gets me part way there then I could loop through the resulting dataset and sum things up in the code (or do a stored proc to return the sums), but I am wondering if there is a way to just get it from the query.
I've tried using the union query as an on the fly temp table and doing the select and group on that but if there are no records returned from either of the select statments then it throws a "column columnA cannot be null error.
Also tried with the syntax above, but not getting the results I am expecting. Any other ways to do this through the query?
using a CASE would prob be your best bet here.
http://dev.mysql.com/doc/refman/5.0/en/case-statement.html
Not sure how far a sql query can go with if/else statements.
I have a simple SELECT statement:
SELECT amount, transtype FROM
transactions
The transtype column is going to be a number.
For example, 1 = sale, 2 = refund, 3 = error, 4 = canceled, 5 = something else.... and so on.
So, nothing complicated. But the list tends to grow for reporting reasons. Which is fine.
For a specific query I'm working on, is there a way to extract that column as one of 2 or three specified numbers or text?
For example, some transtype numbers are a 'loss', while others are a 'gain', and maybe others are 'neutral'.
I'd like to extract that column with only those 3, without using php inside the html table I'm throwing the rows into.
If my explanation is not clear, my apologies. It was hard to spit out.
Use the MySQL CASE() function for a fixed number of arguments. If the list is getting big, you should use a second table and join them.
Example:
SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;
Try joining against another table that contains the transaction types. Something like:
TRANSACTION_TYPES
transtype | number
label | varchar(32)
Then modify your query to include the join:
select t.amount, t.transtype, l.label
from transactions.t
join transaction_types l on t.transtype = l.transtype;
The ELT function should do the trick:
SELECT ELT(`transtype`, 'loss', 'loss', 'gain', 'neutral', …) FROM …
Not very elegant though, and logically I would do this in the view logic, not the database logic.
You should probably use ENUM type for that column. It's limited to 64 values, however if you would need more then you should create a new table and JOIN it in query.