Postgres SQL - IN(..) AS... in Select - sql

Can someone help me undertsand the IN(...) AS... in the select. This is the first time I'm seeing something like this. Also, how does the database determine the row value or newID? This is on Postgres datababse.
SELECT tbl_a.*, (
tbl_z.z_id IN (
SELECT x_id
FROM table_x
WHERE name = '...'
)
) AS newID
FROM (...)

newId will be of type boolean.
true, if
tbl_z.z_id IN (
SELECT x_id
FROM table_x
WHERE name = '...'
)
and false if not.
AS column_name is alias.
update
answering your comment.
https://www.postgresql.org/docs/current/static/sql-select.html#SQL-WHERE
where condition is any expression that evaluates to a result of type
boolean.
So if you have IN (...) in WHERE it returns same boolean as in column list. True or false. No difference - where or as column, returns either true or false

The second column is the answer to the question "is tbl_z.z_id in the list of x_id from table_x where name = '...'?"
As that's a yes/no question (which 'IN' always means), it's a boolean (either true or false).
The "AS" clause tells it what to name that column (it's not directly from a table, so it doesn't know what to call it). It's not strictly required, but it makes addressing that column in your output much easier, you can also use it if you want the column name to be different then the name in the table you're coming from (if you're joining two tables, and they happen to have each have a column with the same names is a use case for this).

Related

SQL Boolean Column Default Value

Someone gave me this code:
select * from table where is_active
Is the is_active column, despite not having been set to anything, set to TRUE by default? Does the above query mean this:
select * from table where is_active = TRUE
It appears so, but couldn't find anything in the PostgreSQL documentation, so just wanted to confirm.
Yes. You are right here. When the system looks at this query select * from table_name where col1>col2, it tries to find effective boolean expression after where clause, and ends up evaluating the expression to either true or false. But since the column value is already boolean so there is no need for that. select * from table where is_active is infact better. This is true for all SQL languages

How to subscript a Postgres column

I have a Postgres query:
SELECT main
FROM (
SELECT
CASE WHEN 1=1 THEN (col_a, col_b)
END as main
FROM "table1"
LIMIT 100) inner_t
Which returns a single column of values in the format (value_a, value_b) in each row. I want the outer query to format those values so that all the value_a's and value_b's are in their own separate columns.
Is there an easy way to do this?
Output screenshot:
http://example.com/path-to-ghosts.jpg
You can abuse row_to_json to do this, but it is probably best to avoid anonymous record types in the first place.
SELECT row_to_json(main)->>'f1', row_to_json(main)->>'f2'
FROM (
SELECT
CASE WHEN 1=1 THEN (col_a, col_b)
END as main
FROM "table1"
LIMIT 100) inner_t
To give a concrete example (after running pgbench -i):
SELECT row_to_json(main)->>'f1', row_to_json(main)->>'f2'
FROM (
SELECT
CASE WHEN 1=1 THEN (aid, bid)
END as main
FROM pgbench_accounts
LIMIT 100) inner_t;
But it only works in v10 and up.
This is more of an explanation than an actual answer. But it won't fit into a comment.
The thing is, SQL is a strictly typed language. Postgres demands to know the number and data types in the SELECT list at call time. The *-expansion in SELECT * FROM .. is based on registered types. Postgres knows the columns of a table because the structure is saved in the catalog tables.
The expression nested in your construct (col_a, col_b) is short for ROW(col_a, col_b) and a ROW constructor creates an anonymous record. The manual:
By default, the value created by a ROW expression is of an anonymous
record type. If necessary, it can be cast to a named composite type —
either the row type of a table, or a composite type created with
CREATE TYPE AS.
Postgres does not know how to expand an anonymous record. *-expansion does not work.
You could cast like the manual says. But that's only an option if the type is stable, i.e. you always put in the same number of columns with the same data types. And that still would not preserve column names.
So, for the best solution, first define:
Obviously you want to preserve column vales.
Do you also want to preserve column names?
Do you also want to preserve column types?
And:
Is the number of columns in the expression always the same?
Are data types always the same?
The CASE condition is stable or based on other columns?
If the true aim of the game is to fit multiple values in a single CASE expression, you only care about values, create a text array instead:
SELECT main[1] AS col_a, main[2] AS col_b
FROM (
SELECT CASE WHEN true THEN ARRAY[col_a::text, col_b::text] END AS main
FROM table1
LIMIT 100
) inner_t;
You lose name and type. You can cast and add aliases if you know name & type.
Else you have to describe your use case more closely - in the question.
Try Below query
SELECT split_part(main,',',1) as Val1,split_part(main,',',2) as Val2
FROM (
SELECT
CASE WHEN 1=1 THEN (col_a, col_b)
END as main
FROM "table1"
LIMIT 100) inner_t

SQL DB2 Replace value in a column

I have the following column, B represents boolean and the rest are empty values. I have to change all the values in this column to the word COLUMN A.
COLUMN
-----
B
I have tried different things, for example
SELECT COLUMN
FROM TABLE
WHERE COALESCE(NULLIF(COLUMN,''), 'COLUMN A');
And I receive the error: "Invalid character found in a character string argument of the function "BOOLEAN"." I'm kind of stuck to this question and I'm getting confused with this boolean value. I will be really happy if someone can help me, thanks!
The easiest thing is to use CASE expression. I am not familiar in db2, so you may want to research it further, but in other DBMSs it works like this:
SELECT CASE
WHEN COLUMN = '' THEN 'COLUMN A' -- if COLUMN = '', replace it with 'COLUMN A'
ELSE COLUMN -- otherwise, keep COLUMN as is.
END as 'COLUMN' -- name the column in the result 'COLUMN'
FROM TABLE
This is an article that explains how it works in db2:
https://www.ibm.com/support/knowledgecenter/en/SSEPEK_11.0.0/sqlref/src/tpc/db2z_caseexpression.html
The WHERE clause is unfinished. Compare the COALESCEd value to something:
SELECT COLUMN
FROM TABLE
WHERE COALESCE(NULLIF(COLUMN,''), 'COLUMN A') = 'COLUMN A';
Or better:
SELECT COLUMN
FROM TABLE
WHERE COLUMN IS NULL OR COLUMN = ''
Doesn't require any thinking/calculating to work out your selection logic. More maintainable, nicer for peer developers
*The above is generic advice for usual cases NOT involving boolean datatypes (which typically require some different treatment)
Now, you say you have to change the value to something. That requires an UPDATE statement. If this column is a boolean then it won't have a value of empty string. The blanks will be nulls:
UPDATE TABLE SET COLUMN = (some boolean) WHERE COLUMN IS NULL
If you don't want to permanently change the table data to something, but instead want to select it out as some value where a blank occurs, but keep the blanks stored in the table:
SELECT COALESCE(column, (some boolean)) FROM TABLE
Might be worth noting that not all versions of DB2 can return a boolean in a result set - this is quite typical of database vendors. Convert the boolean to something else representable using a case when, if your DB2 version is thus restricted
SELECT CASE WHEN column = TRUE THEN 'true' ELSE 'false' END FROM TABLE

is there any difference between the queries

select field from table where field = 'value'
select field from table where field in ('value')
The reason I'm asking is that the second version allow me to use the same syntax for null values, while in the first version I need to change the condition to 'where field is null'...
When you are comparing a field to a null like field_name=NULL you are comparing to a known data type from a field say varchar to not only an unknown value but also an unknown data type as well, that is, for NULL values. When comparison like field_name=NULL again implies therefore a checking of data type for both and thus the two could not be compared even if the value of the field is actually NULL thus it will always result to false. However, using the IS NULL you are only comparing for the value itself without the implied comparison for data type thus it could result either to false or true depending on the actual value of the field.
See reference here regarding the issue of NULL in computer science and here in relation to the similarity to your question.
Now, for the IN clause (i.e. IN(NULL)) I don't know what RDBMS you are using because when I tried it with MS SQL and MySQL it results to nothing.
See MS SQL example and MySQL example.
There is no difference in your example. The second, slightly longer, query is not usually used for a single value, it is usally seen for multiple values, such as
select field from table where field in ('value1', 'value2')
yes there is difference in both this queries. In first statment you can insert only 1 value in where clause "where field = 'value'" but in second statement in where field you can insert many values using IN clause "where field in (value1,value2..)"
Examples:
1) select field from table where field ='value1';
2) select field from table where field in ('value1', 'value2')
To check null values
SELECT field
FROM tbl_name
WHERE
(field IN ('value1', 'value2', 'value3') OR field IS NULL)

