DB2 Error. Inserting to a table through select query - sql

I am tryin to insert some data to a table usin a query that uses tables and subquery. The subquery is where the case clause is used, and a I get the error : ERROR [HY000] [IBM][Controlador ODBC de iSeries Access][DB2 UDB]SQL0420 - The CAST argument character is not valid.
I only get this error when I run the insert command. When I run the select command there are no errors. this is the query
insert into qlib.table
select a.fieldkey, a.field2, ifnull(n.firstdate,0) as firstdate, ifnull(n.lastdate,0) as lastdate, n.totamount, n.timespan
from mainlib.tablea a
left join (select b.fieldkey, MIN(rtrim(b.year)||'-'||case when b.month<10 then '0'||b.month else rtrim(b.month)end) as firstdate,
MAX(rtrim(b.year)||'-'||case when b.month<10 then '0'||b.month else rtrim(b.month) end) as lastdate, sum(b.amount) as totamount,
cast(count(b.year)/12 as char(2))||' Years '||cast(count(b.year)-(count(b.year)/12)*12 as char(2))||' Months' as timespan
from mainlib.tableb b
group by b.fieldkey) n on n.fieldkey = a.fieldkey
Tableb contains monthly savings ok. The subquery returns the first year-month of saving, the last year-month, the total amount, and the years and months span of saving monthly, under the assumption that every month there is a saving/deposit, for each fieldkey
Is there anything wrong with the cast clause of the subquery. Again I only get error when I am trying to insert to qlib.table using the select command.

A few things might clean up your query:
case when b.month<10 then '0'||b.month else rtrim(b.month)end can be replaced with
VARCHAR_FORMAT(b.month,'00')
cast(count(b.year)/12 as char(2))||' Years '||cast(count(b.year)-(count(b.year)/12)*12 as char(2))||' Months' rewritten as
VARCHAR_FORMAT(count(b.year)/12,'99')||' Years '||VARCHAR_FORMAT(count(b.year)-(count(b.year)/12)*12,'99')||' Months'

Related

sql Countrows between date from other table and current_date

