multiply values from 2 tables sql server - sql

I have two tables and want to multiply values together if they satisfy a condition. I looked at Multiply 2 values from 2 different tables
to no avail
I want to multiply all values in #Temp1 with the corresponding value from #Temp2 where the month from #Temp1 is the same as the month from #Temp2.
I tried
select costs * ratio as Value
from #Temp1, #Temp2
where #Temp2.ratio = cast(SUBSTRING(#Temp1.date,5,2)as int)
to no avail
I want:
costs date ratio
234.33 20170103 23.433
56.65 20170203 11.33
I am working with SQL Server2012, and any help will be appreciated.
Table #Temp1
234.33 20170103
56.65 20170203
Table #Temp2
0.1 1
0.2 2
0.3 3
IF OBJECT_ID ('tempdb..#Temp1') IS NOT NULL
DROP TABLE #Temp1
IF OBJECT_ID ('tempdb..#Temp2') IS NOT NULL
DROP TABLE #Temp2
create table #Temp1
(
costs float,
date Varchar(50)
)
create table #Temp2
(
ratio float,
month int
)
insert into #Temp1
values (234.33, 20170103)
insert into #Temp1
values (56.65, 20170203)
insert into #Temp2
values (.1,01)
insert into #Temp2
values (.2,02)
insert into #Temp2
values (.3,03)
select ratio from #Temp2 where month=3
select cast(SUBSTRING(date,5,2)as int) as month from #Temp1
select * from #Temp1
select * from #Temp2
select costs * ratio as Value
from #Temp1, #Temp2
where #Temp2.ratio = cast(SUBSTRING(#Temp1.date,5,2)as int)

If I understood correctly, it should be :
where #Temp2.month = cast(SUBSTRING(#Temp1.date,5,2)as int)
Instead :
where #Temp2.ratio = cast(SUBSTRING(#Temp1.date,5,2)as int)

I am a bonehead.
it was a typo:
select *, costs * ratio as Value
from #Temp1, #Temp2
where #Temp2.month = cast(SUBSTRING(#Temp1.date,5,2)as int)
works

Try now and give me remarks.
select month , case when #Temp2.month = cast(SUBSTRING(#Temp1.date,5,2)as int) then costs * ratio else null End as Value
from #Temp1
left join #Temp2 on
#Temp2.month = cast(SUBSTRING(#Temp1.date,5,2)as int)

It was minor typo but the panic one, used ratio instead of date in the comparison
Above change will resolve your problem but still you can follow the few other major things
1.Avoid using keywords as column names as date, month
2.You don't need to cast the value in INT because it's implicitly converted before comparison
select t1.costs,
t1.date,
(costs * ratio) as ratio
from #Temp1 t1
INNER JOIN #Temp2 t2 ON t2.month = SUBSTRING(t1.date,5,2)

Related

How to Split one row data to many rows

I need to insert the following Data in table A and to make trigger for the inserted date to split in many rows in table B depend on the data in table A
For Example
Table A have the following Data :
Name Start_Date Totals No_Payment Diff_Date
Dave 1/10/17 10000 5 7
the Data to split into Table A for 5 Row depend on No_Payment column and add 7 days to Start_Date based on Diff_Date column .
Thank you
Not sure about your requirement, re explain it.
declare #t table(Name varchar(50), Start_Date date,Totals int, No_Payment int,Diff_Date int)
insert into #t values ('Dave','1/10/17', 10000 , 5, 7)
create table #num(num int)
insert into #num
select ROW_NUMBER()over(order by number) from master..spt_values
--select * from #num
SELECT *
,NewStartDate
,DATEADD(day, t.Diff_Date, NewStartDate) RequireStartDate
FROM #t t
CROSS APPLY (
SELECT DATEADD(day, num, t.Start_Date) NewStartDate
FROM #num
WHERE num <= t.No_Payment
) c
drop table #num
Here is the simplest solution.
declare #t table (Name varchar(10), Start_Date datetime,Totals int,No_Payment int,Diff_Date int)
insert #t
values ('Dave','1/10/17',10000,5,7),
('JOHN','2/10/17',10001,2,5),
('Fotos','3/10/17',10002,3,4),
('Manchi','7/10/17',10003,4,6)
select * from #t;
--Insert into <YOUR TABLE>
select t.Name
, DATEADD(day,t.Diff_Date, t.Start_Date) as Start_Date
,t.Totals
,t.No_Payment
,t.Diff_Date
from #t t
join master..spt_values n
on n.type = 'P'
and n.number < convert(int,No_Payment,1)
It's working in SQLServer-2014.

