How to assign aliases to an array of column names with Joomla's quoteName()? - mysql

I want to use the AS statement for Aliases in a query.
I use this piece of code:
$query->select($db->quoteName(array('NameInQ as nin', 'Name')));
Anyway I get this error:
'Unknown column 'NameInQ as nin' in 'field list'
NameInQ does exist as a column name in the table. nin should be the alias.
What am I doing wrong?

When you tell Joomla:
$query->select($db->quoteName(array('NameInQ as nin', 'Name')));
echo $query->dump(); will tell you:
SELECT `NameInQ as nin`,`Name`
See how it doesn't know how to differentiate an aliased column name from a string with spaces in it?
The Docs: https://api.joomla.org/cms-3/classes/JDatabaseQuery.html#method_quoteName
If you want to assign aliases to column names in Joomla from within the qn() / quoteName() method, you will need to nominate corresponding aliases for all columns.
$query->select($db->quoteName(array('NameInQ', 'Name'), array('nin', 'Name')));
Renders as:
SELECT `NameInQ` AS `nin`,`Name` AS `Name`
// ^-------^----^---^-^----^----^----^-- everything aliased, everything backtick wrapped
Or, of course you could individualize the quoteName() calls, you can avoid aliasing every column.
$query->select(array($db->quoteName('NameInQ', 'nin'), $db->quoteName('Name')));
Renders as:
SELECT `NameInQ` AS `nin`,`Name`
Finally, the truth is: You don't even need to quote any of your sample column names because the query will be stable/secure without the extra method call(s). *I recommend leaving them out to minimize query bloat and developer eye-strain.
$query->select(array('NameInQ AS nin', 'Name'));
or even in raw form:
$query->select('NameInQ AS nin, Name');
For the record, Name (MYSQL is case-insensitive) IS a KEYWORD, but it is not a RESERVED KEYWORD.
See the MySQL Doc: https://dev.mysql.com/doc/refman/5.5/en/keywords.html#keywords-5-5-detailed-N (there is no "(R)" beside Name

Related

Join returns NULL when data that matches is in the table

I'm trying to get results when both tables have the same machine number and there are entries that have the same number in both tables.
Here is what I've tried:
SELECT fehler.*,
'maschine.Maschinen-Typ',
maschine.Auftragsnummer,
maschine.Kunde,
maschine.Liefertermin_Soll
FROM fehler
JOIN maschine
ON ltrim(rtrim('maschine.Maschinen-Nr')) = ltrim(rtrim(fehler.Maschinen_Nr))
The field I'm joining on is a varchar in both cases. I tried without trims but still returns empty
I'm using MariaDB (if that's important).
ON ltrim(rtrim('maschine.Maschinen-Nr')) = ltrim(rtrim(fehler.Maschinen_Nr)) seems wrong...
Is fehler.Maschinen_Nr really the string 'maschine.Maschinen-Nr'?
SELECT fehler.*, `maschine.Maschinen-Typ`, maschine.Auftragsnummer, maschine.Kunde, maschine.Liefertermin_Soll
FROM fehler
JOIN maschine
ON ltrim(rtrim(`maschine.Maschinen-Nr`)) = ltrim(rtrim(`fehler.Maschinen_Nr`))
Last line compared a string to a number. This should be doing it.
Also, use the backtick to reference the column names.
The single quotes are string delimiters. You are comparing fehler.Maschinen_Nr with the string 'maschine.Maschinen-Nr'. In standard SQL you would use double quotes for names (and I think MariaDB allows this, too, certain settings provided). In MariaDB the commonly used name qualifier is the backtick:
SELECT fehler.*,
`maschine.Maschinen-Typ`,
maschine.Auftragsnummer,
maschine.Kunde,
maschine.Liefertermin_Soll
FROM fehler
JOIN maschine
ON trim(`maschine.Maschinen-Nr`) = trim(fehler.Maschinen_Nr)
(It would be better of course not to use names with a minus sign or other characters that force you to use name delimiters in the first place.)
As you see, you can use TRIM instead of LTRIM and RTRIM. It would be better, though, not to allow space at the beginning or end when inserting data. Then you wouldn't have to remove them in every query.
Moreover, it seems Maschinen_Nr should be primary key for the table maschine and naturally a foreign key then in table fehler. That would make sure fehler doesn't contain any Maschinen_Nr that not exists exactly so in maschine.
To avoid this problems in future, the convention for DB's is snake case(lowercase_lowercase).
Besides that, posting your DB schema would be really helpfull since i dont guess your data structures.
(For friendly development, is usefull that variables, tables and columns should be written in english)
So with this, what is the error that you get, because if table "maschine" has a column named "Maschinen-Nr" and table "fehler" has a column named "Maschinen_Nr" and the fields match each other, it should be correct
be careful with Maschinen-Nr and Maschinen_Nr. they have - and _ on purpose?
a very blind solution because you dont really tell what is your problem or even your schema is:
SELECT table1Alias.*, table2Alias.column_name, table2Alias.column_name
FROM table1 [table1Alias]
JOIN table2 [table2Alias]
ON ltrim(rtrim(table1Alias.matching_column)) = ltrim(rtrim(table2Alias.matching_column))
where matching_columns are respectively PK and FK or if the data matches both columns [] are optional and if not given, will be consider table_name

