Defining aliases in a statistical query - mysql

I need to do:
SELECT COUNT(*)
FROM some_table
WHERE someAlias1 = someValue1
AND someAlias2 = someValue2;
someAlias is an alias for a column in some_table. In my case I can't name the columns directly; I need to use aliases.
The issue is that I only know about defining aliases inside the select clause which I don't see how I can do in this case.
Is there a way to accomplish what I need in this case?
edit: Why do I need aliases? I'm building a query from alternative parts, and the condition above applies to different columns from different tables, but with the same logical role. So I need a way to relate to different alternative columns with the same name.
I will appreciate if you answer this question only if you know an answer, even if you don't understand why may I need an alias

You could do a nested SELECT statement then draw the count out from the inner query, I don't really see a way to escape using the column names
SELECT COUNT(*)
FROM(
SELECT col1 as someAlias1,
col2 as someAlias2
FROM some_table
WHERE someAlias1 = someValue1
AND someAlias2 = someValue2
) as inner

I can't figure out a scenario where you can't name the columns directly. If the column name is duplicated, prepend the table name:
WHERE someTable1.someColumn1 = someValue1
If the column name is a reserved keyword or contains spaces, quote it:
WHERE `some Column1` = someValue1
You can even combine both:
WHERE someTable1.`some Column1` = someValue1

Why do you need to use aliases? The only reason to use aliases in your query would be for re-use in e.g. an "having" clause, like:
select count(*) as C
from some_table
where someAlias1=someValue1
and someAlias2=someValue2
having C > someLimit1;

Related

SQL Assign "co-efficients" to query conditions and use them to sort result

I saw a query once that assigned some kind of ranking to query conditions, I can't remember it now.
They way I understood it, i think variable names (s1,s2,...) were assigned to each of the conditions with a coefficient to give them different "weights" then the sum of the variables was used to sort the result.
It looked something like this:
SELECT
*
FROM
table_name
WHERE condition1='value1' as (s1*3)
OR condition2='value2' as (s2*2)
OR condition3='value3' as (s3*1)
ORDER BY (s1+s2+s3)
So, the different numbers sort of give the conditions varying degrees of importance in the ORDER, makes it perfect for doing a related product/post search.
Please, does anyone know the right structure for this query?
In MySQL, you would define the aliases in the SELECT clause and then use them in the ORDER BY. For instance:
SELECT t.*, (condition1 = 'value1') as s1,
(condition2 = 'value2') as s2, (condition3 = 'value3') as s3
FROM table t
ORDER BY (s1*3 + s2*2 + s3*1);

Running a SQL SELECT statement against a MYSQL column of SET type

I'm trying to run a SQL SELECT statement against a column that is of type SET. The table is called myTable and the columns in myTable are called base_props and names. The base_props column is of type SET. The values in base_prop are vb,nt, cnt,poss and loc. So I would like to SELECT entries from the column 'name' where base_props have both the values, vb and poss. The results I'm looking to get may have values other than just vb and poss. So to be clear I would like to select all entries that have the values vb and poss regardless if they have other values as well. I've tried the following SQL queries but I can't get the desired results.
SELECT name from myTable WHERE base_props = 'vb' AND base_props = 'poss'
That query returns an empty result set. I've tried using FIND_IN_SET() and IN() but I couldn't get anywhere with that. I've written SQL statements before but never had to deal with columns that are type SET. Any help is appreciated.
The only thing I can come up with is using the LIKE keyword:
SELECT name FROM myTable WHERE (base_props LIKE '%vb%' AND base_props LIKE '%poss%');
This will make sure both vb and cnt are in the base_props column. Of course you can use cnt, nt and loc in there, or any number of base_props values in the sql, just add more AND statements.
OR as a deleted answer by samitha pointed out, you can use FIND_IN_SET:
SELECT name from myTable WHERE FIND_IN_SET('vb', base_props) AND FIND_IN_SET('poss', base_props);
Comment (by spencer7593): "both of these work, but there is a slight difference. The LIKE operator will actually match any member that includes the search string anywhere in a term; the FIND_IN_SET function will only match an exact member. It's also possible to search for members in set by the order they appear in the SET definition, using the MySQL BITAND operator: for example, to match the 1st and 4th members of the set: WHERE base_props & 1 AND base_props & 8". So for example, if you have 'a' and 'aaa' in your set, then using the LIKE "%a%" method will also return rows containing 'aaa'.
Conclusion: use the FIND_IN_SET solution since it will work for all cases.
FIND_IN_SET return index, Try this
SELECT name from myTable WHERE FIND_IN_SET(base_props, 'vb') > 0 AND
FIND_IN_SET(base_props, 'poss') > 0