SQL: What does NULL as ColumnName imply

I understand that AS is used to create an alias. Therefore, it makes sense to have one long name aliased as a shorter one. However, I am seeing a SQL query NULL as ColumnName
What does this imply?
SELECT *, NULL as aColumn
Aliasing can be used in a number of ways, not just to shorten a long column name.
In this case, your example means you're returning a column that always contains NULL, and it's alias/column name is aColumn.
Aliasing can also be used when you're using computed values, such as Column1 + Column2 AS Column3.
When unioning or joining datasets using a 'Null AS [ColumnA] is a quick way to make sure create a complete dataset that can then be updated later and a new column does not need to be created in any of the source tables.
In the statement result we have a column that has all NULL values. We can refer to that column using alias.
In your case the query selects all records from table, and each result record has additional column containing only NULL values. If we want to refer to this result set and to additional column in other place in the future, we should use alias.
It means that "aColumn" has only Null values. This column could be updated with actual values later but it's an empty one when selected.
---I'm not sure if you know about SSIS, but this mechanism is useful with SSIS to add variable value to the "empty" column.
When using SELECT you can pass a value to the column directly.
So something like :
SELECT ID, Name, 'None' AS Hobbies, 0 AS NumberOfPets, NULL AS Picture, '' AS Adress
Is valid.
It can be used to format nicely a query output when using UNION/UNION ALL.
Query result can have a new column that has all NULL values. In SQL Server we can do it like this
SELECT *, CAST(NULL AS <data-type>) AS as aColumn
e.g.
SELECT *, CAST(NULL AS BIGINT) AS as aColumn
How about without using the the as
SELECT ID
, Name
, 'None' AS Hobbies
, 0 AS NumberOfPets
, NULL Picture
Usually adding NULL as [Column] name at the end of a select all is used when inserting into another table a calculated column based on the table you have just selected.
UPDATE #TempTable SET aColumn = Column1 + Column2 WHERE ...
Then exporting or saving the results to another table.