How to query a column named "OR" in BigQuery? - mysql

We unfortunately have a table with a column that has been written with the field name of "OR".
If we try to query this table - "SELECT OR FROM etc." we get an error because OR is a reserved word.
How do we query that column using BigQuery's legacy SQL queries? (We need that column and not others.)
We thought we could use "SELECT *" and BigQuery's "exclude" feature but isn't part of legacy SQL so we are unable to use it. Other ideas?

I ran into this issue when querying the Hacker News dataset. It appears the authors added a "by" column because they were replicating the API response keys. However, it's difficult to query and not best practice in database design.
I tried the brackets:
SELECT
[by] as author_name
FROM
`bigquery-public-data.hacker_news.full`
LIMIT
1000
but received the following error:
Syntax error: Unexpected keyword BY at [2:4]
Here is a query that works on the Hacker News dataset in BigQuery with Standard SQL Dialect:
SELECT
b.by as author_name
FROM
`bigquery-public-data.hacker_news.full` as b
LIMIT
1000

I know that you're looking for an answer using legacy SQL (and you found one using the bracket syntax), but for future readers, or, and, etc. are valid column names for query results in standard SQL. The following query will not return an error, for instance:
WITH T AS (
SELECT
1 AS `or`,
2 AS `and`
)
SELECT * FROM T;

We found another SO answer for this - except you need to do something additional to what they describe. You cannot just add brackets to the name - you also need to give it a new column name.
The answer is to query like this:
SELECT [OR] AS new_column_name FROM ...

Related

What does it mean to include a string in an SQL SELECT query

I apologize if the question asked is simple and far too stretched out
I've been studying the fundamentals of SQL Injection attacks and at a point, I've read that a potential method of verifying the data type of a particular field in a UNION SQL Injection attack is by making certain changes to the request that we make to the target server.
The software being used is BurpSuite, and the target is a practice lab on the website https://portswigger.net. It is told that the category field is vulnerable, and that the query for the category returns two fields, so the following "code" is appended to the category part of the HTTPS GET message that we send to the server in an attempt to know the data type of the first field
...?category=Gift'+UNION+SELECT+'abc',NULL+FROM+table_that_contains_target_information--
According to the manuals for the lab, what we're doing with the 'abc',NULL part is that we're verifying that the first field in the "table_that_contains_target_information", is of the type string/varchar. This seems to work and aids one in determining the data type of that particular field, as I checked in the lab, since if the first field's datatype is not a string/varchar, I would get an internal server error.
However, later on, when performing a query on a general database to check what the 'abc',NULL part does in a general SELECT query, the results that come are somewhat different.
The general database question is one that is available to use for learning SQL at https://www.w3schools.com/mysql. It has a table named Customers with several fields. I know for a fact that the first field is an integer (via verification with information_schema.columns), and the rest are varchars. For context, in the Customers table, CustomerID is an integer field, and CustomerName is a varchar field. I ran the following query on the server
|-------This part is the original query-------||This is our inserted code to find out information about the database|
SELECT CustomerID, CustomerName FROM Customers UNION SELECT 'abc',NULL FROM Customers
Disclaimer: My intentions were not to cause any harm to the database, only to learn some SQL
According to what I've learnt from the Lab manuals, I should be getting an error of sorts right?, since I'm checking the datatype of a field in a method that and unethical hacker could potentially take. However, all I get are the results of the original query and an extra record with values 'abc' and the second field is NULL.
I've tried to read up on documentation regarding the SELECT query in SQL, but as far as I was able to find, most of them tell about the general SELECT * FROM table_name or SELECT column_name, other_column_name FROM table_name. I wasn't able to find anything about the SELECT 'abc' FROM table_name.
Could anyone please explain what is going on here? Does the SELECT 'abc' FROM table_name just give me an extra record with 'abc'? If so, then why is this same query used to verify the datatypes in the lab at https://portswigger.net, and it seems to work its purpose there.
Thank you for answering in advance!

