create a table where one insert is a batch - postgresql

I want to create a table where one insert is a batch and if there are the same rows trying to insert again it should throw an error.
Here is a simple example.
This is one insert, if we try to insert these rows again it should throw an error.(It should not insert)
col1 col2 col3 col4(ID)
row1 a 0.1 xyz 1
row2 b 0.2 abc 1
row3 c 0.3 pqr 1
Now I just changed insert little bit this should be as a new insert.
col1 col2 col3 col4(ID)
row1 a 0.1 xyz 2
row2 b 0.211 abc 2
row3 c 0.3 pqr 2
I tried composite primary key but I was missing something. I'm seeing this error
ERROR: duplicate key value violates the unique constraint.
I want to throw an error when all three rows are repeated. If anything is changed in these 3 rows it should be a new insert.

Related

Replace infinity with nulls throughout entire table KDB

Example table:
table:([]col1:20 40 30 0w;col2:4?4;col3: 100 200 0w 300)
My solution:
{.[table;(where 0w=table[x];x);:;0n]}'[exec c from meta table where t="f"]
There is a way I am not seeing I'm sure. This just returns a list of for each change which I don't want. I just want the original table returned with nulls replaced.
Thanks in advance!
It would be good to flesh out your question a bit more. Are you always expecting it to be float columns? Will the table have many columns? Will there be string/sym columns mixed in that might complicate things?
If your table has a small number of columns you could just do an update
q)show t
col1 col2 col3
--------------
20 1 100
40 2 200
30 2 0w
0w 1 300
q)inftonull:{(x where x=0w):0n;x}
q)update inftonull col1, inftonull col3 from t
col1 col2 col3
--------------
20 2 100
40 1 200
30 0
3 300
If you think the column names might change or have a very large number of columns you could try a functional update (where you can pass the column names as parameters)
q){![t;();0b;x!inftonull,/:x,:()]}`col1`col3
col1 col2 col3
--------------
20 1 100
40 2 200
30 2
1 300
If your table is comprised of only numeric data something like
q)flip{(x where x=.Q.t[type x]$0w):x 0N;x}each flip t
col1 col2 col3
--------------
20 2 100
40 1 200
30 0
3 300
Might work, which tries to account for the fact the numeric data has different types.
If your data is going to contain string/sym columns the last example won't work

Randomly select observations separately for each column in SQL

I am interested in generating a completely (damaged) randomized data where observations are selected randomly (with replacement) for each field and then combined. I will need to generate a new dummy id to represent the old id as I don't want to reconstruct the data. My goal is to create a simulated column-wise random dataset.
Here is a sample data:
Id Col1 Col2 Col3
11 A 0.01 David
12 B 0.04 Max
13 C 0.05 Tom
14 E 0.06 West
15 C 0.02 Mike
What I am interested in is something like this:
Id2 Col1 Col2 Col3
1 E 0.04 Mike
2 C 0.06 David
3 B 0.02 West
4 A 0.04 Tom
5 C 0.05 Max
I am looking for an organized way of doing this. Here is what I attempted so far but am not interested in doing many times over since I have a lot of columns in the real data.
proc sql;
create table newtable1 as
select monotonic() as id2, col1 from
(select col1 from Table1 order by ranuni(0));
quit;
Using the above code you generate separate random columns and then combine them using the new monotonic key.

TSQL, Pivot rows into single columns

