Column values are not overriden in result set - mysql

Is it a standard behavior for HeidiSQL not to override fields that should be overriden in the result set?
I run SQL query, where two tables have the same fields, one table is main and other is from join. I have to select all fields from main table (e.g. use "*"), and some fields from joined table must override values of main table. And it actually works when we fetch results with PDO (cause as a result we got an array value with the same key overrides previous one). but in HeidiSQL I got this:

Ok, got it by myself.
According to documentation:
MySQL permits duplicate column names. That is, there can be more than one select_expr with the same name. This is an extension to standard SQL. Because MySQL also permits GROUP BY and HAVING to refer to select_expr values, this can result in an ambiguity:
SELECT 12 AS a, a FROM t GROUP BY a;
In that statement, both columns have the name a. To ensure that the correct column is used for grouping, use different names for each select_expr.
I haven't attached importance to this before.

Related

How do I get the output of a SELECT statements in MariaDB/MySQL workbench to name columns in "table.column" format instead of just "column"?

I have to explore undocumented schemas to come up with query statements that will satisfy some business need.
When I SELECT * FROM foo JOIN bar ON foo.barid=bar.id; I get back a list of columns and I could guess where the columns from one table end and the next begin. But it would be awfully convenient if it just used the columns' full names i the output. i.e, every column would display as foo.columnname or bar.columnname.
yes, that's bulkier than optimal, and no I'd never use it in a production solution. but for exploratory pokings and prodings it would make things easier when I'm trying to figure out why a query isn't working right.
How do I turn that on by default?
CLARIFICATION: No. I'm not looking for "how to list all columns in a table/schema. I want to run queries joining tables together, and see the results, and see unambiguously and easily, what table a given field came from.
You can query the database information_schema to help you figure out what is what in your database. Running the following will get you close:
select table_name, column_name from information_schema.columns
https://dev.mysql.com/doc/refman/8.0/en/information-schema-columns-table.html
If you must use * you can qualify by table for example
select foo.*,'//',bar.*
will display all columns from foo first then a divider then all columns from bar and within foo the display left to right represents the ordinal position of the columns in foo. If the display columns are left justified then the column datatype is string of some description (varchar,char,text etc) if right justified then a number of some sort (int,decimal,float etc) . If a number is left justified then the underlying datatype is string. Date datatypes in mysql are in the form yyyy-mm-dd so if you see this then the underlying dataype is likely to be date. Similarly datetime
To understand the actual datatypes and find the indexes,constraints and foreign keys on a table then show create table tablename . If you want all table definitions use workbench export or mysqldump utility.
Also do read up on what information_schema https://dev.mysql.com/doc/refman/8.0/en/information-schema.html can do for you and consider reverse engineering your DB in workbench.

How do the fields in "SHOW COLUMNS" command map to specific tables?

Here is a View called viewwithcommonfield :
SELECT
`schematopologytest01`.`talpha`.`CommonField` AS `CommonField_tAlpha`,
`schematopologytest01`.`tbeta`.`CommonField` AS `CommonField_tBeta`
FROM
(`schematopologytest01`.`talpha`
JOIN `schematopologytest01`.`tbeta`)
When I execute
SHOW FULL fields FROM viewwithcommonfield IN SchemaTopologyTest01
I get this:
How do I map the fields back to specific tables? Can I write a view against the tables in information_schema?
Here are the table structures that are referenced in the view. The tables share a common field called CommonField:
No, there is no metadata available to map views of a column back to the original column in a base table. That would require multiple tables, because any given expression in the select-list may reference multiple columns from different tables.
Consider:
SELECT CONCAT(
`schematopologytest01`.`talpha`.`AlphaFieldA`,
`schematopologytest01`.`tbeta`.`BetaFieldE`) AS `ConcatenatedField`
FROM `schematopologytest01`.`talpha`
JOIN `schematopologytest01`.`tbeta` ON ...
Which table and column would ConcatenatedField list as its origin? It would have to be stored in two rows of another INFORMATION_SCHEMA table.
There are also select-list expressions possible in a view that don't reference any base table:
CREATE VIEW ViewNow AS SELECT NOW() AS `now`;
What about columns that are themselves scalar subqueries? Or references to stored functions? Or an aggregate function like COUNT() or SUM() where the value is not found in any base table?
Many views do not derive their data from base tables deterministically at all. Edit: What I mean is that it's not always possible to know which rows or columns are the source of data in a view, because they results are combined in some ways. It's probably more clear to say that reversing the query to get the original data is not always possible, depending on the query.
It's not possible to update those views. But if there were metadata about where the data "came from," there would have to be something in the metadata to indicate that. It would be impractical because it would be complex, and have little value.

What MySQL commands can use column order instead of names