Split the field value in a mysql JOIN query

I've got a column "code" which may have a string of multiple values e.g. "CODE1&CODE2"... I just need the first one for my JOIN ... kind of like code.split("&")[0]
SELECT myTable.*, otherTable.id AS theID
FROM myTable INNER JOIN otherTable
ON myTable.(+++ code before the & +++) = otherTable.code
The value in myTable may also just be CODE1
SUBSTRING_INDEX will do exactly what you want - return the substring of your column up to the specified character:
SELECT
myTable.*,
otherTable.id AS theID
FROM myTable
INNER JOIN otherTable
ON SUBSTRING_INDEX(myTable.code, '&', 1) = otherTable.code
More info at: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html
And here's a fiddle demoing it: http://sqlfiddle.com/#!2/96a6e/2
Please note that this will be SLOW if you're joining many columns. You're not only eliminating the possibility of using an index, but performing a very slow string operation on every comparison. I wouldn't suggest using this on very large tables. If your data set is huge, you may want to consider rearchitecting your DB.

Avoid ambiguous condition in MySQL

I'm working on a very limited MySQL environment (all MySQL calls are passed as array parameters). The problem is I don't know how to resolve an ambiguos condition.
In this environment all MySQL calls take this form:
SELECT value1,value2,...,valueN
FROM table1,table2,...,tableN
WHERE cond1 OP cond2 OP ... OP condN
That's not a problem until you have the same column names in table1 and table2. Imagine table1 has columns {a,b,z} and table2 has column names {c,d,f,z}. I can do this:
SELECT *
FROM table1, table2
WHERE a='3' AND table1.z='5'
Perfect but, one of the limitations is that I can't use table1.z format, just z='5' that produces a collision.
So, the question is: is there any way to prevent this ambiguosity without the use of table name prefix in the condition part? (for example, it will be great if there is a way to use only part of table2 or say that table1 has priority in case of ambiguity).
There is no way to avoid a collision if you can't qualify which table "myColumn" comes from.
Your constraints seem kind of silly... You're basically asking for valid result when you assert that you cannot write valid SQL....
Perhaps instead of SELECTing from table1, you would SELECT from a nested subquery in which you aliased the column names...
For example:
if table1 and table2 both have column "myColumn"
Rather than:
SELECT
*
FROM
table1,table2
WHERE myColumn = #value -- produces collision!
Could you say:
SELECT
*
FROM
(SELECT myColumn AS foo FROM table1) newTable1,
(SELECT myColumn AS bar FROM table2) newTable2
WHERE
foo = #value
This way you're not fully qualifying the tables in the outer WHERE clause but you are re-aliasing the columns inside the subqueries (thus making them into different names for the outer query)
This seems like a roundabout exercise though
EDIT:
http://thedailywtf.com/Articles/SQL-Sentences.aspx
"MySQL sentences?"

MySQL select with subquery having replace

So I have a data with format like ;1;;2; and then I need to use this number in a query so I thought I'd convert it to 1,2 and use that in a IN condition. In my table, the result should return 2 rows but instead it is returning only 1 row.
My query is like this. The subquery return 1,2 with no problem but only 1 row is retrieve.
select *
from wt_lists
where id IN ((select replace (replace(sendto, ';;',','),';','')
from wt_stats where statsid IN (1)))
But when I try it with this. It returns the correct result, which in my case is 2 rows.
select *
from wt_lists
where id IN (1,2)
What am I missing here?
Comma delimited strings need to be explicitly defined in the query in order to be used in the IN clause - there's countless examples on SO where people need to use dynamic SQL to incorporate user submitted comma delimited strings.
That said, I have a solution using the FIND_IN_SET function:
SELECT DISTINCT wl.*
FROM WT_LISTS wl
JOIN (SELECT REPLACE(REPLACE(ws.sendto, ';;',','),';','') AS ids
FROM WT_STATS ws
WHERE ws.statsid = 1) x ON FIND_IN_SET(wl.id, x.ids) > 0
You are replacing the string:
';1;;2;'
To:
'1,2'
So, you SQL query looks like:
select * from wt_lists where id IN ('1,2') from wt_stats where statsid IN (1)
To use IN clause you need select different values in different rows.
I found this store procedure that does exactly what you need.
http://kedar.nitty-witty.com/blog/mysql-stored-procedure-split-delimited-string-into-rows/
I have not tested, but it is the way.
Obs: Like David said in the comments above, parsing the data in your application is a better way to do this.