Threshold SQL Table - sql

I have a screenshot of a GUI and need to make it into a SQL table. What would be the best way of going about this?

There are 3 distinct entities in that screenshot, so define 3 tables.
Create Table ProbabilityThresholds(
Name varchar (50),
MinValue int,
MaxValue int
)
Create Table RisksMatrix (
Probability varchar(50),
MinorSeverity varchar(50),
ModerateSeverity varchar(50),
MajorSeverity varchar(50),
ExtremeSeverity varchar(50),
SortOrder int
)
Create Table RiskToCategory (
Risk varchar(50),
Category varchar(50),
SortOrder int
)
Then Query the 3 tables in multiple result sets (either as 3 direct queries or as a stored procedure). The as expression sets a column alias, and the SortOrder column is populated to sort in the desired layout, but is not selected in the results:
Select Name
, MinValue
, MaxValue
from ProbabilityThresholds
order by MinValue;
Select
Probability
,MinorSeverity as "Minor Harm",
,ModerateSeverity as "Moderate Harm",
,MajorSeverity as "Major Harm",
,ExtremeSeverity as "Extreme Harm",
from RisksMatrix
order by SortOrder ;
Select
Risk
,Category
from RiskToCategory
order by SortOrder;

Related

Select from a Temp table is giving slow performance

I need some help with the below query where the last step of
Select * from #PersonDetail order by....
is taking so long to execute - why?
There are millions of records being inserted in this temp table #PersonDetail and insert process takes a few seconds, but the last Select from this same temp table is taking so long.
I created a unique clustered index on the columns used for order by and tried many other options but it doesn't make any difference in the performance.
It is a big stored procedure with many temp table but it is this last select step which is impacting the performance. Here is an example of the last step of the query:
DROP TABLE IF EXISTS #PersonDetail
CREATE TABLE #PersonDetail
(
PersonId INT NOT NULL,
Name NVARCHAR(50) NULL,
Number INT NOT NULL,
Tag NVARCHAR(50) NULL,
UserId INT NOT NULL,
NumberEncrypted VARCHAR(100),
Type NVARCHAR(255),
Status NVARCHAR(50),
CreatedDate DATETIMEOFFSET(7),
AddressDetailId NVARCHAR(50),
Category NVARCHAR(50),
PrimaryId INT,
DailyAmount MONEY,
UNIQUE (PersonId UserId),
UNIQUE CLUSTERED(CreatedDate, UserId)
)
INSERT INTO #PersonDetail (PersonId, Name, Number, Tag, UserId, NumberEncrypted,
Type, Status, CreatedDate, AddressDetailId, Category, PrimaryId, Amount)
SELECT
PersonId, Name, Number, Tag, UserId, NumberEncrypted,
Type, Status, CreatedDate, AddressDetailId, Category, PrimaryId, DailyAmount
FROM
#User u
JOIN
dbo.DailyAmount da (NOLOCK) ON da.UserId = u.UserId
SELECT *
FROM #PersonDetail pd
ORDER BY CreatedDate, UserId
You must specify what database are you using.
In general, you must do theese things:
create some indexes on the join columns (DailyAmount.userId, User.userID); how to create the index must change;
create an index on the order by columns, (CreatedDate+UserID); this must change, in postgresql for example an index with the 2 column is better than 2 indexes;
If your data are not changing frequently, you could try materialized view and create the indexes on the materialized view.

Delete duplicate rows with soundex?

I have two tables, one has foreign keys to the other. I want to delete duplicates from Table 1 at the same time updating the keys on Table 2. I.e count the duplicates on Table 1 keep 1 key from the duplicates and query the rest of the duplicate records on Table 2 replacing them with the key I'm keeping from Table 1. Soundex would be the best option because not all the names are spelled right in Table 1. I have the basic algorithm but not sure how to do it. Help?
So far this is what I have:
declare #Duplicate int
declare #OriginalKey int
create table #tempTable1
(
CourseID int, <--- The Key I want to keep or delete
SchoolID int,
CourseName nvarchar(100),
Category nvarchar(100),
IsReqThisYear bit,
yearrequired int
);
create table #tempTable2
(
CertID int,
UserID int,
CourseID int, <---- Must stay updated with Table 1
SchoolID int,
StartDateOfCourse datetime,
EndDateOfCourse datetime,
Type nvarchar(100),
HrsOfClass float,
Category nvarchar(100),
Cost money,
PassFail varchar(20),
Comments nvarchar(1024),
ExpiryDate datetime,
Instructor nvarchar(200),
Level nchar(10)
)
--Deletes records from Table 1 not used in Table 2--
delete from Table1
where CourseID not in (select CourseID from Table2 where CourseID is not null)
insert into #tempTable1(CourseID, SchoolID, CourseName, Category, IsReqThisYear, yearrequired)
select CourseID, SchoolID, CourseName, Category, IsReqThisYear, yearrequired from Table1
insert into #tempTable2(CertID, UserID, CourseID, SchoolID, StartDateOfCourse, EndDateOfCourse, Type, HrsOfClass,Category, Cost, PassFail, Comments, ExpiryDate, Instructor, Level)
select CertID, UserID, CourseID, SchoolID, StartDateOfCourse, EndDateOfCourse, Type, HrsOfClass,Category, Cost, PassFail, Comments, ExpiryDate, Instructor, Level from Table2
select cour.CourseName, Count(cour.CourseName) cnt from Table1 as cour
join #tempTable1 as temp on cour.CourseID = temp.CourseID
where SOUNDEX(temp.CourseName) = SOUNDEX(cour.CourseName) <---
The last part does not exactly work, gives me an error
Error: Column 'Table1.CourseName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
UPDATE: Some of the names in CourseName have numbers in them too. Like some are in romans and numeral format. Need to find those too but Soundex ignores numbers.

