insert 2 column primary key - sql

I want to insert 2 column primary key ( X and Y) in table A. X is inserted from table B and Y inserted from a fixed value..
INSERT INTO A
(X,Y)
SELECT W
FROM table B, '1'

You were close:
INSERT INTO A
(X,Y)
SELECT W, '1'
FROM table B
Define the static value -- in this example, the text "1" -- as a column in the SELECT clause.
Only one FROM clause per SELECT clause. Additional SELECTs need to be within brackets/parenthesis...

Related

Count non-null values from multiple columns at once without manual entry in SQL

I have a SQL table with about 50 columns, the first represents unique users and the other columns represent categories which are scored 1-10.
Here is an idea of what I'm working with
user
a
b
c
abc
5
null
null
xyz
null
6
null
I am interested in counting the number of non-null values per column.
Currently, my queries are:
SELECT col_name, COUNT(col_name) AS count
FROM table
WHERE col_name IS NOT NULL
Is there a way to count non-null values for each column in one query, without having to manually enter each column name?
The desired output would be:
column
count
a
1
b
1
c
0
Consider below approach (no knowledge of column names is required at all - with exception of user)
select column, countif(value != 'null') nulls_count
from your_table t,
unnest(array(
select as struct trim(arr[offset(0)], '"') column, trim(arr[offset(1)], '"') value
from unnest(split(trim(to_json_string(t), '{}'))) kv,
unnest([struct(split(kv, ':') as arr)])
where trim(arr[offset(0)], '"') != 'user'
)) rec
group by column
if applied to sample data in your question - output is
I didn't do this in big-query but instead in SQL Server, however big query has the concept of unpivot as well. Basically you're trying to transpose your columns to rows and then do a simple aggregate of the columns to see how many records have data in each column. My example is below and should work in big query without much or any tweaking.
Here is the table I created:
CREATE TABLE example(
user_name char(3),
a integer,
b integer,
c integer
);
INSERT INTO example(user_name, a, b, c)
VALUES('abc', 5, null, null);
INSERT INTO example(user_name, a, b, c)
VALUES('xyz', null, 6, null);
INSERT INTO example(user_name, a, b, c)
VALUES('tst', 3, 6, 1);
And here is the UNPIVOT I did:
select count(*) as amount, col
from
(select user_name, a, b, c from example) e
unpivot
(blah for col in (a, b, c)
) as unpvt
group by col
Here's example of the output (note, I added an extra record in the table to make sure it was working properly):
Again, the syntax may be slightly different in BigQuery but I think thould get you most of the way there.
Here's a link to my db-fiddle - https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=deaa0e92a4ef1de7d4801e458652816b

How to update each row of a column from one table with a list of values from another?

