How to get in which criteria the range falls using sql query? - sql

Code:
IF OBJECT_ID('tempdb..#TempMaster','U') IS NOT NULL
DROP TABLE #TempMaster
IF OBJECT_ID('tempdb..#TempTransaction','U') IS NOT NULL
DROP TABLE #TempTransaction
CREATE TABLE #TempMaster
(
Sno INT IDENTITY(1,1),
RangeDesc VARCHAR(100),
RangeFromValue INT,
RangeToValue INT
)
CREATE TABLE #TempTransaction
(
Sno INT IDENTITY(1,1),
[Values] INT
)
INSERT INTO #TempMaster(RangeDesc,RangeFromValue,RangeToValue)
SELECT * FROM (VALUES('Type A',1,10),('Type B',11,20),('Type C',21,30)) AS T(RangeDesc,RangeFromValue,RangeToValue)
INSERT INTO #TempTransaction([Values])
SELECT 1
UNION ALL
SELECT 15
UNION ALL
SELECT 5
SELECT * FROM #TempMaster
SELECT * FROM #TempTransaction
Please anyone help me to get a this kind of a solution based on which range the value falls.
I want to get a range description and write down a query for a below output. Thanks in advance.
-------------------------------
sno Values RangeDesc
-------------------------------
1 1 Type A
2 15 Type B
3 5 Type A
-------------------------------

You do left join based on range values.
select t1.Sno, t1.[Values], t2.RangeDesc
from #TempTransaction t1
left join #TempMaster t2 on t1.[Values] between t2.RangeFromValue and t2.RangeToValue

Related

Join two tables multiple times on same column with a lookup table in between

This has probably been answered but, its hard to search for this question, as you can see in my confusing title.
Anyhow, I hope this example will help:
The tricky part is the one to many relationship in the parameter lookup table.
Ive tried using multiple joins and aliases resulting in a hugh number of rows since Im getting every 'amount' for every 'price'.
SELECT paraval.month, paraval.value as amount, paraval2.value as price, trade.position
FROM trade
INNER JOIN parameter para on trade.tID=para.tID and para.name = 'amount'
INNER JOIN parametervalues paraval on para.pID=paraval.pID
INNER JOIN parameter para2 on trade.tID=para2.tID and para2.name = 'price'
INNER JOIN parametervalues paraval2 on para2.pID=paraval2.pID
WHERE trade.type = 'cert'
Guessing I need sub-queries, but not sure where to place them.
EDIT add some SQL code structure :
CREATE TABLE #Trade
(
tID int PRIMARY KEY,
type varchar(50),
position int
);
CREATE TABLE #Parameter
(
pID int PRIMARY KEY,
tID int,
name varchar(50)
);
CREATE TABLE #ParameterValue
(
pID int,
smonth varchar(50),
value varchar(50));
INSERT INTO #Trade
SELECT 1, 'stock', 1
UNION
SELECT 2, 'stock', 2
UNION
SELECT 3, 'cert', 3
INSERT INTO #Parameter
SELECT 1,1,'amount'
UNION
SELECT 2,1,'price'
UNION
SELECT 3,2,'amount'
UNION
SELECT 4,2,'price'
UNION
SELECT 5,3,'amount'
UNION
SELECT 6,3,'price'
INSERT INTO #ParameterValue
SELECT 1,1,'5'
UNION
SELECT 2,1,'500'
UNION
SELECT 3,1,'15'
UNION
SELECT 4,1,'300'
UNION
SELECT 5,1,'5'
UNION
SELECT 5,2,'10'
UNION
SELECT 5,3,'5'
UNION
SELECT 6,1,'100'
UNION
SELECT 6,2,'200'
UNION
SELECT 6,3,'300'
-- SELECT * FROM #Trade
-- SELECT * FROM #Parameter
-- SELECT * FROM #ParameterValue
DROP TABLE #Trade
DROP TABLE #Parameter
DROP TABLE #ParameterValue
I think the best way for build your excepted output and relevant schema you have to use pivot with dynamic sql because in next day it possible to have some new values it’s the principal of your structure.
But i think this query can be respond :
SELECT paraval.month, (case when para. name = 'amount' then max(paraval.value) else null end)as amount, (case when para. name = 'price' then max(paraval.value) else null end) as price, max(trade.position) as position
FROM trade
INNER JOIN parameter para on trade.tID=para.tID
INNER JOIN parametervalues paraval on para.pID=paraval.pID
WHERE trade.type = 'cert'
Group by paraval.month
EDIT correction off previous query :
CREATE TABLE #Trade
(
tID int PRIMARY KEY,
type varchar(50),
position int
);
CREATE TABLE #Parameter
(
pID int PRIMARY KEY,
tID int,
name varchar(50)
);
CREATE TABLE #ParameterValue
(
pID int,
smonth varchar(50),
value varchar(50));
INSERT INTO #Trade
SELECT 1, 'stock', 1
UNION
SELECT 2, 'stock', 2
UNION
SELECT 3, 'cert', 3
INSERT INTO #Parameter
SELECT 1,1,'amount'
UNION
SELECT 2,1,'price'
UNION
SELECT 3,2,'amount'
UNION
SELECT 4,2,'price'
UNION
SELECT 5,3,'amount'
UNION
SELECT 6,3,'price'
INSERT INTO #ParameterValue
SELECT 1,1,'5'
UNION
SELECT 2,1,'500'
UNION
SELECT 3,1,'15'
UNION
SELECT 4,1,'300'
UNION
SELECT 5,1,'5'
UNION
SELECT 5,2,'10'
UNION
SELECT 5,3,'5'
UNION
SELECT 6,1,'100'
UNION
SELECT 6,2,'200'
UNION
SELECT 6,3,'300'
/***/
-- Perform select
/***/
SELECT t.tID, paraval.smonth, MAX(case when para.name = 'amount' then paraval.value else null end)as amount, MAX(case when para.name = 'price' then paraval.value else null end) as price, max(T.position) as position
FROM #Trade T
INNER JOIN #Parameter para on T.tID=para.tID
INNER JOIN #ParameterValue paraval on para.pID=paraval.pID
Group by T.tId, paraval.smonth
/***/
DROP TABLE #Trade
DROP TABLE #Parameter
DROP TABLE #ParameterValue
RESULT :
tID smonth amount price position
1 1 5 500 1
2 1 15 300 2
3 1 5 100 3
3 2 10 200 3
3 3 5 300 3

