How to add the sum of the 'sum of the two tables?' - sql

I created Tables T1 and T2. I managed to add their sum, but I can't seem to add the sum of the T1 and T2 together (10+12 = 22) by adding a sum() in the beginning of the code.
CREATE TABLE T1(kW int)
CREATE TABLE T2(kW int)
SELECT T1C1, T2C1
FROM
( select SUM(Kw) T1C1 FROM T1 ) A
CROSS JOIN
( select SUM(Kw) T2C1 FROM T2 ) B
BEGIN
INSERT INTO T1 VALUES ('4');
INSERT INTO T1 VALUES ('1');
INSERT INTO T1 VALUES ('5');
INSERT INTO T2 VALUES ('7');
INSERT INTO T2 VALUES ('2');
INSERT INTO T2 VALUES ('3');
END

You should use union all to create a "virtual" column from the columns in the two tables:
SELECT SUM(kw)
FROM (SELECT kw FROM t1
UNION ALL
SELECT kw FROM t2) t

Try using a stored procedure. Doing so you will be able to store the sum of each table on a separated variable and then return the SUM of those two variables.
You can also make a UNION ALL and SUM the column you want. Notice that you should a UNION ALL to avoid eliminating duplicated values.

Another approach is to add the results of the two subqueries directly, using the built-in dummy table dual as the main driving table:
select ( select SUM(Kw) FROM T1 )
+ ( select SUM(Kw) FROM T2 ) as total
from dual;
TOTAL
----------
22

Related

Way to randomly update a set of values using another table as a collection of random values without using a loop?