Spring batch with column alias as sort key - malformed "where" statement

I'm using Spring-batch version 3.0.6.RELEASE to query a MySQL DB for some data and then process it.
Details about usage:
query provider is MySqlPagingQueryProvider
when setting up the query provider I'm specifying an alias of one of the columns in the query as the sort key (please check the query below for more details)
Query:
SELECT
target.tx_timestamp AS event_datetime,
....
FROM
some_table AS target
....
WHERE
target.tx_timestamp > :startTime AND target.tx_timestamp <= :endTime;
The code:
Map<String, Order> sortKeys = new HashMap<>();
sortKeys.put("event_datetime", Order.ASCENDING);
MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
queryProvider.setSortKeys(sortKeys);
The generated query (please note the part with event_datetime):
WHERE
(target.tx_timestamp > ? AND target.tx_timestamp <= ?) AND
((event_datetime > ?))
The error:
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar .... Unknown column 'event_datetime' in 'where clause'.
Is it possible to use alias as the sort key ?
Also worth noting are this thread with same issue and this Spring batch Jira ticket which is marked as resolved for version 3.0.4.
I have also tried using 3.0.4.RELEASE, 3.0.5.RELEASE and 3.0.7.RELEASE versions with the same result.
Edit:
After a few more tries I can add that the issue arises only when there is enough records for more than one page. The query for the first page passes without issues but the queries for subsequent pages fail.
Edit2:
As pointed out by Sabir, the issue is in fact with column alias in the where clause. Spring batch is working correctly in this case.
For people running into the same issue:
You can work around this by nesting the whole query in another select like this:
SELECT * FROM (
SELECT
target.tx_timestamp AS event_datetime,
....
FROM
some_table AS target
....
WHERE
target.tx_timestamp > :startTime AND target.tx_timestamp <= :endTime) our_inner_select;
Unknown to me at the moment when I posted the question, the alias cannot be used in WHERE clause and since spring batch was given the alias event_datetime as sort key, the queries for chunks after the 1st one were generated with additional conditions based on sort keys.
With the query above, the inner select is evaluated before the spring batch added WHERE condition and then the usage of column alias for sort key is possible.
When you specify a column alias of SELECT as sort key, page - 1 ( i.e. except page -0 ) onward queries generated by Spring Batch use that alias in WHERE clause as shown in your question and as per this SO question , using a column alias in WHERE clause is not allowed if evaluation of SELECT clause is not forced before WHERE clause.
So to answer your question - No, you can't use an alias as sort key unless you force alias evaluation as suggested in other SQL question.
We ran into this issue, Spring must get your sort key from the returned result set in order to page correctly. As previous answer explains sort key gets used in a WHERE clause which will not work with column aliases.
Our solution was to SELECT target.tx_timestamp as "target.tx_timestamp" so that the sort key can be retrieved from the result set using the same name. Doing SELECT target.tx_timestamp puts the column tx_timestamp into your result set which causes issues since your sort key needs to be "target.tx_timestamp". We preferred this approach to the nested query.

Mysql: query not giving accurate result with IN clause and inner query

I'm trying to get zip codes from zip_id's which are internally stored in companies service table below screens will give you clear idea
I have wrote this query
companies service table
Please suggest me your valuable views . Thanks in advance.
As already mentioned your database scheme is not very well designed, it violates even 1st normal form. You'd need another table where you'd store serv_area_id and zip_code (with possibly multiple rows for a signle serv_area_id) and search within this table and eventually join your original table.
Nevertheless, in order to get the result you describe you cannot use the IN operator as it operates on a value and multiple values in a form of table (either explicit via nested SELECT or enumeration literal (val1, ..., valN)). I would try some string matching as illustrated below. However, consider it rather an ugly hack than correct solution(!)
SELECT zip FROM cities_extended WHERE (
SELECT GROUP_CONCAT(',', serv_are_zipcodes)
FROM company_service_areas WHERE ...
) LIKE concat('%(', id, ')%')