setting rowID as identity (should be ascending number) in SQL

I have this following sql script
DECLARE #tmpTable TABLE (rowID int IDENTITY,
woID varchar(100), srID varchar(100),
woWorkOrderNumber varchar(100),
woSequenceCount varchar(100),
WorkOrderNumber varchar(100)
)
INSERT INTO #tmpTable (woID, srID, woWorkOrderNumber, woSequenceCount, WorkOrderNumber)
SELECT
woID, srID, woWorkOrderNumber, woSequenceCount,
SUBSTRING(woWorkOrderNumber, 11, 20 ) AS WorkOrderNumber
FROM
WorkOrder
WHERE
codeSICurrentStatusCode NOT IN (3, 4)
AND SUBSTRING(woWorkOrderNumber, 11, 20) = ''
SELECT * FROM #tmpTable
But I'm getting these results on my rowID column:
As you can see, the rowID seems to be the row number from the table I selected on. What I'm trying to achieve on this temp table is that the rowID starts from 1 then 2 then 3 and so on and so forth.. What's wrong with my code?
You need to specify ORDER BY on the INSERT statement SELECT clause in order to control the order of identity value assignment. You can alternatively use ROW_NUMBER() instead of IDENTITY to ensure there are no gaps and provide complete control over the values.

SQL query Optimization help

I have the the following SQL query
Declare #tempcalctbl Table
(
ItemId varchar(50),
ItemLocation varchar(50),
ItemNo varchar(50),
Width real,
Unit varchar(50),
date datetime
)
Insert Into #tempcalctbl
Select distinct SubId,ItemLocation,ItemNo,
(ABS((Select width From #temptbl a Where ItemProcess ='P1'and a.ItemId = c.ItemId
and a.ItemNo = c.ItemNo and a.ItemLocation = c.ItemLocation)
-(Select width From #temptbl b Where ItemProcess ='P2' and b.ItemId = c.ItemId
and b.ItemNo = c.ItemNo and b.ItemLocation = c.ItemLocation))) * 1000,
Unit,date
From #temptbl c
Group by ItemId,ItemLocation,ItemNo,Unit,date
I was wondering how to optimize this query.
The idea is to find out the different in width (p1's item - p2's item) between ItemProcess 'P1' and 'P2' according to the same ItemID, same ItemNo and same ItemLocation.
I have around 75000 and it took more then 25 minute to get the width differences for all the ItemId.
I tried to use Group by for the width different calculation but it would return multiple row instead of just a value which then would return error. By the way I am use MS SQL server 2008 and #tempcalctbl is a table that I declared in a store procedure.
Does the following help?
INSERT INTO #tempcalctbl
SELECT P1.SubId ,
P1.ItemLocation ,
P1.ItemNo ,
ABS(P1.Width - P2.Width) * 1000 AS Width ,
P1.Unit ,
P1.date
FROM #temptbl AS P1
INNER JOIN #temptbl AS P2 ON P1.ItemId = P2.ItemId
AND P1.ItemNo = P2.ItemNo
AND P1.ItemLocation = P2.ItemLocation
WHERE P1.ItemProcess = 'P1'
AND P2.ItemProcess = 'P2'
EDIT
To make use of indexes, you will need to change your table variable to a temporary table
CREATE TABLE #temptbl
(
ItemId varchar(50),
ItemLocation varchar(50),
ItemNo varchar(50),
Width real,
Unit varchar(50),
date DATETIME,
ItemProcess INT,
SubId INT
)
CREATE NONCLUSTERED INDEX Index01 ON #temptbl
(
ItemProcess ASC,
ItemId ASC,
ItemLocation ASC,
ItemNo ASC
)
INCLUDE ( SubId,Width,Unit,date)
GO
That should speed you up a little.
John Petrak's answer is the best query for this case.
If the speed is still now acceptable, maybe you can store #temptbl at a temporary real table, and create the related index on those four columns.

group by clause

i have a table called table1 and it has following columns.
suppose there are records like localamount is 20,000, 30000,50000, 100000 then as per my condition i have to delete records from this table according to the group by set of site id, till id, transid,shift id where localamount exceeds 10,000... the rest of the records can be available?
my aim is to delete rows from this table where local amount is exceeds 10,0000 according to site id, till id, transid,shift id
SiteId varchar(10),
TillId tinyint,
ShiftId int,
TransId int,
TranDate datetime,
SettlementType varchar(5),
CreditCardNumber varchar(25),
ProductTypeCode varchar(10),
NewProductTypeCode varchar(10),
TransactionType int,
ForeignAmount money,
LocalAmount money,
ProductCode varchar(10)
Im not sure I understand what you are saying, but couldn't you do this without a group by?
delete from table1 where LocalAmount > 10,0000[sic] and SiteId = whatever and TillId = whatever...
obviously take the [sic] out...
Assuming you want to delete the whole group where the sum is > 10000
;with cte as
(
select sum(localamount) over
(partition by siteid, tillid, transid,shiftid) as l,
* from table1
)
delete from cte where l>10000