MS Access -SQL query - sql

Could someone explain what does the below code mean .
In ms access select join query with below condition (inside where )
Table1.col1 <> [table2]!col2
What does it mean?

It means not equal. Same as !=. It fetches all rows that are not equal to your table1.col1

Table of operators
https://support.office.com/en-us/article/table-of-operators-e1bc04d5-8b76-429f-a252-e9223117d6bd
Comparison operators
| Operator | Purpose | Example |
| <> | Returns True if the first value is not equal to the second value. | Value1 <> Value2 |
—-
Introduction to Access SQL
https://support.office.com/en-gb/article/introduction-to-access-sql-d5f21d10-cd73-4507-925e-bb26e377fe7e
Any relational comparison operator: "=," "<," ">," "<=," ">=," or "<>."
—-
Definition: The Bang (!) Operator
What the bang operator does is simple and specific:
The bang operator provides late-bound access to the default member of an object, by passing the literal name following the bang operator as a string argument to that default member.

Related

Express a ternary SQL data type

Context
I just met a single table in a PostgreSQL database which is actually only defining a triplet of coded values that are used across the whole database as a ternary data type. I am a bit astonished at first glance, I feel it's weird; there should be some ternary data type?
I've searched the web, especially the PostgreSQL documentation without any apparent success (I'm probably wrong with my search keywords?!), but maybe there is no other solution.
Question
I would like to know if it exists a ternary (as comparison with binary or boolean) data type in PostgreSQL or more generally in SQL which permits to express a "ternary state" (or "ternary boolean" which is clearly is an abuse of language), which I would represent as a general idea as:
+-------+----------+--------------------+
| id | type | also expressed as |
+-------+----------+--------------------+
| 0 | false | 0 |
| 1 | true | 1 |
| 2 | unknown | 2 |
+-------+----------+--------------------+
where unknown can be whatever third state you are actually dealing with.
I would like to know if it exists a ternary (as comparison with binary or boolean) data type
Actually, the boolean data type is ternary because it can have the values true, false and null.
Consider this table:
create table data (some_number int, some_flag boolean);
And the following data:
insert into data (some_number, some_flag)
values (1, true), (2, false), (3, null);
Then the following:
select *
from data
where some_flag = false;
will only return one row (with some_number = 2)
there is not a specific ternary operator but you could use case
select case when operator =0 then 'false'
when operatore =1 then 'true'
when operator = 2 then 'unknow'
else 'not managed'
end
from your_table
I second a_horse_with_no_name's solution for your specific example, but the more general approach is to use an enum data type:
CREATE TYPE ternary AS ENUM (
'never',
'sometimes',
'always'
);
Constants of such a data type are written as string constantls, e.g. 'never', but the internal storage uses 4 bytes per value, regardless of the length of the label.

How to do a count of fields in SQL with wrong datatype