SQL different between sum(c1)*sum(c2) and sum(c1*c2)

In SQL language what's the different results or performence between
sum(c1) * sum(c2) from t
and
sum(c1 * c2) from t
I use it to sum sales totals
select sum(price * quantity) as total from Bill
so what's the best choice?
Vertical and Horizontal summations ... assuming no NULLS
declare #mytable table (a int, b int)
insert into #mytable
values
(1,1),
(2,3)
select * from #mytable
select sum(a) * sum(b) from #mytable -- result is 12 .. vertical/column, summarize column first then multiply to other column
select sum(a*b) from #mytable --- result is 7 .. horizontal/row, summarize the product of a and b
This is not a matter of SQL. It's just basic math. Assuming c1=(0,1) and c2=(2,3). Then:
sum(c1)*sum(c2) alias... (0+1)*(2+3) = 5
is not the same as:
sum(c1*c2) alias... (0*2)+(1*3) = 3
NULLs and Zeros are one concern
Declare #YourTable table (C1 money,C2 money)
Insert Into #YourTable values
(100,10)
,(100,null)
Select sum(c1) * sum(c2) -- 2000.00
From #YourTable
Select sum(c1 * c2) -- 1000.00
From #YourTable

Replace empty values as 0 instead of null while joining two tables in sql

I have join two tables t1 and t2. The output produces some null records since there is no data in the table t2. Instead of showing null I want to show 0 since I have to perform some arithmetic operation in the crystal reports.
please help me.....
sample example
declare #t table (ID int)
declare #t1 table (ID int)
insert into #t (id) values (1)
select t.ID,ISNULL(TT.ID,0)id from #t t
LEFT JOIN #t1 tt
ON t.ID = tt.ID
Use the COALESCE function which automatically replace null values as 0.
Sample
SELECT COALESCE(total_amount, 0) from #Temp1

Is there a way to return more than 1 row in select without using existing tables

Simple question, just out of curiosity.
For example select 1,2,3 that will show table with one column and three rows.
Something like this: select values(1),(2),(3)
*with one select statement
An example for my comment in your post.
DECLARE #TABLE TABLE (ONE INT, TWO INT, THREE INT)
INSERT INTO #TABLE VALUES (1,2,3)
SELECT UP.COL, UP.VALUE
FROM #TABLE
UNPIVOT (VALUE FOR COL IN (ONE,TWO,THREE)) UP
Query:
DECLARE #t TABLE (i1 INT, i2 INT, i3 INT)
INSERT INTO #t VALUES (1, 2, 3)
SELECT t.*
FROM #t
CROSS APPLY (
VALUES(i1), (i2), (i3)
) t(value)
Output:
value
-----------
1
2
3
Additional info:
http://blog.devart.com/is-unpivot-the-best-way-for-converting-columns-into-rows.html
As it appears there is a simple code that I've been searching for:
select n from (values (1),(2),(3)) D(c);

Union temporary tables to a final temporary table