I have a table with a column that contains some values. I want to replace all the existing values with random values from another table (but only the existing ones - so WHERE COL1 IS NOT NULL). There is no way to correlate the two tables. Each of the random values needs to be different (well... unless they are randomly the same, in which case it's fine).
For example:
CREATE TABLE T1 (ID NUMBER(11,0), COL1 VARCHAR2(20));
CREATE TABLE T2 (COL2 VARCHAR2(20));
INSERT INTO T1 VALUES (1, NULL);
INSERT INTO T1 VALUES (54, NULL);
INSERT INTO T1 VALUES (941, 'Some text');
INSERT INTO T1 VALUES (251, NULL);
INSERT INTO T1 VALUES (352, 'Some other text');
INSERT INTO T1 VALUES (354, NULL);
INSERT INTO T2 VALUES ('Val1');
INSERT INTO T2 VALUES ('Val2');
INSERT INTO T2 VALUES ('Val3');
INSERT INTO T2 VALUES ('Val4');
INSERT INTO T2 VALUES ('Val5');
INSERT INTO T2 VALUES ('Val6');
INSERT INTO T2 VALUES ('Val7');
I have tried a few things and have searched this site for answers. The answers I've found seem to require that there is some correlation between the two tables. A lot of the examples are for SQL Server. I've tried a few out anyway, but I can't seem to get a MERGE or CROSS APPLY approach to work (I appreciate this is most likely my failure...).
The only solution I have that actually works at the moment is the following:
BEGIN
FOR X IN (
SELECT ID FROM T1 WHERE COL1 IS NOT NULL
)
LOOP
UPDATE T1 SET COL1 = (
SELECT COL2 FROM (
SELECT COL2 FROM T2 ORDER BY SYS_GUID()
) WHERE ROWNUM = 1
)
WHERE T1.ID = X.ID;
END LOOP;
END;
/
This produces a (desired) result of:
SELECT * FROM T1;
ID COL1
---------------------------
1
54
941 Val3
251
352 Val7
354
(COL1 values are both random each time I run the loop).
... But I know there must be a set-based way to achieve this... right?
You could do it with a MERGE statement.
merge into t1
using ( select a1.id
, a2.col2
from ( select id
, row_number() over (order by dbms_random.value) rn
from t1
where col1 is not null ) a1
join ( select col2
, row_number() over (order by dbms_random.value) rn
from t2) a2
on a1.rn = a2.rn
) q
on ( q.id = t1.id)
when matched then
update set t1.col1 = q.col2
/
The USING query is a little unorthodox. There are two subqueries, one for each table, which generate analytic row_number() in a random order (this is tidier than using rownum. The two subqueries are joined on the random row numbers which gives a random combination of T1.ID and T2.COL_2. After that, it's a straightforward MERGE.
You can create a FUNCTION named GET_RANDOM_VALUE
create or replace FUNCTION GET_RANDOM_VALUE
RETURN VARCHAR2 AS
sValue VARCHAR2(100) := '?';
BEGIN
select col2 INTO sValue
from t2
order by dbms_random.value
fetch first 1 rows only;
RETURN sValue;
END GET_RANDOM_VALUE;
and the UPDATE command can be
UPDATE t1
SET col1 = GET_RANDOM_VALUE()
WHERE col1 IS NOT NULL;
Normally, I avoid using SELECT in function, but in this case, I found this solution more readable and more easy to understand.

Sum union values

I am trying to sum two values across a UNION. Like:
SELECT
sum(target_value) FROM table
UNION ALL
SELECT
sum(target_value) FROM table_2
But rather than getting the 2 sum values, I want them to also be summed.
How should I go about doing this?
You can try using this in a subquery and calculate at the outer query. Ensure you use UNION ALL to evade the duplicate check
SELECT SUM(a) target_value
FROM
(SELECT
sum(target_value) a FROM table
UNION ALL
SELECT
sum(target_value) a FROM table_2) ;
You can use the WITH clause to do this:
WITH CTE AS (SELECT SUM(target_value) as FirstSum
FROM table
UNION
SELECT
SUM(target_value) as FirstSum
FROM table_2)
SELECT SUM(FirstSum) AS TotalSum FROM CTE
Please see the example below:
create table #temp (x int)
create table #temp2 (x2 int)
insert into #temp values (2)
insert into #temp values (3)
insert into #temp2 values (5)
insert into #temp2 values (6)
select t.col1,t.col2,t.col1+t.col2 as Total
from (
SELECT (select sum(x) FROM #temp) as col1,
(select sum(x2) FROM #temp2) as col2
) t

Counting repeated data

I'm trying to get maximum repeat of integer in table I tried many ways but could not make it work. The result I'm looking for is as:
"james";"108"
As this 108 when I concat of two fields loca+locb repeated two times but others did not I try below sqlfiddle link with sample table structure and the query I tried... sqlfiddle link
Query I tried is :
select * from (
select name,CONCAT(loca,locb),loca,locb
, row_number() over (partition by CONCAT(loca,locb) order by CONCAT(loca,locb) ) as att
from Table1
) tt
where att=1
please click here so you can see complete sample table and query I tried.
Edite: adding complete table structure and data:
CREATE TABLE Table1
(name varchar(50),loca int,locb int)
;
insert into Table1 values ('james',100,2);
insert into Table1 values ('james',100,3);
insert into Table1 values ('james',10,8);
insert into Table1 values ('james',10,8);
insert into Table1 values ('james',10,7);
insert into Table1 values ('james',10,6);
insert into Table1 values ('james',0,7);
insert into Table1 values ('james',10,0);
insert into Table1 values ('james',10);
insert into Table1 values ('james',10);
and what I'm looking for is to get (james,108) as that value is repeated two time in entire data, there is repetion of (james,10) but that have null value of loca so Zero value and Null value is to be ignored only those to be considered that have value in both(loca,locb).
SQL Fiddle
select distinct on (name) *
from (
select name, loca, locb, count(*) as total
from Table1
where loca is not null and locb is not null
group by 1,2,3
) s
order by name, total desc
WITH concat AS (
-- get concat values
SELECT name,concat(loca,locb) as merged
FROM table1 t1
WHERE t1.locb NOTNULL
AND t1.loca NOTNULL
), concat_count AS (
-- calculate count for concat values
SELECT name,merged,count(*) OVER (PARTITION BY name,merged) as merged_count
FROM concat
)
SELECT cc.name,cc.merged
FROM concat_count cc
WHERE cc.merged_count = (SELECT max(merged_count) FROM concat_count)
GROUP BY cc.name,cc.merged;
SqlFiddleDemo
select name,
newvalue
from (
select name,
CONCAT(loca,locb) newvalue,
COUNT(CONCAT(loca,locb)) as total,
row_number() over (order by COUNT(CONCAT(loca,locb)) desc) as att
from Table1
where loca is not null
and locb is not null
GROUP BY name, CONCAT(loca,locb)
) tt
where att=1

How to get Distinct Records from Temp table to Sql one database table

i have temp table named "#Test" which have columns "T1", "T2", "T3" with data.
I have database table named "TestTbl" which have same columns.
I want to insert data from #Test table to TestTbl with distinct records of T1 column.
Do you have any idea how to insert distinct records in TestTbl table?
You Can Try Like this....
INSERT INTO TestTbl (T1,T2,T3) SELECT T1,T2,T3 from
(
Select Row_Number() over(Partition By T1 order By T1) as row,* from #Test
) a
where a.row=1;
INSERT INTO TestTbl (T1,T2,T3)
SELECT Distinct(T1), T2, T3 FROM #Test
EDIT After further explanation
INSERT INTO TestTbl
( T1 ,
T2 ,
T3
)
SELECT T1 ,
T2 ,
T3
FROM ( SELECT T1 ,
T2 ,
T3 ,
Row_Number() OVER ( PARTITION BY T1 ORDER BY T1) AS record
-- you need to select the relevant clause here for the order
-- do you want first or latest record?
FROM #Test
) tmp
WHERE tmp.record = 1 ;
Get distinct records
SELECT DISTINCT column_name,column_name
FROM table_name
Insert records
INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...)

Insert lost data to the table

I have two tables, which have two common column 'StationID'.
Create table t1(ID int, StationID bigint)
insert into t1 values
(0,1111),
(1,2222),
(2,34),
(3,456209),
(56,78979879),
(512,546)
go
Create table t2(StationID bigint, Descr varchar(50))
insert into t2 values
(-1,'test-1'),
(0,'test0'),
(1,'test1'),
(2,'test2'),
(5001,'dummy'),
(5002,'dummy'),
(6001,'dummy')
go
Now we notice that not every t1.StationID is in t2.StationID. Run the script can prove it.
select distinct StationID from t1 as A
where not exists
(select * from t2 as B where B.StationID =A.StationID)
The result is:
StationID
34
546
1111
2222
456209
78979879
Now I want to fill t2 with the lost StationID above, the column Descr can be any dummy data.
My real case has thousands records, how to use script to implement it?
insert into t2 (StationID, Descr)
select distinct StationID, 'dummy'
from t1 as A
where not exists
(select * from t2 as B where B.StationID =A.StationID)
INSERT INTO
t2
SELECT DISTINCT
stationid, 'dummy'
FROM
t1
WHERE
stationid NOT IN (SELECT stationid FROM t2)
(As an alternative to the others).