I am trying to import legacy data from another system into our system. The problem I am having is that the legacy data is dirty- very dirty! We have a field which should be an integer, but sometimes is a varchar, and the field is defined as a varchar...
In SQL Server, how can I do a select to show those records where the data is varchar instead if int?
Thanks
If you want to find rows1 where a column contains any non-digit characters or is longer than 9 characters (either condition means that we cannot assume it would fit in an int, use something like:
SELECT * FROM Table WHERE LEN(ColumnName) > 9 or ColumnName LIKE '%[^0-9]%'
Not that there's a negative in the LIKE condition - we're trying to find a string that contains at least one non-digit character.
A more modern approach would be to use TRY_CAST or TRY_CONVERT. But note that a failed conversion returns NULL and NULL is perfectly valid for an int!
SELECT * FROM Table WHERE ColumnName is not null and try_cast(ColumnName as int) is null
ISNUMERIC isn't appropriate. It answers a question nobody has ever wanted to ask (IMO) - "Can this string be converted to any of the numeric data types (I don't care which ones and I don't want you to tell me which ones either)?"
ISNUMERIC('$,,,,,,,.') is 1. That should tell you all you need to know about this function.
1If you just want a count, as per the title of the question, then substitute COUNT(*) for *.
In SQL Server, how can I do a select to show those records where the data is varchar instead of int?
I would do it like
CREATE TABLE T
(
Data VARCHAR(50)
);
INSERT INTO T VALUES
('102'),
(NULL),
('11Blah'),
('5'),
('Unknown'),
('1ThinkPad123'),
('-11');
SELECT Data -- Per the title COUNT(Data)
FROM
(
SELECT Data,
cast('' as xml).value('sql:column("Data") cast as xs:int ?','int') Result
FROM T --You can add WHERE Data IS NOT NULL to exclude NULLs
) TT
WHERE Result IS NULL;
Returns:
+----+--------------+
| | Data |
+----+--------------+
| 1 | NULL |
| 2 | 11Blah |
| 3 | Unknown |
| 4 | 1ThinkPad123 |
+----+--------------+
That if you can't use TRY_CAST() function, if you are working on 2012+ version, I'll recommend that you use TRY_CAST() function like
SELECT Data
FROM T
WHERE Data IS NOT NULL
AND
TRY_CAST(Data AS INT) IS NULL;
Demo
Finally, I would say do not use ISNUMERIC() function because of (from docs) ...
Note
ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($). For a complete list of currency symbols, see money and smallmoney (Transact-SQL).

why does 10/NULL evaluate to null?

In SQL , why does 10/NULL evaluate to NULL (or unknown) ? Example :
if((10/NULL) is NULL)
DBMS_OUTPUT.PUT_LINE("Null.");
However , 1 = NULL being a COMPARISON is considered as FALSE. Shouldn't 10/NULL also be considered as FALSE ?
I am referring to SQL only . Not any DBMS in particular. And it might be a duplicate but I didn't know what keywords to put in search for this query.
Shouldn't 10/NULL also be considered as FALSE?
No, because:
Any arithmetic expression containing a null always evaluates to null. For example, null added to 10 is null. In fact, all operators (except concatenation) return null when given a null operand.
Emphasis mine, taken from the Oracle manual: http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements005.htm#i59110
And this is required by the SQL standard.
Edit, as the question was for RDBMS in general:
SQL Server
When SET ANSI_NULLS is ON, an operator that has one or two NULL expressions returns UNKNOWN
Link to the the manual:
MySQL
An expression that contains NULL always produces a NULL value unless otherwise indicated in the documentation for a particular function or operator
Link to the manual
DB2
if either operand can be null, the result can be null, and if either is null, the result is the null value
Link to the manual:
PostgreSQL
Unfortunately I could not find such an explicit statement in the PostgreSQL manual, although I sure it behaves the same.
Warning: The "(except concatenation)" is an Oracle only and non-standard exception. (The empty string and NULL are almost identical in Oracle). Concatenating nulls gives null in all other DBMS.
1 = null is not null. It is actually unknown. As well as any other null operation.
The equality predicate 1 = NULL evaluates to NULL. But NULL in a boolean comparison is considered false.
If you do something like NOT( 1 = NULL ), 1 = NULL evaluates to NULL, NOT( NULL ) evaluates to NULL and so the condition as a whole ends up evaluating to false.
Oracle has a section in their documentation on handling NULL values in comparisons and conditional statements-- other databases will handle things in an very similar manner.
10/something means that you are counting how much "something" will be in 10
in this case you're counting how much "nothing" will be in 10 - that's infinity, unknown..
1 = NULL is false because one does not equal nothing
The NULLIF function accepts two parameters. If the first parameter is equal to the second parameter, NULLIF returns Null. Otherwise, the value of the first parameter is returned.
NULLIF(value1, value2)
NVL
The NVL function accepts two parameters. It returns the first non-NULL parameter or NULL if all parameters are NULL.
also check this conditional outcomes:
This "null equals UNKNOWN truth value" proposition introduces an inconsistency into SQL 3VL. One major problem is that it contradicts a basic property of nulls, the property of propagation. Nulls, by definition, propagate through all SQL expressions. The Boolean truth values do not have this property. Consider the following scenarios in SQL:1999, in which two Boolean truth values are combined into a compound predicate. According to the rules of SQL 3VL, and as shown in the 3VL truth table shown earlier in this article, the following statements hold:
( TRUE OR UNKNOWN ) → TRUE
( FALSE AND UNKNOWN ) → FALSE
However, because nulls propagate, treating null as UNKNOWN results in the following logical inconsistencies in SQL 3VL:
( TRUE OR NULL ) → NULL ( = UNKNOWN )
( FALSE AND NULL ) → NULL ( = UNKNOWN )
The SQL:1999 standard does not define how to deal with this inconsistency, and results could vary between implementations. Because of these inconsistencies and lack of support from vendors the SQL Boolean datatype did not gain widespread acceptance. Most SQL DBMS platforms now offer their own platform-specific recommendations for storing Boolean-type data.
Note that in the PostgreSQL implementation of SQL, the null value is used to represent all UNKNOWN results and the following evaluations occur:
( TRUE OR NULL ) → TRUE
( FALSE AND NULL ) → FALSE
( FALSE OR NULL ) IS NULL → TRUE
( TRUE AND NULL ) IS NULL → TRUE

SQL Server boolean operators

I know that SQL Server does not have boolean data type and your best option is to use BIT data type.
My question is to what boolean expressions evaluate. For example if I have the statement
expr1 AND expr2
and if expr1 is true and expr2 is false, do they internally evaluate to BITs with values 1 and 0? And then the AND operator checks for BITs?
I think this is not the case because then the following should work:
select 1 where 1 and 0
So does sql server internally have a boolean data type?
The following work
select 1 where 1 = 0
select 1 where 1 = 0 and 0 = 0
but this
select 1 where 1 and 0
reports
Msg 4145, Level 15, State 1, Line 1
An expression of non-boolean type specified in a context where a condition is expected, near 'and'.
which means that internally sql server handles the expressions as booleans, but why don't have access to that data type.
SQL Server does have a Boolean data type. You can open the Logical Operators (Transact-SQL) manual page and find the following statement:
Logical operators test for the truth of some condition. Logical operators, like comparison operators, return a Boolean data type with a value of TRUE, FALSE, or UNKNOWN.
It's just that you can't use this type in the same way you can use other Transact-SQL data types. For instance, you can't declare boolean variables or arguments, add boolean columns to tables, cast to/from a boolean. But you can have boolean expressions and use them in contexts where they are required (WHERE, ON, check constraints…). You can also apply boolean operators to those expressions: AND, NOT et al. (Operators like <, =, LIKE and other can also be considered boolean, in the sense that they return boolean results, but their operands are actually never booleans.)
So, to summarise, there is a boolean type in SQL Server but its use is limited, as described above. Why? My answer may be a silly one, sorry, but that's one that I'm satisfied with: this is the way they chose it to be.
Logical operators results in true or false. So in your example you get a result if expr1 and expr2 is true. To check if its true or not is the operation you do for each expression.
So you compare e.g. a column against something like a bit value column_bit = 0 and this results in true or false.
If your expr1 is true and expr2 is false your result is false for the logical AND operator.
Edit:
Your select 1 where 1 and 0 can't work because you don't use a compare operator. 1=1 AND 0=0 works e.g. but its nonsense :)

