Update sqlite table with non-null values from another table - database

I have two sqlite tables, both with the same column layout. I would like to merge the two tables (or update table 1), taking values from table 2 if they are not null, otherwise, taking them from table 1. Is there a better way of doing this this short of an UPDATE with multiple case clauses (similar to the approach in SQLITE UPDATE field IF NULL from another table)? The tables have a large number of columns which would make such a statement quite long.
table 1
|-------+-------+--------+----+--------|
| id | col1 | col2 | .. | col100 |
|-------+-------+--------+----+--------|
| 2346a | apple | red | | WA |
| d27d7 | pear | green | | VA |
| 568ba | lemon | yellow | | CA |
| 9896f | grape | purple | | CA |
| 1b7da | peach | pink | | CA |
|-------+-------+--------+----+--------|
table 2
|-------+-------+--------+----+--------|
| id | col1 | col2 | .. | col100 |
|-------+-------+--------+----+--------|
| 2346a | null | green | | null |
| 1b7da | null | null | | GA |
| 9896f | plum | null | | null |
|-------+-------+--------+----+--------|
desired result
|-------+-------+--------+----+--------|
| id | col1 | col2 | .. | col100 |
|-------+-------+--------+----+--------|
| 2346a | apple | green | | WA |
| d27d7 | pear | green | | VA |
| 568ba | lemon | yellow | | CA |
| 9896f | plum | purple | | CA |
| 1b7da | peach | pink | | GA |
|-------+-------+--------+----+--------|

You can bring table2 with a left join and prioritize non-null values from table2 using coalesce():
select
t1.id,
coalesce(t2.col1, t1.col1) col1,
coalesce(t2.col2, t1.col2) col2,
...
coalesce(t2.col100, t1.col100) col100
from table1 t1
left join table2 t2 on t2.id = t1.id

You can use ROW VALUES to update Table1:
update Table1
set (col1, col2, col100) = (
select
coalesce(t2.col1, Table1.col1),
coalesce(t2.col2, Table1.col2),
................................
coalesce(t2.col100, Table1.col100)
from Table2 t2
where t2.id = Table1.id
)
where exists (select 1 from Table2 t2 where t2.id = Table1.id);
See the demo.
Results:
| id | col1 | col2 | col100 |
| ----- | ----- | ------ | ------ |
| 2346a | apple | green | WA |
| d27d7 | pear | green | VA |
| 568ba | lemon | yellow | CA |
| 9896f | plum | purple | CA |
| 1b7da | peach | pink | GA |

Related

Get row with highest number from one column and join rows with same value from another column

I have a large table with a similar structure as follows...
| version | col1 | col2 |
| ------- | ---- | ---- |
| 1 | val1 | 3243 |
| 2 | val1 | 7542 |
| 3 | val1 | 7322 |
| 4 | val1 | 8632 |
| 1 | val2 | 1948 |
| 2 | val2 | 0491 |
| 1 | val3 | 6282 |
| 1 | val4 | 9283 |
| 2 | val4 | 8272 |
| 3 | val4 | 0029 |
| 4 | val4 | 1279 |
I am trying to find a row with the highest number value from version and display all the rows with the same value from col1 as the first row. My desired output would be as follows...
| version | col1 | col2 | | version | col1 | col2 |
| ------- | ---- | ---- | | ------- | ---- | ---- |
| 1 | val1 | 3243 | | 1 | val4 | 9283 |
| 2 | val1 | 7542 | OR | 2 | val4 | 8272 |
| 3 | val1 | 7322 | | 3 | val4 | 0029 |
| 4 | val1 | 8632 | | 4 | val4 | 1279 |
The final set of rows aren't important. It's only important to choose one row that would contain the highest version number and be joined with other rows containing the same col1 value.
My idea was to find the first row using:
SELECT a.* FROM (SELECT TOP(1) * FROM table ORDER BY version DESC) a
and join the other rows but I don't know how to go about it.
Can anyone please help me write a query that would achieve one of these results?
Ok, I figured it out...
SELECT a.* FROM table a
RIGHT JOIN
(SELECT TOP(1) * FROM table ORDER BY version DESC) b
ON a.col1 = b.col1
ORDER BY a.version

Results of join listed in rows vs additional columns?

