SQL case query didn't work - sql

I have a table where there are two columns, which should technically just be one column. Let's say there are 20 rows in my table, id_col1 has data till row 15, then id_col2 has data from rows 16-20. So in my new table, I'm creating a new column that has data from these 2 columns by using a case statement. But, the new column accepts data from id_col1, but doesn't from id_col2, it's just blank when it should have data from id_col2. My code is as follows:
select
case
when id_col1 is null then id_col2
else id_col1 end as 'newcol',
cusip,
cast (Date as date) as 'Date',
Price,
Evaluator,
Yes_No as 'Accepted'
into #cloudtemptbl
from MasterData
where Date >= '2017-01-01'
select * from #cloudtemptbl
My theory is that the data in id_col2 is binary not string. Any help is highly appreciated. Thank you.

I would suggest this :
when id_col1 is null or id_col1 = '' then id_col2
else id_col1 end as 'newcol'

You might need to use CONVERT or CAST to get the data types to match across both tables.
Work out the data type you're planning on using in the final, combined table. Then use CAST or CONVERT on any data that doesn't match that type, to get it into the correct format.

Related

Need to identify same characters between two columns' value in spark sql

I have two columns one is code and other one is category
Code: category
321 3210001
432 4320001
5314 5314001
6310 7480001
Based on the above code value is exactly the prefix of category value.
Now I have to write a spark sql query which should provide how many rows are categorized and non categorized
eg: if code and prefix of category values are matching, then it should be categorized else
it is non categorized.
from the above table, 4th row is non-categorized and rest of them are categorized
I am trying to use like, substring, len, case but I am not able to achieve this result.
Could someone please help me out on this?
thanks,
Raja
assumed those columns are string , if not cast them to str by cast(column as string) in the same query below :
select case when instr(category , code) = 1
then 'Categorized'
else 'Non Categorized' end
, count(*) counts
from df
group by case when instr(category , code) = 1
then 'Categorized'
else 'Non Categorized' end

Multiple Between Dates from table column

There is yearly data in the source. I need to exclude the data -which is in another table and raw count is not static- from it.
Source data:
Dates to be excluded:
There can be 2 raws or 5 raws of data to be excluded, so it need to be dynamically and 2 tables can be bound by the DISPLAY_NAME column.
I am trying to do it with query, don't want to use sp. Is there any way or sp is only choise to do this.
Maybe multiple case when for each raw 1 / 0 and only get if all new case when columns are 1 but issue is don't know how many case when i will use since exclude table data raw count is not static.
Are you looking for not exists?
select s.*
from source s
where not exists (select 1
from excluded e
where e.display_name = s.display_name and
s.start_datetime >= e.start_date and
s.end_datetime < e.end_date
);
Note: Your question does not explain how the end_date should be handled. This assumes that the data on that date should be included in the result set. You can tweak the logic to exclude data from that date as well.

Compare value in each row to average of the column (SQL)

I am trying to create a view where the score for each row is compared to the average for that column, so that I can easily identify records by their rough "grade". Simplified code:
select recordID,
case when table.ColumnA>avg(all table.ColumnA) then 'Hard' else 'Easy' end as Difficulty,
from table
group by recordID, ColumnA
I've tried various combinations of this and the case formula keeps defaulting to 'else', which on investigation seems to be that every calculated value is coming out as 0, as both the row value and average value are being deemed the same.
I have a feeling the answer has something to do with Rollup, either on this table or the source table, but the syntax required is beyond me.
Anyone?
You want a window function:
select recordID,
(case when table.ColumnA > avg(table.ColumnA) over ()
then 'Hard' else 'Easy'
end) as Difficulty
from table;

How can I aggregate Jsonb columns in postgres using another column type

I have the following data in a postgres table,
where data is a jsonb column. I would like to get result as
[
{field_type: "Design", briefings_count: 1, meetings_count: 13},
{field_type: "Engineering", briefings_count: 1, meetings_count: 13},
{field_type: "Data Science", briefings_count: 0, meetings_count: 3}
]
Explanation
Use jsonb_each_text function to extract data from jsonb column named data. Then aggregate rows by using GROUP BY to get one row for each distinct field_type. For each aggregation we also need to include meetings and briefings count which is done by selecting maximum value with case statement so that you can create two separate columns for different counts. On top of that apply coalesce function to return 0 instead of NULL if some information is missing - in your example it would be briefings for Data Science.
At a higher level of statement now that we have the results as a table with fields we need to build a jsonb object and aggregate them all to one row. For that we're using jsonb_build_object to which we are passing pairs that consist of: name of the field + value. That brings us with 3 rows of data with each row having a separate jsonb column with the data. Since we want only one row (an aggregated json) in the output we need to apply jsonb_agg on top of that. This brings us the result that you're looking for.
Code
Check LIVE DEMO to see how it works.
select
jsonb_agg(
jsonb_build_object('field_type', field_type,
'briefings_count', briefings_count,
'meetings_count', meetings_count
)
) as agg_data
from (
select
j.k as field_type
, coalesce(max(case when t.count_type = 'briefings_count' then j.v::int end),0) as briefings_count
, coalesce(max(case when t.count_type = 'meetings_count' then j.v::int end),0) as meetings_count
from tbl t,
jsonb_each_text(data) j(k,v)
group by j.k
) t
You can aggregate columns like this and then insert data to another table
select array_agg(data)
from the_table
Or use one of built-in json function to create new json array. For example jsonb_agg(expression)

Literal Does Not Match 01861

select case
when sale not in TO_date(sale,'MMYY') then 'N'
else sale
end test
from daily sales
I would like to see if the data in the column meets the following criteria using the above select. I am receiving the following error:
LITERAL DOES NOT MATCH FORMAT STRING
small data set
0109
0106
0409
column is a varchar
to_date('0109', 'mmyy') is correct, it will return 01-01-2009 00:00:00 AM (in one possible format). So the problem is likely in the column - you may have one or more value(s) that are not, in fact, four digits. You need to do some troubleshooting.
Something I would try:
select max(length(sale)) as max_len, min(length(sale)) as min_len from table_name
(daily sales cannot be a table name - table names don't have spaces in them)