How do I add calculated field for this?
I have table in tableau in following format (connected through redshift and every day 100000 rows are appended for the same ID1 and ID2, and sometimes new values for ID1 and ID2 are also added):
Value in Date Field 1 could either be Null or some date value (which is appended every day). What I want is whenever for specific combination of ID1 and ID2, Date Field 1 is not Null, I want that value to be copied to other rows also as follows:
How do I do it?
Note: I got an answer for this question under SQL tag but it is with UPDATE table method: SQL: Copy values for unique keys from one row to other
But I specifically need answer for tableau also to add calculated field.
You can create a calculated field using IF THEN statement as in the images below to look for a Match:
You can see the data reflects the new Match field as well:
Related
Is there a way to ignore values with missing columns when using INSERT INTO in PostgreSQL?
For example:
INSERT INTO tblExample(col_Exist1, col_Exist2, col_NotExist) VALUES ('Val1', 'Val2', 'Val3)
I want to insert a new row containing values Val1 and Val2, but ignore Val3 since its column does not exist, so the result would be:
# | col_Exist1 | col_Exist2
-----------------------------
1 | Val1 | Val2
I see that there is a INSERT ... ON CONFLICT DO NOTHING construct, but this seems to apply to an entire row only - not a singular value.
For explanation, I realise this may be not best practice, but my application is using dynamically created queries based on properties from documents - the properties can vary, but there are lots of columns, so defining them explicitly is painful. Instead, I'm using a 'template' document to define them and, hopefully, I can just ignore properties from other documents that don't exist in the template document.
Thanks in advance.
EDIT: I've figured out a workaround for now - I'm just querying the table to get the list of columns - if the column name exists, add the property to the new INSERT INTO query. The original question still stands.
What about moving document's data to json?
Form one table where you will have following fields:
Table: Documents
id: uuid4
name: varchar or text
data: json type according https://www.postgresql.org/docs/devel/datatype-json.html
After this trick you can store any dynamical data you'd like
I have two columns, I want the second column to have the same values as the first column always, in PostgreSQL.
The columns are landmark_id (integer) and name (varchar), I want the name column to always have the same values (id's) from landmark_id.
landmark_id (integer) | name (varchar)
1 1
2 2
3 3
I don't understand why you would want to do that, but I can think of two ways to accomplish your request. One is by using a generated column
CREATE TABLE g (
landmark_id int,
name varchar(100) GENERATED ALWAYS AS (landmark_id::varchar) STORED
)
and the other is by enforcing a constraint
CREATE TABLE c (
landmark_id int,
name varchar(100),
CONSTRAINT equality_cc CHECK (landmark_id = name::varchar)
)
Both approaches will cause the name column to occupy disk space. The first approach will not allow you to specify the name column in INSERT or UPDATE statements. In the latter case, you will be forced to specify both columns when inserting.
You could also have used a trigger to update the second column.
Late edit: Others suggested using a view. I agree that it's a better idea than what I wrote.
Create a view, as suggested by #jarlh in comments. This automatically generates column name for you on the fly. This is usually preferred to storing essentially the same data multiple times as in an actual table, where the data occupies more disk space and also can get out of sync. For example:
CREATE VIEW landmarks_names AS
SELECT landmark_id,
landmark_id::text AS name
FROM landmarks;
I have a TSV file that I want to load into redshift via the copy command.
I want one of the fields in the table to be a timestamp that registers the time the row was loaded.
I have defined a field like this:
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
This works fine if I insert into this row at the psql command line, without specifying a value for this column - it defaults to the current timestamp as expected.
However, what can I have in my TSV file in that column that will cause redshift to default to the current timestamp?
If I use \N in my TSV, then I just get a NULL in the ts field.
On the other hand, if I define my column as NOT NULL
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
then I get an error from the COPY command that I can't insert NULL values into a NOT NULL field.
On mysql, mysql would convert a NULL value into the current timestamp, but redshift's behaviour is to throw an error.
Any suggestions? Many thanks!
I've been banging my head over this for a while and found one partial workaround: you can have ts column as the last column of your table and the TSV file with all the other columns but this one. The file will be read with the columns that exist and loaded into the consecutive list of columns with the same width in the target table, leaving all columns beyond that width with default values, i.e. you can have id | ts table and load the file with id only and ts will take the default. The current timestamp column is typically a metadata column, so it's ok to place it at the end of the table.
I have a table test_123 with the column as:
int_1 (int),
datetime_1 (datetime),
tinyint_1 (tinyint),
datetime_2 (datetime)
So when column datetime_1 is updated and the value at column tinyint_1 = 1 that time i have to update my column datetime_2 with column value of datetime_1
I have created the below trigger for this.. but with my trigger it is updating all datetime2 column values with datetime_1 column when tinyint_1 = 1 .. but i just want to update that particular row where datetime_1 value has updated( i mean changed)..
Below is the trigger..
CREATE TRIGGER test_trigger_upd
ON test_123
FOR UPDATE
AS
FOR EACH STATEMENT
IF UPDATE(datetime_1)
BEGIN
UPDATE test_123
SET test_123.datetime_2 = inserted.datetime_1
WHERE test_123.tinyint_1 = 1
END
ROW-level triggers are not supported in ASE. There are only after-statement triggers.
As commented earlier, the problem you're facing is that you need to be able to link the rows in the 'inserted' pseudo-table to the base table itself. You can only do that if there is a key -- meaning: a column that uniquely identifies a row, or a combination of columns that does so. Without that, you simply cannot identify the row that needs to be updated, since there may be multiple rows with identical column values if uniqueness is not guaranteed.
(and on a side note: not having a key in a table is bad design practice -- and this problem is one of the many reasons why).
A simple solution is to add an identity column to the table, e.g.
ALTER TABLE test_123 ADD idcol INT IDENTITY NOT NULL
You can then add a predicate 'test_123.idcol = inserted.idcol' to the trigger join.
I have to tables with identical columns. In both cases the first column is called id and type of SERIAL.
I want to copy the content of the second to the first table. I want to copy everything except the id. If I do this:
INSERT INTO first
SELECT *
FROM second;
It will complain, because it will duplicate the id.
If I do this:
INSERT INTO first
SELECT 1col, 2col, 3col .... (every column except the id column, which I dont want to be copied)
FROM second;
It will complain because it tries to insert the value of the '1col' into id column.
ERROR: column "id" is of type bigint but expression is of type date
So the bottom line is I want copy EVERYTHING except the SERIAL value, which needs to be calculated by the receiving table. Any hint?
You were half way there.
INSERT INTO first (1col, 2col, 3col ....)
SELECT 1col, 2col, 3col ....
FROM second
Yes, you have to repeat all the columns. No, there's no way to say "all except id".