I have 2 tables, with the same exact fields and fields names. i am trying to inner join them but im having some difficulty determining how i can get my results in my desired format.
I know i can do select a.customer, a.id, a.date, a.line, a.product, b.customer, b.id, b.date, b.line, b.product but instead of having my A data and B data on the same row, id like for them to be on seperate rows.
I have 2 tables, with the same exact fields and fields names, i am trying to inner join them so that unique line becomes a row.
Table A:
|customer| id | Date | line | Product|
|--------|-----|---------|------|--------|
| 445678 | 123 | 1/1/22 | 10 | 88975 |
| 853652 | 456 | 1/10/22 | 5 | 55876 |
| 845689 | 789 | 1/25/22 | 1 | 45587 |
TABLE B:
|customer| id | Date | line | Product|
|--------|-----|---------|------|--------|
| 445678 | 489 | 1/1/22 | 1 | 87574 |
| 853652 | 853 | 1/10/22 | 12 | 45678 |
| 587435 | 157 | 2/12/22 | 3 | 25896 |
DESIRED RESULTS:
|customer| id | Date | line | Product|
|--------|-----|---------|------|--------|
| 445678 | 123 | 1/1/22 | 10 | 88975 |
| 445678 | 489 | 1/1/22 | 1 | 87574 |
| 853652 | 456 | 1/10/22 | 5 | 55876 |
| 853652 | 853 | 1/10/22 | 12 | 45678 |
my query:
select a.customer, a.id, a.date, a.line, a.product
from data1 a
inner join data2 b
on a.date = b.date
and a.customer = b.customer

MySQLServer: Check if conditions exist in group, then label entire group

My goal is to add another column to an existing table, to see if the value/conditions exists in a group and appropriately labeling the entire group if it is present or not.
If a Team has one project with a budget >= 20M or Actual_Spend >=2.5M I want to label the Team and all it's projects as Table 1 in the Category column. Irrespective if the other projects within the same Team fit this criteria.
I will provide a SQL fiddle link w/ my solution: http://sqlfiddle.com/#!18/3ddaf/12/0
I'm ending up with two extra columns of "Team" and "Category" and not sure how they're ending up there.
Below is the end result I'm looking for. I'm open to better solutions than the one I provided.
Thank you for your time
| Team | ProjectID | Budget | Actual_Spend | State | Category |
|------|-----------|----------|--------------|------------|----------|
| Cyan | 2 | NULL | NULL | Utah | Table 1 |
| Blue | 1 | NULL | 3000000 | California | Table 1 |
| Cyan | 1 | 20000000 | 1000000 | Utah | Table 1 |
| Blue | 2 | 22000000 | NULL | California | Table 1 |
| Red | 1 | 7000000 | 1000000 | Washington | Table 2 |
| Red | 2 | 19999000 | 2490000 | Oregon | Table 2 |
| Gray | 1 | 19000000 | 2500000 | Utah | Table 1 |
| Gray | 1 | 10000000 | 500000 | Utah | Table 1 |
Providing code to create the dataset:
Create Table Source_Data
(
Team varchar(50),
ProjectID INT,
BUDGET INT,
Actual_Spend INT,
State varchar(max),
)
INSERT INTO Source_Data
VALUES
('Blue',1,NULL,3000000,'California'),
('Green',1,20000000,1000000,'Utah'),
('Blue',2,22000000,NULL,'California'),
('Green',2,NULL,NULL,'Utah'),
('Red',1,7000000,1000000,'Washington'),
('Red',2,19999000,2490000,'Oregon'),
('Yellow',1,19000000,2500000,'Utah'),
('Yellow',1,10000000,500000,'Utah');
I think that you are looking for window functions:
select
s.*,
min(case when Budget>=20000000 or Actual_Spend>=2500000 then 'Table1' else 'Table2' end)
over(partition by team) Category
from Source_Data s
If any of the records having the same team satisfies condition Budget>=20000000 or Actual_Spend>=2500000, the new column yields Table1, else it produces Table2.
Demo on DB Fiddle:
Team | ProjectID | Budget | Actual_Spend | State | Category
:--- | --------: | -------: | -----------: | :--------- | :-------
Blue | 2 | 22000000 | null | California | Table1
Blue | 1 | null | 3000000 | California | Table1
Cyan | 1 | 20000000 | 1000000 | Utah | Table1
Cyan | 2 | null | null | Utah | Table1
Gray | 1 | 19000000 | 2500000 | Utah | Table1
Gray | 1 | 10000000 | 500000 | Utah | Table1
Red | 1 | 7000000 | 1000000 | Washington | Table2
Red | 2 | 19999000 | 2490000 | Oregon | Table2