Why doesn't comparison work in CONVERT?

Is it possible to use a comparison operator in a CONVERT or CAST function?
I've got a statement that looks like this:
SELECT
...
CASE field
WHEN 'Y' THEN 1 # If Y then True
ELSE 0 # Anything else is False
END
...
FROM ...
A similar thing happens for a few fields, so I would like to change it to a shorter version:
SELECT
...
CONVERT(BIT, field = 'Y')
...
FROM ...
But MSSQL is giving an error Incorrect syntax near '='.
My interpretation of the help is that it should work:
CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
expression: expression { binary_operator } expression
binary_operator: Is an operator that defines the way two expressions are combined to yield a single result. binary_operator can be an arithmetic operator, the assignment operator (=), a bitwise operator, a comparison operator, a logical operator, the string concatenation operator (+), or a unary operator.
comparison operator: ( = | > | < | >= | <= | <> | != | !< | !> )
I ran a few tests and got these results:
SELECT CONVERT(BIT, 0) // 0
SELECT CONVERT(BIT, 1) // 1
SELECT CONVERT(BIT, 1+2) // 1
SELECT CONVERT(BIT, 1=2) // Error
SELECT CONVERT(BIT, (1=2)) // Error
SELECT CONVERT(BIT, (1)=(2)) // Error
I think you are misinterpreting the documentation for CONVERT. There is nothing in the documentation for CONVERT that states it will handle an expression that makes use of the comparison operators, only that it accepts an expression. It turns out that CONVERT does not handle every valid SQL expression. At the very least it cannot handle the results of an expression that uses a comparison operator.
If you check the documentation for Operators, you'll see that the comparison operators (which is what you want = to be, in this case) return a Boolean data type, and are used in WHERE clauses and control-of-flow statements. From the documentation for Operators:
The result of a comparison operator has the Boolean data type, which has three values:
TRUE, FALSE, and UNKNOWN. Expressions that return a Boolean data type are known as
Boolean expressions.
Unlike other SQL Server data types, a Boolean data type cannot be
specified as the data type of a table column or variable, and cannot
be returned in a result set.
...
Expressions with Boolean data types are used in the WHERE clause to
filter the rows that qualify for the search conditions and in
control-of-flow language statements such as IF and WHILE...
That helps to explain why SQL like SELECT 1=2 is invalid SQL, because it would create a result set with a Boolean data type, which the documentation says is not allowed. That also explains why the CASE WHEN construct is necessary, because it can evaluate the comparison operators and return a single value of a data type that SQL Server can return in a result set.
Furthermore, if you look at the documentation for CONVERT, you'll see that Boolean is not supported in either CAST or CONVERT (see the table towards the middle of the page, there is no Boolean data type in there).
For your purposes, I think you're stuck using CASE WHEN. If it helps you can write it all on one line:
CASE WHEN field = 'Y' THEN 1 ELSE 0 END
Alternatively, you could create a UDF to handle the CASE expression (something like dbo.func_DoCase(field, 'Y', 1, 0)), but personally I would just stick with CASE WHEN.