Teradata make FOLLOWING dynamic based on a column - teradata

I have a table with columns item, store, date, and fcst. For each item store day I need to sum the next x number of days of forecast, however x changes for each item store combination. This following code does not work and I was advised that X FOLLOWING has to be replaced with a static innteger FOLLOWING:
Doesn’t run:
SELECT
ITEMNBR,
STORENBR,
DT,
SUM(FCST)OVER(PARTITION BY STORENBR,ITEMNBR ORDER BY DT BETWEEN CURRENT ROW AND X ROWS FOLLOWING) AS VALUE
FROM TABLENAME
Does run:
SELECT
ITEMNBR,
STORENBR,
DT,
SUM(FCST)OVER(PARTITION BY STORENBR,ITEMNBR ORDER BY DT BETWEEN CURRENT ROW AND 7 ROWS FOLLOWING) AS VALUE
FROM TABLENAME
Any fix or suggested workaround?

Related

Adding date from 3 columns in table X to one column in table Y

Hi I am new to sqlite and I am wondering if it is possible to add date from 3 columns in table X to one column in table Y. For example, in Table X, I have 3 columns called startDay,startMonth,startYear. I want to add these to one column in table Y called Start_Date (possible in format DD/MM/YYYY). Also hopefully the format it is in should be able to carry out computation, i.e subtracting 2 dates. Any ideas?
You can do something like:
CREATE TABLE newtable(start_date TEXT);
INSERT INTO newtable
SELECT printf('%d-%02d-%02d', startYear, startMonth, startDay)
FROM oldtable;
And to compute the number of days between two dates:
SELECT juliandate('2019-06-30') - juliandate('2019-06-29') AS diff;
diff
----------
1.0
(Using a format other than those supported by sqlite date and time functions like your dd/mm/yyyy is a bad idea. Means you can't use them with the functions, and in your case, also means you can't meaningfully sort by date)

Redshift join with metadata table and select columns

