Knex.js divide value of a column by another column - sql

Hellow I'm searching how to create query like this with knex
SELECT product.price/100 AS priceInDollars
and getting error 'price/100 not found'
related question divide the value of a column by another column

Knex seems to wrap the columns in quotes, so such operations cannot be supported using Knex query builder, as the database would interpret that as literals.
knex.column('title', 'author', 'year').select().from('books')
Outputs:
select `title`, `author`, `year` from `books`
However, knex also provides a way to fire raw SQL statements, so you would be able to execute this query.
knex.raw('SELECT product.price/100 AS priceInDollars').then(function(resp) { ... });
Further reading: Knex Raw Queries

This can be done using knex.raw query partially for the columns.
You have two possible solutions:
Raw SQL:
You have possibility to use knex.raw to use full raw SQL query as you would execute it against database (as other answers already indicated). However, if you are using tools like knex, usually this is something you want to avoid (especially when you are using query builder to build more complicated queries and relationships - I assume that this is why you are using knex in the first place).
You can use knex.raw partially for specific column instead.
Lets consider following query:
SELECT id, product.price/100 AS priceInDollars, created_at WHERE id='someUUID';
You can execute this with knex in a following format:
knex
.select([
'id',
knex.raw('products.price::numeric/100 as priceInDollars'),
'created_at'
])
.from('products')
.where({ id: 'someUUID' });
My assumption in the answer is that postgresql is used (hence numeric), but if you want to extract float after the division, you will need to do a casting (in dependency of what kind of types database support)

Related

Get query used to create a table

We use snowflake at work to store data, and for one of the tables, I dont have the SQL query used to create the table. Is there a way to see the query used to make that table?
I tried using the following
get_ddl('table', 'db.table', true)
but this gives me an output like-
This doesnt give me any information about the sql query that was used. How do I get that in snowflake?
If get_ddl() is not enough you may use INFORMATION_SCHEMA.
To get more information you have 2 options:
Use the QUERY_HISTORY() table functions: https://docs.snowflake.com/en/sql-reference/functions/query_history.html
Use the QUERY_HISTORY() view: https://docs.snowflake.com/en/sql-reference/account-usage/query_history.html
If you use the funtions/view above and filter all the records by QUERY_TEXT, maybe you get more information about the exact SQL that was used to create your table.

HANA Bind JS Array as Parameter Value to WHERE IN(...) Clause

I'm using the #sap/hana-client npm module in a NodeJS project to connect to a HANA database and run queries.
I have a list of IDs that I want to include in a WHERE ID IN(...) SQL clause via parameterized queries, but cannot seem to figure out the syntax to do it.
Here's what I imagine it would look like (but this does not work, fails at the parameter binding stage)
const ids = [1,2,3,4];
const params = [ids];
const sql = "SELECT * FROM T WHERE ID IN (?)";
// this fails with => code: -20007, message: 'Can not bind parameter(0).', sqlState: 'HY000'
conn.query(sql, params, (err, result) => {
// process query results or errors
});
I know that in Postgres I can do this by using the UNNEST(...) 1 array function, but the same does not seem to work in HANA
That's a well-known difficulty with HANA.
ARRAY-like types are not natively supported in the client software.
Your (special) case of this, namely turning an array into a list of parameters for an IN clause requires some additional efforts.
See e.g. Errors with declared array/table variable values in SAP HanaDB SQL
The bottom line is that Postgres handles this special case specifically by replacing the single IN-clause parameter ? with a whole list of delimited values.
HANA does (sadly) not do something like that.
Instead, if you have to know in advance how many elements (at max) the IN-list will have so that you can prepare a statement with a parameter ? for each of those elements.
Alternatively, you can use SQLScript and the UNNEST construct that I've shown in the linked question, or you can create a temporary table, fill it with the IN-list elements and use it in the IN-clause (or join it).
Either way, it's rather cumbersome to manually do this, and I'd probably look for a framework that does that sort of stuff.

Accessing PostgreSQL Fields via Indexing

Is there a way in PostgreSQL to access fields without explicitly providing the column name? For example, instead of the statement:
select (col1,col2,col3,...col42) from foo_table;
there's a (possible) alternative of:
select (1:42) from foo_table;
There is no such syntax in Postgres' SQL.
You could always resort to having code that dynamically constructs the query for you before executing it, but that's about as good as it will get.

Oracle equivalent of PostgreSQL INSERT...RETURNING *;