How to display "The Many" of a One-to-Many on One Line

I was provided 2 files, as two tables: 'VoterData' and 'VoterHistory' - What is the best way to accomplish my expected display?
EXPECTED DISPLAY
ID | First Name | Last Name | Election1 | Election2 | Election3
--------+------------+-------------+-----------+-----------+----------
2155077 | Camille | Bocchicchio | 2016June7 | 2016Nov8 | 2018June5
2155079 | Manabu | Lonny | 2016June7 | 2016Nov8 |
2155083 | Scott | Bosomworth | 2016June7 | | 2018June5
ONE- 'VoterData'
lVoterUniqueID | szNameFirst | szNameLast
---------------+-------------+------------
2155077 | Camille | Bocchicchio
2155079 | Manabu | Lonny
2155083 | Scott | Bosomworth
MANY- 'VoterHistory'
lVoterUniqueID | sElectionAbbr
---------------+---------------
2155077 | 2016June7
2155077 | 2016Nov8
2155077 | 2018June5
2155079 | 2016June7
2155079 | 2016Nov8
2155083 | 2016June7
2155083 | 2018June5
Using Crosstab query
TRANSFORM First(H.sElectionAbbr) AS FirstOfsElectionAbbr
SELECT H.lVoterUniqueID AS ID, D.szNameFirst AS [First Name], D.szNameLast AS [Last Name]
FROM VoterData AS D INNER JOIN VoterHistory AS H ON D.lVoterUniqueID = H.lVoterUniqueID
GROUP BY H.lVoterUniqueID, D.szNameFirst, D.szNameLast
PIVOT H.sElectionAbbr;

I made stored procedure, but I don't know what to put on my WHERE clause to filter the null column

I made a INNER JOIN in stored procedure, but I don't know what to put to my WHERE clause to filter those column with null values and only shows those rows who has not null on a particular column.
CREATE PROCEDURE [dbo].[25]
#param1 int
AS
SELECT c.Name, c.Age, c2.Name, c2.Country
FROM Cus C
INNER JOIN Cus2 C2 ON c.id = c2.id
WHERE c2.country is not null and c2.id = #param1
Order by c2.Country
RETURN 0
ID 1
+-----+----+---------+---------+
| QID | ID | Name | Country |
+-----+----+---------+---------+
| 1 | 1 | Null | PH |
| 2 | 1 | Null | CN |
| 3 | 1 | Japhet | USA |
| 4 | 1 | Abegail | UK |
| 5 | 1 | Norlee | Ger |
+-----+----+---------+---------+
ID 2
+-----+----+----------+---------+
| QID | ID | Name | Country |
+-----+----+----------+---------+
| 1 | 2 | Null | PH |
| 2 | 2 | Null | CN |
| 3 | 2 | Reynaldo | USA |
| 4 | 2 | Abegail | UK |
| 5 | 2 | Norlee | Ger |
+-----+----+----------+---------+
ID 3
+-----+----+----------+---------+
| QID | ID | Name | Country |
+-----+----+----------+---------+
| 1 | 3 | Gab | PH |
| 2 | 3 | Null | CN |
| 3 | 3 | Reynaldo | USA |
| 4 | 3 | Abegail | UK |
| 5 | 3 | Norlee | Ger |
+-----+----+----------+---------+
I want when I choose any of the user in the C Table it will display the C child table data and remove the null name rows and remain the rows with not null name column.
Desired Result:
C Table (Parent)
+----+---------+-----+
| ID | Name | Age |
+----+---------+-----+
| 3 | Abegail | 31 |
+----+---------+-----+
C2 Table (Child)
+-----+----+----------+---------+
| QID | ID | Name | Country |
+-----+----+----------+---------+
| 1 | 3 | Gab | PH |
| 3 | 3 | Reynaldo | USA |
| 4 | 3 | Abegail | UK |
| 5 | 3 | Norlee | Ger |
+-----+----+----------+---------+
WHERE column IS NOT NULL is the syntax to filter out NULL values.
Solution 1: test not null value
Example:
WHERE yourcolumn IS NOT NULL
Solution 2: test comparaison value in your where clause (comparaison substract null values)
Examples:
WHERE yourcolumn = value
WHERE yourcolumn <> value
WHERE yourcolumn in ( value)
WHERE yourcolumn not in ( value)
WHERE yourcolumn between value1 and value2
WHERE yourcolumn not between value1 and value2

Resources