I have created a subset of the pg_table_def table with table_name,col_name and data_type. I have also added a column active with 'Y' as value for some of the rows. Let us call this table as config.Table config looks like below:
table_name column_name
interaction_summary name_id
tag_transaction name_id
interaction_summary direct_preference
bulk_sent email_image_click
crm_dm web_le_click
Now I want to be able to map the table names from this table to the actual table and fetch values for the corresponding column. name_id will be the key here which will be available in all tables. My output should look like below:
name_id direct_preference email_image_click web_le_click
1 Y 1 2
2 N 1 2
The solution needs to be dynamic so that even if the table list extends tomorrow, the new table should be able to accommodate. Since I am new to Redshift, any help is appreciated. I am also considering to do the same via R using the dplyr package.
I understood that dynamic queries don't work with Redshift.
My objective was to pull any new table that comes in and use their columns for regression analysis in R.
I made this working by using listagg feature and concat operation. And then wrote the output to a dataframe in R. This dataframe would have 'n' number of select queries as different rows.
Below is the format:
df <- as.data.frame(tbl(conn,sql("select 'select ' || col_names|| ' from ' || table_name as q1 from ( select distinct table_name, listagg(col_name,',') within group (order by col_name)
over (partition by table_name) as col_names
from attribute_config
where active = 'Y'
order by table_name )
group by 1")))
Once done, I assigned every row of this dataframe to a new dataframe and fetched the output using below:
df1 <- tbl(conn,sql(df[1,]))
I know this is a round about solution. But it works !! Fetches about 17M records under 1 second.

PL/SQL Case with Group By and Pivot

I have data that I'm presenting in an APEX interactive report, using a pivot statement to display monthly data for a period of 15 years. I am color coding some of the values based on if it contains a decimal using a case statement.
My problem is that by using the case statement, it is creating multiple rows from one row of data. My report is showing 2 rows for each item, one for the row containing values without decimals, and one row with values containing decimals.
Multiple Rows
How can I combine the rows into one? Use a Group By? or is there a better way?
select buscat, prod_parent, year_month, volume, load_source, tstamp,
case when instr(VOLUME, '.') > 0 then 'color:#FF7755;' else 'color:#000000;' end flag
from HISTORY where id > 0
Here is raw data from SQL query...
SQL return
According to the SQL Return image the data is not repeating. It looks like you are not filtering for 'Volume == 0'. Try changing 'ID' to 'volume' in where clause:
select yearMonth, volume, load_source, tstamp,
case when instr(volume, '.') > 0 then 'color:#FF7755;' else 'color:#000000;' end flag
from HISTORY
where volume > 0

adding repeating sequence numbers to a column in SQLite database based on conditions

I added a column in my SQLite database, and I need to insert repeating sequence numbers, starting with 1...n BUT it's based on grouping by other columns. The sequence needs to start over at 1 again when there is a new grouping.
Here is my table:
CREATE TABLE "ProdRunResults" ("ID" INTEGER PRIMARY KEY NOT NULL UNIQUE , "SeqNumbr" INTEGER, "Shift" INTEGER, "ShiftSeqNumbr" INTEGER, "Date" DATETIME, "ProdRunID" INTEGER, "Result" VARCHAR)
ShiftSeqNumbr is the new column that I need to populate with sequence numbers, based on grouping of numbers in ProdRunID column then by numbers in the Shift column.
There could be up to 3 "shifts" (work shifts in a 24 hr period).
I scraped together some code to do this but it adds the sequence numbers to ShiftSeqNumbr column in reverse (descending) order:
UPDATE ProdRunResults
SET ShiftSeqNumbr = (SELECT COUNT (*)
FROM ProdRunResults AS N
WHERE N.ProdRunID = ProdRunResults.ProdRunID
AND N.Shift = ProdRunResults.Shift
AND N.ShiftSeqNumbr = ProdRunResults.ShiftSeqNumbr);
How can I change the Update statement so the sequence numbers start at 1 and go up? Or is there a better way to do this?
Your UPDATE statement counts how many rows there are that have the same values in the ProdRunID/Shift/ShiftSeqNumbr columns as the current row. The current row always has an empty value in ShiftSeqNumbr, so it is counting how many rows in the current group have not yet been updated.
You need to count how many rows come before the current row, i.e., how many rows have the same ProdRunID and Shift values, and the same or a smaller SeqNumbr value:
UPDATE ProdRunResults
SET ShiftSeqNumbr = (SELECT COUNT (*)
FROM ProdRunResults AS N
WHERE N.ProdRunID = ProdRunResults.ProdRunID
AND N.Shift = ProdRunResults.Shift
AND N.SeqNumbr <= ProdRunResults.SeqNumbr);

How to add a total column in SQLite

I am trying to run some analysis on sales data using SQLite.
At the moment, my table has several columns including a unique transaction ID, product name, quantity of that product and value of that product. For each transaction, there can be several records, because each distinct type of product in the basket has its own entry.
I would like to add two new columns to the table. The first one would be a total for each transaction ID which summed up the total quantity of all products in that basket.
I realize that there would be duplication in the table, as the repeated transaction IDs would all have the total. The second one would be similar but in value terms.
I unfortunately cannot do this by creating a new table with the values I want calculated in Excel, and then joining it to the original table, because there are too many records for Excel.
Is there a way to get SQL to do the equivalent of a sumif in Excel?
I was thinking something along the lines of:
select sum(qty) where uniqID = ...
But I am stumped by how to express that it needs to sum all quantities where the uniqID is the same as the one in that record.
You wouldn't create a column like that in SQL. You would simply query for the total on the fly. If you really wanted a table-like object, you could create a view that held 2 columns; uniqID and the sum for that ID.
Let's set up some dummy data in a table; column a is your uniqID, b is the values you're summing.
create table tab1 (a int, b int);
insert into tab1 values (1,1);
insert into tab1 values (1,2);
insert into tab1 values (2,10);
insert into tab1 values (2,20);
Now you can do simple queries for individual uniqIDs like this:
select sum(b) from tab1 where a = 2;
30
Or sum for all uniqIDs (the 'group by' clause might be all you're groping for:) :
select a, sum(b) from tab1 group by a;
1|3
2|30
Which could be wrapped as a view:
create view totals as select a, sum(b) from tab1 group by a;
select * from totals;
1|3
2|30
The view will update on the fly:
insert into tab1 values (2,30);
select * from totals;
1|3
2|60
In further queries, for analysis, you can use 'totals' just like you would a table.

Resources