I've converted a bunch of DML (INSERT/UPDATE/DELETE) queries from Oracle into PostgreSQL and now I need to check whether they produce the same set of rows, i.e. that delete removes the same rows, assuming the oracle and postgresql databases contain the same data initially, update updates the same rows etc. On PostgreSQL side, I can use the returning clause with DML statements, i.e.
INSERT INTO test(id, name) VALUES(42, 'foo') RETURNING *;
What's good about the statement above is that I can prepend 'returning *' to any DML statement without knowing the structure or even the name of the table it's executed against and just get all rows like it's a select statement.
However, it seems to be not that shiny on the Oracle side. According to the documentation, Oracle 8i (the one I'm working with) supports RETURNING clause, but it has to store the result into variables and there seem to be no obvious way to get all result columns instead of manually specifying the column name.
Hence, the question is if there is an oracle statement (or sequence of statements) to emulate PostgreSQL 'returning *' without hard-coding table or column names. In other words, is there a way to write an Oracle function like this:
fn('INSERT INTO test(id, name) VALUES(42, ''foo'')')
It should return the set of rows inserted (or modified in the generic case) by the SQL statement.
Update:
I actually found a very similar question (for the conversion from SQL server, not PostgreSQL, into Oracle). Still, I'd love to hear a more simple answer to that if possible.
I could imagine a solution involving EXECUTE IMMEDIATE, RETURNING, and REF CURSOR, but clearly it will be far from simple. I've previously found solutions such as this one, involving XML to problems where records of arbitrary type are to be used. They're quite freaky, to say the least. I guess you'll have to resort to running two separate queries... Specifically, with Oracle 8i, I'm afraid you won't even be able to profit from most of those features.
In short, I don't think there is any SQL construct as powerful as Postgres ... RETURNING clause in Oracle.
It's not currently possible, especially in an old version of Oracle such as 8i. See this answer to a similar question.

Dynamically building WHERE clauses in SQL statements

I have a question regarding SQL. I have the following SQL statement:
SELECT id, First, Last, E_Mail, Notes
FROM mytable
WHERE SOMETHING_SHOULD_BE_HERE IS NOT NULL;
I know that the SOMETHING_SHOULD_BE_HERE should be a column(attribute) in my table. Is their a way I can put a variable that can refer to the column I'm trying to access? In my case their are 30 columns. Can I have a string for SOMETHING_SHOULD_BE_HERE that can be assigned in my program to the column in which I want to search?
Thanks
No. Variables in SQL can refer to data, but not to object names (columns, functions or other database objects).
If you are building the SQL query, you'll need to use string operations to build your query.
The column can't be variable, but the value of the column can. The parser needs to know what to bind to.
If you elaborate on what you're trying to solve and which platform you're using it would allow for more complete answers.
You can have different SQLs queries in your code and use each one according to the case.
Another way is generate dynamically the query according the fields you want.
Without dynamic SQL, this is probably your best bet:
SELECT
id, first, last, email, notes
FROM
My_Table
WHERE
CASE #column_name_variable
WHEN 'column_1' THEN column_1
WHEN 'column_2' THEN column_2
...
ELSE 'not null'
END IS NOT NULL
There might be some issues with data type conversions, so you might need to explicitly cast all of the columns to one data type (VARCHAR is probably the best bet). Also, there's a good chance that performance will be horrendous on this query. I'd test it thoroughly before even thinking about implementing something like this.
I mentioned this in my comment, but for completeness I'll put it here too... you can probably also accomplish this with dynamic SQL, but how you do that will depend on your database server (MS SQL Server, Oracle, mySQL, etc.) and there are usually some caveats to using dynamic SQL.
In JDBC program, yes,the select statement can be composed like string operation.
for(String colName: colList)
{
String sql="Select id, First, Last, E_Mail, Notes From mytable where "+colName+" IS NOT NULL";
//execute the sql statement
}
It depends on how you are going to find out the value of SOMETHING_SHOULD_BE_HERE.
If you are in an Oracle PLS/SQL environment you could build up the WHERE clause using dynamic SQL and then use EXECUTE IMMEDIATE to execute it.
If you have a small set number of possibilities you could use CASE to workaround your problem possibly.
Your question is unclear.
However I am quite sure that what you have in mind is the so-called dynamic SQL (and related). "Dynamic SQL" allows you to dynamically build and submit queries at runtime. However such functionalities may not exist for your RDBMS.
There are several ways to do this.
When your query would return one and only one row
then you have to consider the EXECUTE IMMEDIATE statements (along with sp_executesql in tSQL : http://msdn.microsoft.com/en-us/library/ms188001.aspx ; or the USING clause in PL/SQL : http://docs.oracle.com/cd/B14117_01/appdev.101/b10807/13_elems017.htm to specify a list of input/output bind arguments) and/or PREPARED statements (http://rpbouman.blogspot.fr/2005/11/mysql-5-prepared-statement-syntax-and.html).
When your query can return more than one row
then you have to consider techniques such as the EXECUTE IMMEDIATE statement with the BULK COLLECT INTO clause or the OPEN-FOR, FETCH, and CLOSE statements (explicit cursors in PL/SQL :
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/dynamic.htm)
Please note that except in some particular cases, most conventional techniques like IF-THEN-ELSE and CASE statements should be preferred (along with a good algorithm). Furthermore they work with almost all RDBMS.