Creating a column name alias from a select statement - mysql

I am trying to create a column alias by looking up a value in another table. This is the MySQL I am trying but keep getting syntax errors - any help would be appreciated.
SELECT
product_code,
bField1 as (select [label_value] from [labels] where [field_value]='bField1'),
bField2 as (select [label_value] from [labels] where [field_value]='bField2'),
....
FROM products

try as folow:
SELECT
product_code,
(select [label_value] from [labels] where [field_value]='bField1') as bField1,
(select [label_value] from [labels] where [field_value]='bField2') as bField2,
....
FROM products

What you wish is not possible wtih only MySQL.
See below for similar questions:
Dynamic column alias based on column value
Specifying column alias with user-defined variable
I'm not sure why exactly you want to do this but it's always possible to incorporate the alias selection logic with the server side language that is dynamically creating the query. But of course, this would then be a two step process but you are not actually losing out as in your example you are using sub queries anyways.

Related

cakePHP subquery in FROM

I need help to understand if something like this is posible on cakePHP...
I have a MYSQL query that retrive the information on the way it's needed, and it looks something like this:
SELECT *
FROM
(SELECT id ...)
JOIN
(SELECT id ...)
GROUP BY ...
So what I need to know if there is anyway on cakePHP to resolve the first FROM subquery.
I could break the query in two but I want to know if it can be solved in cakePHP using one Model->find command.
Thanks.
It cannot because your first "table" (in the FROM clause) is based on the model of the find. That being said
You can take your FROM subquery and make a SQL view out of it. Then create a Cakephp based on that view.
If your first subquery does not have a GROUP BY, the entire query can probably can be re-written without the subquery.

What does the 'a' do in this MySQL query? It doesn't run without it

The 'a' at the end of this:
SELECT
email_home
FROM
(SELECT email_home FROM sales
UNION ALL
SELECT email_work FROM sales) a
What's it do/for? The code doesn't run without it. Thanks.
It's just an alias. Mysql requires all sub queries like that require a specific name. People just use 'a' as convention if they aren't really going to use it.
You could specify the column name thusly:
a.email_home
It sets the name of an alias to the table to "a".
Presumably, you could reference objects in that table by using "a.[columnName]" for future stuff.
As you are using subquery in From clause MySql requires alias name. In your case "a" is just a alias given to your subquery in From clause. for detail information read this

Group by statement column name resolution

I have a query like this (more columns in reality)
select
custom_amend_column_function(colname) as colname
from source_table
group by colname
I've used this construct a lot.It appears to have always used the output from the function rather than the input to group data by.
Now for the first time today I have run this statement directly into a new table like this:
create table new_table as
select
custom_amend_column_function(colname) as colname
from source_table
group by colname
Curiously by adding the first line, I am getting an error message that my query is using an ambiguous column name in the group statement.
As group by can use new column names (ie. the below works) I always expected that group by will first use the columns defined in the select statement and then look at the underlying table(s) if it cannot find the names.
select
custom_amend_column_function(colname) as new_colname
from source_table
group by new_colname
Am I right? Is the error message right? I cannot find any place this is documented either for the SQL standard or for MySQL.
I know I could avoid this by just creating a new column name, but I want to figure this out as I may need to review existing queries if it is indeed ambiguous.
To trace the problem do an
EXPLAIN EXTENDED SELECT ...
On your query. Beside the normal output this will give you a warning containing the query as it is seen by the optimizer. All implicit renaming is done here, so you can see why the column name is ambiguous.
I think you can solve this by saying
... GROUP BY 1
instead of providing the column name in the group by.

MySQL Select from 1 Table, Insert into Another using Where across different databases

I have a select shown below that brings back the correct count per "sender_userid".
I want to insert this into a table in another database where there is a matching column "userid".
I'm not sure how to get the WHERE clause to work when used across database.
I've tried database.table.column but this appears wrong.
Is this possible? thx
WHERE statements must come before ORDER BY and GROUP BY statements. Also you should use the ON operator. Try this:
INSERT INTO dating_users.statistics (messages_sent)
SELECT COUNT(pid) FROM dating_messages.messages M
JOIN dating_users.statistics S
ON (S.userid = M.sender_userid)
GROUP BY sender_userid ORDER BY sender_userid ASC;
Edit: sorry I didn't realize that you were missing your actual JOIN statement. Just because you are INSERTing into a table doesn't make any data accessible from that table. You still need to JOIN to it.

Subquery for fetching table name

I have a query like this :
SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo WHERE group='BEST'
Basically, the table name for the main query is fetched through the subquery.
I get an error that #1054 - Unknown column 'group' in 'where clause'
When I investigate (removing the where clause), I find that the query only returns the subquery result at all times.
Subquery table adm_linkedfields has structure id | name | linktable
Currently am using MySQL with PDO but the query should be compatible with major DBs (viz. Oracle, MSSQL, PgSQL and MySQL)
Update:
The subquery should return the name of the table for the main query. In this case it will return tbl_company
The table tbl_company for the main query has this structure :
id | name | group
Thanks in advance.
Dynamic SQL doesn't work like that, what you created is an inline-view, read up on that. What's more, you can't create a dynamic sql query that will work on every db. If you have a limited number of linktables you could try using left-joins or unions to select from all tables but if you don't have a good reason you don't want that.
Just select the tablename in one query and then make another one to access the right table (by creating the query string in php).
Here is an issue:
SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo
WHERE group='BEST';
You are selecting from DT which contains only one column "linktable", then you cant put any other column in where clause of outer block. Think in terms of blocks the outer select is refering a DT which contains only one column.
Your problem is similar when you try to do:
create table t1(x1 int);
select * from t1 where z1 = 7; //error
Your query is:
SELECT *
FROM (SELECT linktable
FROM adm_linkedfields
WHERE name = 'company'
) cbo
WHERE group='BEST'
First, if you are interested in cross-database compatibility, do not name columns or tables after SQL reserved words. group is a really, really bad name for a column.
Second, the from clause is returning a table containing a list of names (of tables, but that is irrelevant). There is no column called group, so that is the problem you are having.
What can you do to fix this? A naive solution would be to run the subquery, run it, and use the resulting table name in a dynamic statement to execute the query you want.
The fundamental problem is your data structure. Having multiple tables with the same structure is generally a sign of a bad design. You basically have two choices.
One. If you have control over the database structure, put all the data in a single table, linktable for instance. This would have the information for all companies, and a column for group (or whatever you rename it). This solution is compatible across all databases. If you have lots and lots of data in the tables (think tens of millions of rows), then you might think about partitioning the data for performance reasons.
Two. If you don't have control over the data, create a view that concatenates all the tables together. Something like:
create view vw_linktable as
select 'table1' as which, t.* from table1 t union all
select 'table2', t.* from table2 t
This is also compatible across all databases.