I have like 10 diff temporary tables created in SQL server, what I am looking to do is union them all to a final temporary table holding them all on one table. All the tables have only one row and look pretty much exactly like the two temp tables below.
Here is what I have so far this is an example of just two of the temp tables as their all exactly like this one then #final is the table I want to union the all to:
create table #lo
(
mnbr bigint
)
insert into #login (mnbr)
select distinct (_ID)
FROM [KDB].[am_LOGS].[dbo].[_LOG]
WHERE time >= '2012-7-26 9:00:00
Select count(*) as countreject
from #lo
create table #pffblo
(
mber_br
)
insert into #pffblo (mber_br)
select distinct (mber_br)
from individ ip with (nolock)
join memb mp with (nolock)
on( ip.i_id=mp.i_id and mp.p_type=101)
where ip.times >= '2012-9-26 11:00:00.000'
select count(*) as countaccept
create table #final
(
countreject bigint
, Countacceptbigint
.....
)
insert into #final (Countreject, Countaccept....more rows here...)
select Countreject, Countaccept, ...more rows selected from temp tables.
from #final
union
(select * from #lo)
union
(select * from #pffblo)
select *
from #final
drop table #lo
drop table #pffblo
drop table #final
if this the form to union the rows form those temp tables to this final one. Then is this correct way to show all those rows that were thus unioned. When I do this union I get message number of columns in union need to match number of columns selected in union
I think you're using a union the wrong way. A union is used when you have to datasets that are the same structure and you want to put them into one dataset.
e.g.:
CREATE TABLE #Table1
(
col1 BIGINT
)
CREATE TABLE #Table2
(
col1 BIGINT
)
--populate the temporary tables
CREATE TABLE #Final
(
col1 BIGINT
)
INSERT INTO #Final (col1)
SELECT *
FROM #Table1
UNION
SELECT *
FROM #Table2
drop table #table1
drop table #table2
drop table #Final
I think what you're trying to do is get 1 data set with the count of all your tables in it. Union won't do this.
The easiest way (although not very performant) would be to do select statements like the following:
CREATE TABLE #Table1
(
col1 BIGINT
)
CREATE TABLE #Table2
(
col1 BIGINT
)
--populate the temporary tables
CREATE TABLE #Final
(
col1 BIGINT,
col2 BIGINT
)
INSERT INTO #Final (col1, col2)
select (SELECT Count(*) FROM #Table1) as a, (SELECT Count(*) FROM #Table2) as b
select * From #Final
drop table #table1
drop table #table2
drop table #Final
It appears that you want to take the values from each of temp tables and then place then into a single row of data. This is basically a PIVOT, you can use something like this:
create table #final
(
countreject bigint
, Countaccept bigint
.....
)
insert into #final (Countreject, Countaccept....more rows here...)
select
from
(
select count(*) value, 'Countreject' col -- your UNION ALL's here
from #lo
union all
select count(*) value, 'countaccept' col
from #pffblo
) x
pivot
(
max(value)
for col in ([Countreject], [countaccept])
) p
Explanation:
You will create a subquery similar to this that will contain the COUNT for each of your individual temp table. There are two columns in the subquery, one column contains the count(*) from the table and the other column is the name of the alias:
select count(*) value, 'Countreject' col
from #lo
union all
select count(*) value, 'countaccept' col
from #pffblo
You then PIVOT these values to insert into your final temp table.
If you do not want to use PIVOT, then you can use a CASE statement with an aggregate function:
insert into #final (Countreject, Countaccept....more rows here...)
select max(case when col = 'Countreject' then value end) Countreject,
max(case when col = 'countaccept' then value end) countaccept
from
(
select count(*) value, 'Countreject' col -- your UNION ALL's here
from #lo
union all
select count(*) value, 'countaccept' col
from #pffblo
) x
Or you might be able to JOIN all of the temp tables similar to this, where you create a row_number() for the one record in the table and then you join the tables with the row_number():
insert into #final (Countreject, Countaccept....more rows here...)
select isnull(lo.Countreject, 0) Countreject,
isnull(pffblo.Countaccept, 0) Countaccept
from
(
select count(*) Countreject,
row_number() over(order by (SELECT 0)) rn
from #lo
) lo
left join
(
select count(*) Countaccept,
row_number() over(order by (SELECT 0)) rn
from #pffblo
) pffblo
on lo.rn = pffblo.rn
SELECT *
INTO #1
FROM TABLE2
UNION
SELECT *
FROM TABLE3
UNION
SELECT *
FROM TABLE4
If you would like to get count for each temporary table in the resulting table, you will need just to calculate it for each column in subquery:
INSERT INTO result (col1, col2,...
SELECT
(SELECT COUNT() FROM tbl1) col1
,(SELECT COUNT() FROM tbl2) col2
..