Insert value from two tables based on the rows source table - sql

I have two tables A and B each with 1 column for simplicity sake and they are primary Keys.
A contains the values (1,2,3) B contains (1,2,3)
The third table needs to be the insertion of both A and B and has a composite primary key.
Table C (id, src)
If the id is coming from table A I'd like src to be 'A' and if its coming from B then 'B'.
There can be duplicate ID's between the tables but they are not the same item which is why I need to create a composite key based on which table the row is coming from.
I've tried
Insert into C (anID, src)
Select
Case when (A.anID is not null)
then A.anID else B.anID end,
case when (A.anID is not null)
then 'A' else 'B' end
from
A,
B
But my results always end up as just 3 rows (1, A) (2,A) (3,A) When there should be 6 rows (one of each of those with a B)

insert into TableC (id, src)
select ID, 'A' from tableA
union
select ID, 'B' from tableB

Related

How to join a base table with update table with change data?

I have two tables (in real code there is more data columns, this is just an example with single data column)
create table base_t (
id int primary key,
val int;
);
create table update_t (
id int primary key,
c char (1),
val int;
);
In update table, char column can be 'A' (add), 'D' (delete) or 'U' (update). In the result view I need to get rows from update_t when c is 'A' or 'U', when c is 'D' that row should not be present in result and all other rows should be taken from base_t table.
Example
contents of base_t table
1 10
2 20
3 30
contents of update_t table
2 'U' 21
3 'D' NULL
4 'A' 41
expected result
1 10
2 21
4 41
How to create such join in postgresql?
You could use COALESCE() for the U rows, preferring the update_t table over the base_t table. This is assuming that no A records in update_t would exist yet in base_t. Otherwise you could change that COALESCE() over to a case expression like CASE WHEN update_t.c = 'UPDATE' then update_t.id ELSE base_t.id END as id (and similar for val) column.
SELECT COALESCE(update_t.id, base_t.id) as id,
COALESCE(update_t.val, base_t.val) as val
FROM base_t
FULL OUTER JOIN update_t
ON base_t.id = update_t.id
WHERE
update_t.c <> 'D'

Is it possible to insert multiple rows in a table based on a select returning more than one row

Using Oracle SQL, I am trying to insert into table A based on select from table B, but I am not sure how to achieve this, since the select is returning more than one row.
INSERT INTO A
VALUES
(
SELECT id FROM B WHERE status = 'APPROVED',
'Hardcoded-Value'
);
Table B:
id
status
1
APPROVED
2
DECLINED
3
APPROVED
Based on that insert, I want to achieve following:
Table A:
Column A
Column B
1
Hardcoded-Value
3
Hardcoded-Value
You can use a const in the select list
INSERT INTO A(colA, colB)
SELECT id, 'Hardcoded-Value'
FROM B
WHERE status = 'APPROVED'

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

SQL Query to get specific child records

I have a requirement to get child table records based on parent table search criteria but they need to be distinct and output should be like below:
Table A, have three rows. Row one is for generic rules, Row 2 is for specific Category and Row 3 is for Specific Branch, Category and Sub-Category.
Now, my output should consists of the rules which are specific to generic.
Below are the rules for the output:
Input to the query will be Branch, Category and Sub-Category
Each record-set in Table-A is comprised of 03 rows
Row 1 has Branch but Category and Sub-Category as Null
Row 2 has Branch and Category Sub-Category as Null
Row 3 has Branch, Category and Sub-Category.
Each Row in a record-set of Table-A has child records in Table-B
Record with Branch only (Row 1), have generic records and these records can also be child records of Row 2 and Row 3
Record with Branch and Category Sub-Category as Null (Row 2) has child records in Table-B and they are overriding child records of Row 1
Record with Branch, Category and Sub-Category (Row 3) has child records in Table-B and they are overriding child records of Row 1 and Row 2.
All child records of Row 1,2 & 3 will be part of the output but if a child is present in Row 3 then despite if it is present in other Rows output will consists of child record of Row 3
If a child record is present in Row 1 & 2 but not in 3 then output
will have child record of Row 2
if a child record is present in Row 1 but not in Row 2 & 3 then it
will be part of output.
Now,
In the sample output, 'Pay' is present in Row 1,2 and 3 but in the
output we are considering child record of Row 3 as it overrides both Record 1 & 2
'Discount' is present in Record 1 & 3 but output includes child of Row 3
'Items' is not part of Row 1 and Row 2 childs but as it is present in Row 3 so it will be part of output
'Paris' is only part of Row 2 but as it is not overriden by Row 2 so
it is part of output as it is
I have tried following query but it is not giving the required output:
SELECT DISTINCT RULE,
value
FROM siebel.b rxm
WHERE par_row_id IN (SELECT row_id
FROM siebel.a
WHERE ( branch = 'Civil'
AND category = 'C.M.> (Civil)'
AND sub_category IS NULL )
OR ( branch = 'Civil'
AND category = 'C.M. (Civil)'
AND sub_category = 'Pauper' )
OR ( branch = 'Civil'
AND category IS NULL
AND sub_category IS NULL ))
I am using Oracle as RDBMS.
Schema statements:
Create Table A (ROW_ID int, BRANCH varchar(50), CATEGORY varchar(50), SUB_CATEGORY varchar(50))
Create Table B (PAR_ROW_ID int, RULE varchar(50), Value varchar(50))
INSERT INTO A (ROW_ID, BRANCH)
VALUES (1,'Civil')
INSERT INTO A (ROW_ID, BRANCH, CATEGORY)
VALUES (2,'Civil','C.M. (Civil)')
INSERT INTO A (ROW_ID, BRANCH, CATEGORY, SUB_CATEGORY)
VALUES (3,'Civil','C.M. (Civil)','Pauper')
INSERT INTO B (PAR_ROW_ID, RULE, VALUE)
VALUES (1,'Pay','10')
INSERT INTO B (PAR_ROW_ID, RULE, VALUE)
VALUES (1','Days','25')
INSERT INTO B (PAR_ROW_ID, RULE, VALUE)
VALUES (1,'Discount','20')
INSERT INTO B (PAR_ROW_ID, RULE, VALUE)
VALUES (2,'Pairs','5')
INSERT INTO B (PAR_ROW_ID, RULE, VALUE)
VALUES (2,'Pay','30')
INSERT INTO B (PAR_ROW_ID, RULE, VALUE)
VALUES (3,'Pay','15')
INSERT INTO B (PAR_ROW_ID, RULE, VALUE)
VALUES (3,'Discount','20')
INSERT INTO B (PAR_ROW_ID, RULE, VALUE)
VALUES (3,'items','30')
SELECT MAX( par_row_id ) AS par_row_id,
rule,
MAX( value ) KEEP ( DENSE_RANK LAST OVER ORDER BY par_row_id ) AS value
FROM table_b
GROUP BY rule
Or:
SELECT par_row_id,
rule,
value
FROM (
SELECT b.*,
ROW_NUMBER() OVER ( PARTITION BY rule ORDER BY par_row_id DESC ) AS rn
FROM table_b b
)
WHERE rn = 1;

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 ...)