I have a table A with records with 1 column only that are random alphanumerical characters. That table has say 10 rows.
I have another table B with 10 rows also that I want to take a value from a row from table A and apply it to a row in table B.
So basically, take a value from Table A and assign it to a row in table B. Preferably, take the value from table A row 1 and assign it to table B row 1, etc...
I am using SQL Server.
We can take any value from table B to assign to a row in table A. We just can't re-use a value from table B.
Here are the 2 tables in it's simplest form for this example:
CREATE TableA ([Value] NVARCHAR(50))
CREATE TableB ([Value] NVARCHAR(50))
Given the following table structure:
CREATE TABLE #tempA (stringEntry NVARCHAR(50));
INSERT INTO #tempA (stringEntry) VALUES ('abcd'), ('efgh'), ('ijkl');
CREATE TABLE #tempB (stringEntry NVARCHAR(50));
INSERT INTO #tempB (stringEntry) VALUES ('mnop'), ('qrst'), ('uvwx');
You can do the following:
SELECT
ROW_NUMBER() OVER(ORDER BY #tempA.stringEntry) AS RowNumber,
#tempA.stringEntry AS entryA
INTO #tempA2
FROM #tempA;
SELECT
ROW_NUMBER() OVER(ORDER BY #tempB.stringEntry) AS RowNumber,
#tempB.stringEntry AS entryB
INTO #tempB2
FROM #tempB;
UPDATE #tempA
SET #tempA.stringEntry = #tempB2.entryB
FROM #tempA
INNER JOIN #tempA2 ON #tempA.stringEntry = #tempA2.entryA
INNER JOIN #tempB2 ON #tempB2.RowNumber = #tempA2.RowNumber;
This assumes that you have equal number of rows in each table, as you indicated, or are okay with having the "excess" entries in your first table not being updated.

Creating temp table which duplicates values of one column but changes the value of another colum

I have table Z with 2 columns:
I need to add 2 more types: C and D where the Total value is equal to A and B respectively and make a new temp X table like this:
I want to use the logic where the Total value of C is equal to A and the total Value of D is equal to B instead of using the insert into function where I state the value of C as 12 and D as 15 because the original Total value for table Z will keep changing; hence, I don't want to manually insert the new values every time. I also don't have the authority to create new tables in the database so table Z is derived from a select statement and I can't create new permanent tables. So I am hoping to create a temp table of table Z.
Thank you for your help!
One method uses union all. I'm not sure if aggregation is needed, but this calculates the total for all As and Bs:
insert into x (type, total)
select 'C', sum(total)
from x
where type = 'A'
union all
select 'D', sum(total)
from x
where type = 'B';
Or if aggregation is not necessary, a case expression allows a single scan of the data:
insert into x (type, total)
select (case when type = 'A' then 'C' else 'D' end), total
from x
where type in ('A', 'B');

Insert into history table - oracle SQL - PL/SQL

I have a table X and and table Y. Table Y is history table. Whenever a record is inserted or updated or deleted in table X it will get inserted in history table Y. Now I am trying to update the history table with the missing records. For this I wrote a minus query to get the differences. I have to insert all these records into history table. I tried to use 'merge' and other forms of insert statements but not able to get exact output.
EX:
Table X
A B C
EMP NO EMP NAME EMP ADD
Table Y
A B C D E F
EMP NO EMP NAME EMP ADD st dt end dt indicator
While inserting I have to use three additional columns as values which have dates and indicator as table X does not have these columns. Please help me out to write an insert for this history table when there is a difference.
There are several different ways to do this. One is to use not exists:
insert into tabley (Y, A, B, C, EMPNO, EMPNAME, EMPADD)
select X, A, B, C, EMPNO, EMPNAME, EMPADD
from tablex x
where not exists (
select 1
from tabley
where tabley.y = x.X
)
Just make sure you define the same number of columns for the insert as you do for the select. Depending on where the other fields come from, you may be able to supply them as well -- depends on your sample data and expected results.
Btw, this assumes the x values in tablex are your unique identifiers. If not, you'll need to update the where criteria above.
You will need to create the data for the missing columns in table x (formatted for improved readability):
insert into tabley(empno
, empname
, empadd
, st_dt
, end_dt
, indicator)
select empno
, empname
, empadd
, to_date(some_date_you_create)
, to_date(another_date_or null)
, (whatever_starting_indicator_value_is_allowed)
from tablex x
where not exists (select 1
from tabley y
where x.empno = y.empno);
Essentially, you have to create the missing values with some arbitrary thing you decide on. This also assumes that empno is a distinct key value.

sql - select row id based on two column values in same row as id

Using a SELECT, I want to find the row ID of 3 columns (each value is unique/dissimilar and is populated by separate tables.) Only the ID is auto incremented.
I have a middle table I reference that has 3 values: ID, A, B.
A is based on data from another table.
B is based on data from another table.
How can I select the row ID when I only know the value of A and B, and A and B are not the same value?
Do you mean that columns A and B are foreign keys?
Does this work?
SELECT [ID]
FROM tbl
WHERE A = #a AND B = #b
SELECT ID FROM table WHERE A=value1 and B=value2
It's not very clear. Do you mean this:
SELECT ID
FROM middletable
WHERE A = knownA
AND B = knownB
Or this?
SELECT ID
FROM middletable
WHERE A = knownA
AND B <> A
Or perhaps "I know A" means you have a list of values for A, which come from another table?
SELECT ID
FROM middletable
WHERE A IN
( SELECT otherA FROM otherTable ...)
AND B IN
( SELECT otherB FROM anotherTable ...)