Confused with selecting data from db in mysql [duplicate]

This question already has an answer here:
Syntax error due to using a reserved word as a table or column name in MySQL
(1 answer)
Closed 8 years ago.
I have 2 tables: PLAYER and GROUP.
When I call:
SELECT * FROM PLAYER
Everything is OK but when I call:
SELECT * FROM GROUP
There is error:
#1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'GROUP' at line 1`
I don't understand why there is such error.
GROUP is a reserved word and it must be escaped with back ticks.
SELECT * FROM `GROUP`
It's also better practice to avoid using table names or columns that are reserved words. Also, specify a column list and not use *.
GROUP is a reserved keyword . You have to escape it, like so
SELECT * FROM `GROUP`
Things to note:
It is highly recommended not to name the table group, it is better to use the plural Groups.
Also, try to avoid *.
Just as you use the reserved keywords SELECT and FROM for constructing your query, there are other reserved keywords like the ones in the following list that you may want to avoid when naming all your tables, views, constraints and columns.
List of (some) reserved keywords: WHERE, ORDER, GROUP, UPDATE, DELETE, CHECK, CHANGE, LIKE etc...
Therefore, in your case the DB Engine is complaining because a query
needs 1 mandatory clause SELECT and optional clauses FROM, WHERE,
ORDER BY, GROUP BY, HAVING, LIMIT etc... read more here
We might be tempted to use these keywords; especially if they've been modeled in our problem domain (or in the diagrams). For example, a client placing an order yields 2 Entities CLIENT and ORDER etc. or a mechanic performing a check giving MECHANIC and CHECK. or even a FACEBOOK_USER expressing a LIKE. or in your case there might be a GROUP of PEOPLE for example.
As a general rule, you can transform your entities like so to avoid problems:-
a) The Entity is always modeled (on paper) as singular as it represents a concept/asset/person in the real world or problem domain. eg. ORDER, LIKE, CHECK, STUDENT, CAR
b) the corresponding DB Table it is transformed into is always named using plural. The logic is that the table will contain lots of instances of that Entity. Therefore ORDERS, LIKES, CHECKS, STUDENTS, CARS
In the end, you decide because you really can use GROUP if you really
want or need to make your table name like a reserved word. Just
remember to give them a special treatment by putting them in quotes
using the backtick (“`”) when querying. At the moment of creation the DB engine
won't complain, trusting that you know what you're doing.

Selecting a column that is also a keyword in MySQL

For some reason, the developers at a new company I'm working for decided to name their columns "ignore" and "exists". Now when I run MySQL queries with those words in the where clause, I get a syntax error; however, I can't seem to figure out how to reference those columns without running into an error. I tried setting them as strings, but that doesn't make any sense.
Help?
Also, is there a term for this kind of mismatch?
put the names in backticks:
`ignore`, `exists`
If you're working across multiple tables or databases you need to escape the database name, table name, and field name separately (if each matches a keyword):
SELECT * FROM `db1`.`table1`
LEFT JOIN `db2`.`table2` on `db1`.`table1`.`field1`=`db2`.`table2`.`field2`
Only the portions that actually match a keyword have to be escaped, so things like:
select * from `db1`.table
are ok too.
The official term is "idiocy" :-) You can put backticks around the names such as
`ignore`
but I would give serious consideration to changing the names if possible. Backticks are not standard SQL, and I prefer my column names to be a little more expressive. For example, ignoreThisUser or orderExists (the general rule I try to follow is to have a noun and a verb in there somewhere).
Interestingly, some DBMS' can figure out not to treat it as a reserved word based on context. For example, DB2/z allows the rather hideous:
> CREATE TABLE SELECT ( SELECT VARCHAR(10) );
> INSERT INTO SELECT VALUES ('HELLO');
> SELECT SELECT FROM SELECT;
SELECT
---------+---------+---------+--------
HELLO
DSNE610I NUMBER OF ROWS DISPLAYED IS 1