I have and old MySQL database where I need to insert new columns into tables (to support new parts of the front-end). But some of the old parts use SQL commands that depend on column count and order instead of their names. e.g.:
INSERT INTO `data` VALUES (null /*auto-id*/, "name", "description", ...)
When I add new columns into this table, I get the error:
1136 - Column count doesn't match value count at row 1
Right now I know about the INSERT which needs to be changed to:
INSERT INTO `data` (`name`, `desc`, ...) VALUES ("name", "description", ...)
The question is: are there any other commands that can use similar syntax that rely on an order or count of the columns instead of their names? I need to update all the old SQL commands before updating the DB and using trial & error method would be really long.
SELECTs are not a problem, because the front-end uses associative mapping and correctly uses their names everywhere so new columns will be just ignored. Also I'm sure there are no commands that modifying the DB structure (e.g. ALTER TABLE).
You ruled out data structure modifying queries, so this leaves us with insert, update, delete, and select.
Insert you are already aware of.
Update requires each updated field to be specified, so mostly that's ok. However, subqueries may be used in the where clause, and mysql allows multi-table updates, so my points around select do apply.
Delete applies to a whole record, so there is nothing that an extra field would influence. However, subqueries may be used in the where clause, so my points around select do apply.
You tried to rule out select, but you should not. It is not only the final resultset that can be influenced by a new field:
A subquery may use select * that and an extra field may cause error in the outer query. For example the newly introduced field mayhave the same name as another field in the outer query leading to ambiguous field name error.
If select * is used in union, then column counts may not match after adding a new field.
Natural joins may also be affected by an introduction of a new field.

Making a calculated column SQL from 2 tables that result lives in a third

TABLE 1: EventBill(EstTotal)
Table 2: OperatingCost(EmpCost)
Table 3: Venue(VenueRate)
I have these three tables and I am trying to get them to work together so that the EstTotal is calculated from the other two variables :
ALTER TABLE EventBill
SELECT ShiftLength,
VenueRate
FROM DesiredStaffLevel,
Venue
ADD EstTotal AS (ShiftLength * VenueRate)
All the readings and texts I'm looking at say this works for a single column. Am I missing something to do this with multiple tables ? Maybe a join ? I'm still not quote fluent on those.
What you are attempting CANNOT be achieved using a "computed column".
A computed column is computed from an expression that can use other columns in the same table. The expression can be a noncomputed column name, constant, function, and any combination of these connected by one or more operators, but the expression cannot be a subquery.
Kun Cheng (Microsoft SQLCAT) bold emphasis added

How to get the fifth field of the second register of a table?

I have an automatically generated SQL database.
I don't know the name of the fields, and I don't know the value of the fields; I just know which number of register I need to get and with number of field of that register.
For example, if I need to obtain the fifth field of the second register of the table "Table1" of the database, which SQL query should I do?
Rows in a table in a database are formally unordered, though they are, of course, stored in some order. There's no way in SQL to refer to columns in a table by position; you must know the name of the column.
Since you know the table name, you can interrogate the system catalog to learn the columns in the table, and therefore the second column name in the table (assuming it isn't a single-column table).
However, if you don't know the schema of the tables, you can't do anything meaningful in the way of querying the data. You have to know what the columns mean to know what the query is going to do.
Clearly you can run some query on the table (once you know the column name you're after) and then collect two rows of data; the second row is the one you're after.
...
There's a half-cheat that you can use which will work if your database access language returns you rows with the values for each row in an array - as in Perl with DBI, or PHP, or ...
SELECT * FROM Table1;
This will collect all the data (including column 5, assuming there are that many columns), and your fetch operation may return the values represented by * into an array, and you can then look at the value in the fifth element of the array for the second row to see the data. In many SQL DBMS (I don't know about MySQL specifically), you can even use an obsolescent notation to order by the fifth column:
SELECT * FROM Table1 ORDER BY 5;
The 5 here refers to the fifth column in the result set which, given that this is selecting all columns from a single table, means the fifth column of the table.
However, running blind like that is a ridiculous proposition for the long term. You must understand the schema and its interpretation to be able to use a database sensibly.
You could try:
SELECT *
FROM information_schema.COLUMNS
WHERE information_schema.COLUMNS.TABLE_SCHEMA = '<DATABASENAME>'
AND information_schema.COLUMNS.TABLE_NAME = '<TABLENAME>'
ORDER BY information_schema.COLUMNS.ORDINAL_POSITION ASC
This would give you the table metadata, including column names and types.
can you not do it thru PHP (or your choice):
$i=1;
while($row = mysql_fetch_row($res))
{
if ($i == 2)
{
echo $row[4];
}
$i++;
}
Presumably you have access to the database?
Can't you do:
SHOW CREATE TABLE Table1;
The order of the columns returned should give you the names of the fields which you can then use in a query.