Find missing numbers with SQL

In a large log file I have records containing the field INVNO (invoice-number).
The lowest and highest values are easy to find, BUT it looks like some numbers in between are not there.
Anyone got a trick with SQL, which can tell which numbers are missing within the number range?
use the following table valued function that takes 2 parameters : the min and max numbers,
and returns a list of missing number,
suppose your table name is YOUR_TABLE and the column name called InvNo
create FUNCTION [dbo].[MissingInvoiceNumbers]
(
#minPaym bigint,
#MaxPaym bigint
)
RETURNS #tmp table(numbers bigint)
AS
BEGIN
declare #n bigint --#minPaym bigint , #MaxPaym bigint,
declare #tmpAll table(Allnumbers bigint)
set #n= #minPaym
delete #tmp
delete #tmpAll
while (#n<=#MaxPaym)
begin
INSERT INTO #tmpAll
(AllNUMBERS)
VALUES (#n)
set #n=#n+1
end
INSERT INTO #tmp
(numbers)
SELECT Allnumbers
FROM #tmpAll
where Allnumbers not in (select distinct convert(bigint,InvNo) as InvoiceNum from YOUR_TABLE where
InvNo <> '' )
return
END
For oracle this should work. For any other database you just need to change way to generate the number sequence.
with vals as (
select rownum r
from dual
connect by rownum between {min} and {max}
)
select *
from vals v
left join {sometable} s on s.{someid} = v.r
where s.{someid} is null
The trick is just to generate numbers between min and max value, join table with invoices to this generated sequence and filter out everything that match.
Just join the table on itself...
DECLARE #tvp TABLE ( INVNO INT )
INSERT INTO #tvp
VALUES ( 1 ),
( 2 ),
( 3 ),
( 5 ),
( 6 ),
( 7 ),
( 8 ),
( 9 ),
( 10 ),
( 11 )
SELECT *
FROM #tvp;
SELECT t.INVNO + 1
FROM #tvp t
LEFT OUTER JOIN #tvp x ON x.INVNO = t.INVNO + 1
WHERE ISNULL(x.INVNO, 0) = 0;

Insert - Select keeping identity mapping

I have 2 tables, and im trying to insert data from one to another and keepeng the mappings between ids.
I found here someone with the same problem, but the solution isnt good for me.
here is the example:
the two tables
CREATE TABLE [source] (i INT identity PRIMARY KEY, some_value VARCHAR(30))
CREATE TABLE [destination] (i INT identity PRIMARY KEY, some_value VARCHAR(30))
CREATE TABLE [mapping] (i_old INT, i_new INT) -- i_old is source.i value, i_new is the inserted destination.i column
some sample data
INSERT INTO [source] (some_value)
SELECT TOP 30 name
FROM sysobjects
INSERT INTO [destination] (some_value)
SELECT TOP 30 name
FROM sysobjects
Here, i want to transfer everything from source into destination, but be able to keep a mapping on the two tables:
I try to use OUTPUT clause, but i cannot refer to columns outside of the ones being inserted:
INSERT INTO [destination] (some_value)
--OUTPUT inserted.i, s.i INTO [mapping] (i_new, i_old) --s.i doesn't work
SELECT some_value
FROM [source] s
Anyone has a solution for this?
Not sure is it write way but it works :D
MERGE [#destination] AS D
USING [#source] AS s
ON s.i <> s.i
WHEN NOT MATCHED BY TARGET
THEN
INSERT (some_value) VALUES (some_value)
OUTPUT inserted.i, s.i INTO [#mapping] (i_new, i_old);
try this sql below if you don't have permission to modify the tables:
The idea is using a temp table to be a bridge between destination table and the mapping table.
SQL Query:
declare #source table (i INT identity PRIMARY KEY, some_value VARCHAR(30))
declare #destination table (i INT identity PRIMARY KEY, some_value VARCHAR(30))
declare #mapping table (i_old INT, i_new INT) -- i_old is source.i value, i_new is the inserted destination.i column
declare #tempSource table
(
id_source INT identity , source_value VARCHAR(30)
,Id_New int,source_new VARCHAR(30)
)
insert into #source
output inserted.i, inserted.some_value into #tempSource(id_source,source_value)
SELECT TOP 10 name
FROM sysobjects
--select * from #tempsource
insert into #destination
OUTPUT inserted.i, inserted.some_value INTO #tempSource (Id_New,source_new)
select source_value from #tempSource
insert into #mapping
select Id_source, Id_New from
(
select a.id_source, a.source_value
from
#tempSource a
where id_source is not null and source_value is not null
) aa
inner join
(
select a.Id_New, a.source_new
from
#tempSource a
where Id_New is not null and source_new is not null
) bb on aa.source_value = bb.source_new
select * from #mapping
The mapping table result:
i_old i_new
----------- -----------
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10

Inserting values into a table based on column values of another table

I would like to insert data into a table based on all the values of a secondary table's column. For example
I have two tables
CREATE TABLE Table1 (
id int identity(1, 1) not null,
FullName varchar(100),
Age int,
CourseID int
)
CREATE TABLE Table2 (
id int identity(1, 1) not null,
Courses int
)
I would like to perform something like this ..
insert into Table1 ('Auser',20,'And the list of Courses that I get from Table2')
Is there a way I can do this in sql server ?
So for one new user you want to insert all available courses?
INSERT INTO Table1
SELECT 'Ausser', 20, t2.Courses
FROM Table2 t2;
Edit: Here's the fiddle: http://sqlfiddle.com/#!3/89470/1/0
Since, you are using SQL Server 2008, you can use the MERGE STATEMENT . Here is a program for your example
CREATE TABLE Table1
(
Id int identity(1, 1) not null,
FullName varchar(100),
Age int,
CourseID int
)
CREATE TABLE Table2
(
ID int identity(1, 1) not null,
Courses int
);
INSERT INTO Table2
SELECT 10 UNION ALL SELECT 20 UNION ALL
SELECT 30 UNION ALL SELECT 40 UNION ALL SELECT 50;
--The Merge Query
MERGE Table1 AS t1
USING (SELECT * FROM Table2) AS t2
ON t1.CourseID= t2.Courses
WHEN NOT MATCHED THEN
INSERT(FullName,Age,CourseID)
VALUES('Ausser',20,t2.Courses);
SELECT *
FROM Table1
DROP TABLE Table1
DROP TABLE Table2
//Result
Id FullName Age CourseID
1 Ausser 20 10
2 Ausser 20 20
3 Ausser 20 30
4 Ausser 20 40
5 Ausser 20 50

Nightmare Case Statement Assistance pl

Table 1 - Deal ID, REF NOS, Type, Papa ID
Table 2 - Deal ID, Type
Making a column in a new view called Method used. The way the field is to be set is as follows ( 4 conditions);
If Deal ID from table 1 Exists in Table 2 and Type is not Null from Table 2.
Set Method used to be Y
If Deal ID does not exist in Table 1 and Type does not contain 27,42 or 55 in Table 1.
Set Method used to be Y
If Papa ID is null from Table 1, and Type does not contain 27,42 or 55 in Table 1.
Set Method used to be Y
Else
Set to N
Started it and thought wow!..
create view Master as (
select Deal ID, REF NOS, Type, Papa ID
[Method used]=
Case
When
from Table 1 A
)
Something like this may work (assuming that these tables join on DealId). Note, I've removed spaces from some of your column names that you showed in your question.
Given these tables:
CREATE TABLE #Table1 (DealId INT, RefNos VARCHAR(100), [Type] VARCHAR(100), PapaId INT);
CREATE TABLE #Table2 (DealId INT, [Type] VARCHAR(100));
view example:
WITH DealIds AS (
SELECT DealId FROM #Table1
UNION
SELECT DealId FROM #Table2
)
SELECT
CASE
-- If Deal ID from table 1 Exists in Table 2 and Type is not Null from Table 2.
-- Set Method used to be Y
WHEN t1.DealId IS NOT NULL AND t2.DealId IS NOT NULL AND t2.[Type] IS NOT NULL THEN 'Y'
-- If Deal ID does not exist in Table 1 and Type does not contain 27,42 or 55 in Table 1.
-- Set Method used to be Y
-- Note: it is is redundant to have the type condition if DealId is the PK.
WHEN t1.DealId IS NULL AND t1.[Type] NOT IN (27, 42, 55) THEN 'Y'
-- If Papa ID is null from Table 1, and Type does not contain 27,42 or 55 in Table 1.
-- Set Method used to be Y
WHEN t1.PapaId IS NULL AND t1.[Type] NOT IN (27,42, 55) THEN 'Y'
-- Else
-- Set to N
ELSE 'N'
END AS MethodUsed
FROM DealIds d
LEFT JOIN #Table1 t1 ON d.DealId = t1.DealId
LEFT JOIN #Table2 t2 ON d.DealId = t2.DealId