Before, I had to solve something similar:
Here was my pivot and flatten for another solution:
I want to do the same thing on the example below but it is slightly different because there are no ranks.
In my previous example, the table looked like this:
LocationID Code Rank
1 123 1
1 124 2
1 138 3
2 999 1
2 888 2
2 938 3
And I was able to use this function to properly get my rows in a single column.
-- Check if tables exist, delete if they do so that you can start fresh.
IF OBJECT_ID('tempdb.dbo.#tbl_Location_Taxonomy_Pivot_Table', 'U') IS NOT NULL
DROP TABLE #tbl_Location_Taxonomy_Pivot_Table;
IF OBJECT_ID('tbl_Location_Taxonomy_NPPES_Flattened', 'U') IS NOT NULL
DROP TABLE tbl_Location_Taxonomy_NPPES_Flattened;
-- Pivot the original table so that you have
SELECT *
INTO #tbl_Location_Taxonomy_Pivot_Table
FROM [MOAD].[dbo].[tbl_Location_Taxonomy_NPPES] tax
PIVOT (MAX(tax.tbl_lkp_Taxonomy_Seq)
FOR tax.Taxonomy_Rank in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15])) AS pvt
-- ORDER BY Location_ID
-- Flatten the tables.
SELECT Location_ID
,max(piv.[1]) as Tax_Seq_1
,max(piv.[2]) as Tax_Seq_2
,max(piv.[3]) as Tax_Seq_3
,max(piv.[4]) as Tax_Seq_4
,max(piv.[5]) as Tax_Seq_5
,max(piv.[6]) as Tax_Seq_6
,max(piv.[7]) as Tax_Seq_7
,max(piv.[8]) as Tax_Seq_8
,max(piv.[9]) as Tax_Seq_9
,max(piv.[10]) as Tax_Seq_10
,max(piv.[11]) as Tax_Seq_11
,max(piv.[12]) as Tax_Seq_12
,max(piv.[13]) as Tax_Seq_13
,max(piv.[14]) as Tax_Seq_14
,max(piv.[15]) as Tax_Seq_15
-- JOIN HERE
INTO tbl_Location_Taxonomy_NPPES_Flattened
FROM #tbl_Location_Taxonomy_Pivot_Table piv
GROUP BY Location_ID
So, then here is the data I would like to work with in this example.
LocationID Foreign Key
2 2
2 670
2 2902
2 5389
3 3
3 722
3 2905
3 5561
So I have some data that is formatted like this:
I have used pivot on data like this before--But the difference was it had a rank also. Is there a way to get my foreign keys to show up in this format using a pivot?
locationID FK1 FK2 FK3 FK4
2 2 670 2902 5389
3 3 722 2905 5561
Another way I'm looking to solve this is like this:
Another way I could look at doing this is I have the values in:
this form as well:
LocationID Address_Seq
2 670, 5389, 2902, 2,
3 722, 5561, 2905, 3
etc
is there anyway I can get this to be the same?
ID Col1 Col2 Col3 Col4
2 670 5389, 2902, 2
This, adding a rank column and reversing the orders, should gives you what you require:
SELECT locationid, [4] col1, [3] col2, [2] col3, [1] col4
FROM
(
SELECT locationid, foreignkey,rank from #Pivot_Table ----- temp table with a rank column
) x
PIVOT (MAX(x.foreignkey)
FOR x.rank in ([4],[3],[2],[1]) ) pvt

How to remove rows that contain NaNs in a specific column from a table in Matlab?

I have a table, which is similar to this one:
Rows = {'Row1';'Row2';'Row3'};
Column1 = [NaN;1;2];
Column2 = [4;5;NaN];
Column3 = [NaN;NaN;4];
Table1 = table(Column1,Column2,Column3,...
'RowNames',Rows)
Table1 =
Column1 Column2 Column3
_______ _______ _______
Row1 NaN 4 NaN
Row2 1 5 NaN
Row3 2 NaN 4
I need to remove rows that have NaN in Column1. All other rows, which may or may not have NaNs in other columns, should stay. So the desired output should look like this:
Table2 =
Column1 Column2 Column3
_______ _______ _______
Row2 1 5 NaN
Row3 2 NaN 4
Of course, this is just a simplified example. The real table is huge and I will be working with one column at a time, which is why I need to selectively remove rows that contain NaN in a specific column.
Is there a way to do it without converting the table into a struct array or something else?
I tried this:
Table2 = Table1(~isnan(Table1.Column1), :)
I make use of the fact that the first column is called Column1.
Note that Table1.Column1 returns:
ans =
NaN
1
2
and so choosing the non-NaN values in this column is achieved by using ~isnan().
The rest is purely indexing into the table. I get the following with the command above:
Table2 =
Column1 Column2 Column3
_______ _______ _______
Row2 1 5 NaN
Row3 2 NaN 4

sybase update based on sequential column

Can any one of you please help me out with the below condition in sybase update?
Table A
ID COL1 COL1_AMT COL2 COL2_AMT COL3 COL3_AMT COL4 COL4_AMT
1 10 100.00 16 50.00 17 80.00 21 90.00
Table B
ID FIN_AMT
1 20
Whenever COL1 or COL2 or COL3 or COL4 equals value as '17' then the corresponding amount column COL1_AMT or COL2_AMT or COL3_AMT or COL4_AMT value should be picked from Table A and get updated in Table B FIN_AMT clumn
Here COL3 is 17, so COL3_AMT value 80 should be added in Table B FIN_AMT
Expected Result in Table B
ID FIN_AMT
1 100 (Already 20 is there, so 80 should be added to this)
Thanks in advance
I can't test on SYBASE, and it's been years, so have mercy on the finer details of the syntax ;)
Something like this ought to do it;
UPDATE TableB
SET TableB.FIN_AMT = TableB.FIN_AMT +
CASE WHEN TableA.COL1 = 17 THEN TableA.COL1_AMT ELSE 0 END +
CASE WHEN TableA.COL2 = 17 THEN TableA.COL2_AMT ELSE 0 END +
CASE WHEN TableA.COL3 = 17 THEN TableA.COL3_AMT ELSE 0 END +
CASE WHEN TableA.COL4 = 17 THEN TableA.COL4_AMT ELSE 0 END
FROM TableB, TableA
WHERE TableB.ID = TableA.ID