All,
To be honest I used to work with Power bi without knowing SQL, so I am learning things backwards.
I started learning SQL two weeks ago for my current (new role) at work.
So probably it is just a simple rookie mistake.
In this case I have 2 tables
events and marketingprofiles
In Table 1 (events) I have columns named
pk_eventtype_id (Which I want to count)
eve.starting (which is the date of the interview)
From the other Table 2 (marketingprofiles) I need the
marketinglivedate (as the new date to count from) Till current_date.
Both tables have a relationship column called mar.pk_marketingprofile_id and eve.marketingprofile_id
I am trying to count the number of interviews someone had in a certain period.
Tried it like this with a sub query, but receive an error at the
ERROR: syntax error at or near "(" LINE 8: (SELECT count(*)
SELECT
eve.femarketingname,
eve.starting,
eve.ending,
eve.pk_event_id,
COUNT(eve.pk_event_id) AS num_int
(SELECT count(*)
FROM marketingprofiles mar
where mar.marketinglivedate >= eve.starting
AND current_date <= eve.ending) AS num_int_by_MLD
FROM events eve
GROUP BY eve.femarketingname,
eve.starting,
eve.ending,
eve.pk_event_id
So I tried with an other method,But here i get the error:
ERROR: operator does not exist: integer >= timestamp with time
zone LINE 8: Where pk_event_id BETWEEN eve.starting and
current_date
Select
*,
Count(pk_event_id)
From
Events eve
Left join marketingprofiles mar
On eve.starting = mar.marketinglivedate
Where pk_event_id BETWEEN eve.starting and current_date
Group by femarketingname

SQL Why am I getting the invalid identifier error?

I am trying to use columns that I created in this query to create another column.
Let me first my messy query. The query looks like this:
SELECT tb.team, tb.player, tb.type, tb.date, ToChar(Current Date-1, 'DD-MON-YY') as yesterday,
CASE WHEN to_date(tb.date) = yesterday then 1 else 0 end dateindicator,
FROM (
COUNT DISTINCT(*)
FROM TABLE_A, dual
where dateindicator = 1
Group by tb.team
)
What I am trying to do here is:
creating a column with "Yesterday's date"
Using the "Yesterday" column to create another column called dateindicator indicating each row is yesterday's data or not.
then using that dateindicator, I want to count the distinct number of player for each team that has 1 of the dateindicator column.
But I am getting the "invalid identifier" error. I am new to this oracle SQL, and trying to learn here.
You cannot use an Alias in your Select statement.
see here: SQL: Alias Column Name for Use in CASE Statement
you need to use the full toChar(.. in the CASE WHEN.
Also:
Your WHERE-condition (Line 5) doesnt belong there.. it should be:
SELECT DISTINCT .>. FROM .>. WHERE. you have to specify the table first. then you can filter it with where.
If I follow your explanation correctly: for each team, you want to count the number of players whose date column is yesterday.
If so, you can just filter and aggregate:
select team, count(*) as cnt
from mytable
where mydate >= trunc(sysdate) - 1 and mydate < trunc(sysdate)
group by team
This assumes that the dates are stored in column mydate, that is of date datatype.
I am unsure what you mean by counting distinct players; presumably, a given player appears just once per team, so I used count(*). If you really need to, you can change that to count(distinct player).
Finally: if you want to allow teams where no player matches, you can move the filtering logic within the aggregate function:
select team,
sum(case when mydate >= trunc(sysdate) - 1 and mydate < trunc(sysdate) then 1 else 0 end) as cnt
from mytable
group by team

AWS Redshift column "view_table_B.cost" must appear in the GROUP BY clause or be used in an aggregate function

I have 2 queries in AWS Redshift, the queries target different table with similar schema. But my issue is that one of the query is working meanwhile the other is failed.
First Query
SELECT view_table_A.accountId, view_table_A.date, SUM(view_table_A.cost) as Cost
FROM view_table_A
GROUP BY accountId, date
HAVING Cost >= '20'
Second Query
SELECT view_table_B.projectname, view_table_B.usagedate, sum(view_table_B.cost) as Cost
FROM view_table_B
GROUP BY projectname, usagedate
HAVING Cost >= '20'
My problem is that the first query is working well meanwhile second query will return error as below
Amazon Invalid operation: column "view_table_B .cost" must appear in the GROUP BY clause or be used in an aggregate function;
Update-1
I try to remove ' from the query but still get same result. And I attach the screenshot of query I tried to execute in redshift.
Redshift identifiers are case insensitive, therefore cost and Cost collide in your query.
I was able to reproduce the problem with:
with src(cost, dat) as (
select 1, current_date
union all
select 2, current_date
)
SELECT
dat,
sum(s.cost) as Cost
FROM src s
GROUP BY dat
HAVING Cost = 3
;
it's giving me
[2020-06-04 11:22:44] [42803][500310] Amazon Invalid operation: column "s.cost" must appear in the GROUP BY clause or be used in an aggregate function;
If you renamed the column to something distinct, that would fix the query:
with src(cost, dat) as (
select 1, current_date
union all
select 2, current_date
)
SELECT
dat,
sum(s.cost) as sum_cost
FROM src s
GROUP BY dat
HAVING sum_cost = 3
;
I was also surprised to see that quoting identifiers with " does not solve the problem - as I initially expected.

ERROR: more than one row returned by a subquery used as an expression in inserting data

I'm trying to insert a data in the down_event table using the data on my event table that has more than 1k data but the problem is i'm encountering the more than one row is being returned by my subquery.
Below is my query code:
INSERT INTO dashboard.down_event(terminal_id, event_description, down_date, down_time, down_duration_sec)
SELECT terminal_id, event_description, event_start_adj::TIMESTAMP::DATE AS date, event_start_adj::TIMESTAMP::TIME AS time, (SELECT EXTRACT(EPOCH FROM (SELECT event_end_adj FROM dashboard.event )::timestamp - (SELECT event_start_adj FROM dashboard.event)::timestamp) AS seconds) FROM dashboard.event WHERE event_status = 'DOWN' AND planned = 'UNPLANNED'
Upon checking the query. It works for the query below and got all the data i needed in the table.
SELECT terminal_id, event description, event_start_adj::TIMESTAMP::DATE as date, event_start_adj::TIMESTAMP::TIME AS time
but the problem is when i added my query for extracting the seconds when subtracting the event_end_adj column and the event_start_adj column. The error seems to appear on this query.
I can't figure out why you would be using a subquery. Does this do what you want?
SELECT terminal_id, event_description,
event_start_adj::TIMESTAMP::DATE AS date,
event_start_adj::TIMESTAMP::TIME AS time,
(EXTRACT(EPOCH FROM event_end_adj::TIMESTAMP) -
EXTRACT(EPOCH FROM event_start_adj::TIMESTAMP)
) AS seconds
FROM dashboard.event
WHERE event_status = 'DOWN' AND planned = 'UNPLANNED'

Redshift - Case statement returns duplicates

I have a dataset that has product name, order number and the time order was placed.
prod_name,order_no,order_time
a,101,2018-05-01
a,102,2018-06-04
a,103,2018-05-03
b,104,2018-01-21
b,105,2018-01-11
I am trying to build a report that shows time since first order (compared against current time) with an output as below:
prod_name,time_since_first_sale,aging
a,64,Less than 3 months back
b,177,Less than 6 months back
Given below is the SQL I am using:
select DISTINCT b.prod_name,case when((CURRENT_TIMESTAMP - min(a.order_time))) < '90' THEN 'Less than 3 months'
when ((CURRENT_TIMESTAMP - min(order_time))) < '180' THEN 'Less than 6 months'
else 'Other' end as aging
from sales a, prod b where a.id=b.prod_id;
The above SQL when executed returns duplicates, believe it also considers each sale_id in the sales table. How could I modify the above query to get just one record per prod_name. If I however remove the case statement the duplicates are not there. Could any one assist as to what I am doing wrong that pulls in these duplicates.
I am using Amazon Redshift DB.
Thanks..
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax.
Don't use SELECT DISTINCT when you intend GROUP BY.
So your query should look like:
select p.prod_name,
(case when CURRENT_TIMESTAMP - min(s.order_time) < '90'
then 'Less than 3 months'
when CURRENT_TIMESTAMP - min(s.order_time) < '180' then 'Less than 6 months'
else 'Other'
end) as aging
from sales s join
prod p
on s.id = p.prod_id
group by p.prod_name;
Notice that I also added in reasonable table aliases (abbreviations for the table names) and qualified all column references.