Why do all my SQL queries have to be wrapped using the ` symbol?

I have been working on a database for my coursework and have used phpMyAdmin to build it. Now I am working on the queries using the query tool.
When I pick the tables and data I want to query and press "update query" it will generate the query which looks something like this:
SELECT `Customer`.`CustomerName`, `OrderDetails`.`Product`, `OrderDetails`.`QuantityOrdered`
FROM `Customer`
LEFT JOIN `Order` ON `Order`.`Customer` = `Customer`.`CustomerID`
LEFT JOIN `OrderDetails` ON `OrderDetails`.`Order` = `Order`.`OrderID`
This works fine and gives me the results I was expecting. However when I try and write my own query and put something like "SELECT Customer.CustomerName," WITHOUT the ' symbol it won't work and just throws up an error message.
Must I always wrap them using the ' symbol for the query to work?
Forward quotes are used to escape object names in MySQL. You don't have to use them unless you use names that wouldn't be valid identifiers - in this case, the table name order is a reserved word, and must be escaped. All the other tables and columns you're using seem to be OK.
Except for the visual nightmare and ability to create horrendous table names, backticks are entirely unnecessary. You will, however, be required to wrap any variables in single quotes.
As you can see from my example below, using backticks is not a requirement with PHPMYADMIN;
The reason it is not working when you remove the backticks is because you have a column called 'order'. Order is a keyword in SQL and therefore cannot be used as a column name without being wrapped in either quotes or backticks.

SQL REPLACE INTO not working

So I have a form that can get data from a database by its ID (auto-incremented column(Primary Key)) and display all fields in the <input> tags via value properties. And when I submit the form I want it to either INSERT a new row if the ID from the ID column doesn't already exist and if it does I want to UPDATE the rest of the data in the row with the same ID.
I have been trying to research this, but no one seems to be doing the same thing I am trying to do, its always slightly different. I found a REPLACE INTO and created it like below:
$sqlString = 'REPLACE INTO coursework
SET cwID=`'. $cwID .'`,
cwTitle=`'. $cwTitle .'`,
cwContent=`'. $cwContent .'`,
cwProgress=`'. $cwProgress .'`,
cwDue=`'. $cwDue .'`;
All the $cw[] variables being content received from $_POST method.
I keep getting a Error code: 1054-Unknown column '6' in 'field list' -
the "Unknown column '6'" is mysql trying to call $cwID (value of $_POST['cwID']) instead of the cwID column(which is the Primary Key for my table). I feel like there is something simple and stupid I am missing but I have never used this REPLACE INTO method before.
I saw a post about INSERT IGNORE INTO and INSERT ... ON DUPLICATE KEY UPDATE but both of those sound more destructive than what I am looking for.
I just want to make sure that the table is updated if the cwID exists and the auto-increment is kept in tact, or a new row is added if there is no ID. Should I just run a SELECT query to see if it exists and INSERT/ UPDATE appropriately?
Remove Replace the back-ticks (`) surrounding the strings with single quotes (').
MySql is trying to find a column named by the strings you are using as values.
See http://dev.mysql.com/doc/refman/5.5/en/identifiers.html
Replace the backticks with single quotes:
$sqlString =
"REPLACE INTO coursework SET cwID='$cwID', cwTitle='$cwTitle', cwContent='$cwContent', cwProgress='$cwProgress', cwDue='$cwDue'";
Also, note that " will interpolate your variables.

MySQL: REGEXP to remove part of a record

I have a table "locales" with a column named "name". The records in name always begin with a number of characters folowed by an underscore (ie "foo_", "bar_"...). The record can have more then one underscore and the pattern before the underscore may be repeated (ie "foo_bar_", "foo_foo_").
How, with a simple query, can I get rid of everything before the first underscore including the first underscore itself?
I know how to do this in PHP, but I cannot understand how to do it in MySQL.
SELECT LOCATE('_', 'foo_bar_') ... will give you the location of the first underscore and SUBSTR('foo_bar_', LOCATE('_', 'foo_bar_')) will give you the substring starting from the first underscore. If you want to get rid of that one, too, increment the locate-value by one.
If you now want to replace the values in the tables itself, you can do this with an update-statement like UPDATE table SET column = SUBSTR(column, LOCATE('_', column)).
select substring('foo_bar_text' from locate('_','foo_bar_text'))
MySQL REGEXs can only match data, they can't do replacements. You'd need to do the replacing client-side in your PHP script, or use standard string operations in MySQL to do the changes.
UPDATE sometable SET somefield=RIGHT(LENGTH(somefield) - LOCATE('_', somefield));
Probably got some off-by-one errors in there, but that's the basic way of going about it.

Can a table field contain a hyphen?

I have a table in a MySQL table with a fieldname 'product', and want to rename it to 'ds-product'.
The CMS type system I am using uses the id of formfields as the name of the table field to insert into.
For most this works fine, but for a particular field it prepends 'ds-' to whatever ID I give it, so I must make the table field name match.
However, when trying to do a query I get the error that
Unknown column 'sales.ds' in 'field list'
Is there any way I can have a field called ds-product?
Yes, you can use punctuation, white space, international characters, and SQL reserved words if you use delimited identifiers:
SELECT * FROM `my-table`;
In MySQL, use the back-ticks. In standard SQL, use double-quotes.
Or if you use MySQL you can set the ANSI_QUOTES SQL mode:
SET SQL_MODE = ANSI_QUOTES;
SELECT * FROM "my-table";
Try putting brackets on the last part of your call on the table. in your case:
SELECT * FROM [TABLE-NAME];
just make sure to put the brackets on the table name only. not on the whole database it is located
SELECT * FROM some_database.anotherdatabase.[your-table];
P.S. works on columns, too.
I'm using Microsoft SQL Server Management.