Access query doesn't work with DISTINCT and Val() - sql

I have a query
SELECT col1, Val(col2)
FROM table1;
where col2 is a text data type.
I want to use DISTINCT here,
SELECT DISTINCT col1, Val(col2)
FROM table1;
but when I add it, I have an error
"Data type mismatch in criteria expression".
I have the same error when I try to sort the column2 (for the first query). Why?

The Val function doesn't process NULL values. Change your second column to Val(nz(col2,""))

I'm answering my question.
Because some of the rows have NULL value in col2 and SQL cannot compare two NULLs to find distinct rows, one should add WHERE col2 IS NOT NULL.
SELECT DISTINCT col1, Val(col2)
FROM table1
WHERE col2 IS NOT NULL;

Related

DB2 SQL Select All With Columns As

I am working with some SQL queries on DB2. Is it possible to select all the columns in a table and also specify certain conditions using the "as" keyword within that select statement? For example, is this query possible:
select
*,
col1 + col2 as sum1,
col3 - col4 as dif1
from
table;
Whenever I attempt this, I am getting the SQL0104 error and it is saying "Token , was not valid. Valid tokens: FROM INTO".
Thank you for your help.
EDIT:
This query is running inside an SQLRPGLE program on an AS400.
Put your table alias in front of the *. So:
select
t.*,
col1 + col2 as sum1,
col3 - col4 as dif1
from
table t;

Insert Statement for List

I'm not too sure how to describe my SQL Insert statement so I will describe the expected result.
I'm building a data extract list and have a table that I've put all my data into. It's called _MATTER_LIST
What I am trying to Achieve is to have the Client_Number + Col1 combination repeat after every unique COL1+COL2+COL3 combination but not duplicate when there is already a CLIENT_NUMBER+COL1. So the end result would be:
thanks in advance for any tips.
Simple ORDER BY should work for you if i understand. Try this :
select Client_Number, Col1, Col2, Col3 from _MATTER_LIST
order by Client_Number, Col1
I've managed to fix my own issue. I added a unique key for the col1 + col2 + col3 , then make col2 repeat over each combination for example.
The result is: select * from _MATTER_LIST order by COL4, COL5

Reject a row based on 2 column values

Below is the output of a simple join query. All the 3 columns are from different tables.
Col1 Col2 Col3
Manual Y-Yes Include
MC Y-Yes Include
Manual Y-Yes Exclude
Manual Y-Yes Exclude
I need to get the rows with 'Include' only if there is no 'Exclude' for the same Col1 value.
If there is no 'Exclude' for the Col1 value, then its fine to display 'Include'.
So the query should not display the first row according to the requirement since the Col1 value 'Manual' has 'Exclude'.
Your sql query should look a lot like what your question would be in English:
You want all the rows where there is no row for the same col1 value that has 'Exclude' in the col3 value, right?
I cannot give exact sql since you do not provide table or column names, but if all three columns were in the same table, it would look like this:
Select * from mytable
where not exists
(select * from mytable
where col1 = t.col1
and col3 = 'Exclude')

How to generate Dynamic Order by clause in PL/SQL procedure?

I am trying to write a PL/SQL procedure which will have the SQL query to get the results. But the requirement is that the order by can be dynamic and is mainly for sorting the columns in the screen. I am passing 2 parameters to this procedure - in_sort_column and in_sort_order.
The requirement is such that on text columns the sorting is in ASC and for numbers it is DESC.
My query looks something like this without adding the in_sort_order -
SELECT col1, col2, col3 from tabl e1 where col1 > 1000
ORDER BY decode(in_sort_column,'col1', col1, 'col2', col2, 'col3', col3);
I am not able to figure out how to use the in_sort_order parameter in this case. Can someone who has done this before help out ?
Thanks
When doing a dynamic sort, I recommend using separate clauses:
order by (case when in_sort_column = 'col1' then col1 end),
(case when in_sort_column = 'col2' then col2 end),
(case when in_sort_column = 'col3' then col3 end)
This guarantees that you will not have an unexpected problem with type conversion, if the columns are of different types. Note that case return NULL without an else clause.
Since the requirement is based on data type, you could just negate the numeric columns in your decode; if col1 is numeric and the others are text then:
ORDER BY decode(in_sort_column, 'col1', -col1, 'col2', col2, 'col3', col3);
But this is going to attempt to convert the text columns to numbers. You can swap the decode or around to avoid that, but you then do an implicit conversion of your numeric column to a string, and your numbers will then be sorted alphabetically - so 2 comes after 10, for example.
So Gordon Linoff's use of case is better, and you can still negate the col1 value with that to make the numbers effectively sort descending.

How do I add a null row in Postgres in a generic manner

I would like to do
select col1, col2 from foo union values (null, null)
but null is given the default type of TEXT, so I get the error "UNION types [e.g.] integer and text cannot be matched". In specific cases I can provide the types of the columns of foo, but I am constructing SQL statements programatically and it would be preferable if I didn't have to carry around the column type information with me.
Is there a workaround for this?
You can query INFORMATION_SCHEMA table COLUMNS using query like this:
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'mytable'
or you can use PostgreSQL specific form:
SELECT attname, atttypid::regtype
FROM pg_attribute
WHERE attrelid = 'public.mytable'::regclass
AND attnum > 0
This will give you data types for columns of interest in your table. Having this, in your automated framework you can generate UNION string to add empty row by casting NULLs to required data type, like this:
SELECT col1, col2 FROM foo
UNION ALL VALUES (NULL::VARCHAR, NULL::INTEGER)
Probably more important question is why do you want empty row? Perhaps you can get around without having this synthetic empty row in first place?
Just abuse an outer join like so:
select col1, col2 from foo
full join (select) as dummy on false
If col1 is of type bar and col2 is of type baz then
select col1, col2 from foo union values (null::bar, null::baz)
Will work
Actually, you can cast NULL to int, you just can't cast an empty string to int. Assuming you want NULL in the new column if data1 contains an empty string or NULL, you can do something like this:
UPDATE table SET data2 = cast(nullif(data1, '') AS int);
or
UPDATE table SET data2 = nullif(data1, '')::int;
Reference