closest numeric value in database using Prisma Client - sql

Is there any way I could re-write this SQL query using Prisma Client.
SELECT TOP 1 * FROM [myTable]
WHERE Name = 'Test' and Size = 2 and PType = 'p'
ORDER BY ABS( Area - #input )

You can use queryRaw and directly pass the raw SQL to execute it.
It would look like this:
const result = await prisma.$queryRaw`SELECT TOP 1 * FROM [myTable]
WHERE Name = 'Test' and Size = 2 and PType = 'p'
ORDER BY ABS( Area - #input )`

Related

postgresql Multiple identical conditions are unified into one parameter

I have one sql that need convert string column to array and i have to filter with this column,sql like this:
select
parent_line,
string_to_array(parent_line, '-')
from
bx_crm.department
where
status = 0 and
'851' = ANY(string_to_array(parent_line, '-')) and
array_length(string_to_array(parent_line, '-'), 1) = 5;
parent_line is a varchar(50) column,the data in this like 0-1-851-88
question:
string_to_array(parent_line, '-') appear many times in my sql.
how many times string_to_array(parent_line) calculate in each row. one time or three times
how convert string_to_array(parent_line) to a parameter. at last,my sql may like this:
depts = string_to_array(parent_line, '-')
select
parent_line,
depts
from
bx_crm.department
where
status = 0 and
'851' = ANY(depts) and
array_length(depts, 1) = 5;
Postgres supports lateral joins which can simplify this logic:
select parent_line, v.parents, status, ... other columns ...
from bx_crm.department d cross join lateral
(values (string_to_array(parent_line, '-')) v(parents)
where d.status = 0 and
cardinality(v.parents) = 5
'851' = any(v.parents)
Use a derived table:
select *
from (
select parent_line,
string_to_array(parent_line, '-') as parents,
status,
... other columns ...
from bx_crm.department
) x
where status = 0
and cardinality(parents) = 5
and '851' = any(parents)

how to select in if statements

I want to test two TaskChangeLogIDs where ID '28' has a NewRollback of 0, and ID '31' has a NewRollback of 1.
I want make sure that depending which ID is called, it selects the correct NewRollback number. I get an error applying the code below in a new window so just need help tweaking this and learn on how to test things like this in the future. I'm getting an error in the IF statement line only.
SELECT isnull(NewRollback, 0) FROM Core.TaskChangeLog
WHERE TaskChangeLogID = 28
SELECT isnull(NewRollback, 0) FROM Core.TaskChangeLog
WHERE TaskChangeLogID = 31
IF (NewRollback = 1)
Select * from Core.TaskChangeLog where NewRollback = 1
ELSE
BEGIN
Select * from Core.TaskChangeLog where NewRollback = 0
END
You don't need IF condition to do this just AND/OR logic will do the job
Try this way
Select * from Core.TaskChangeLog
where (NewRollback = 1 and askChangeLogID = 28)
OR (NewRollback = 0 and askChangeLogID = 31)
To do some action based on select result try this
IF EXISTS (Select * from Core.TaskChangeLog
where NewRollback = 1 and askChangeLogID = 28) -- Replace with your ID
BEGIN
--some action
END
IF EXISTS (Select * from Core.TaskChangeLog
where NewRollback = 0 and askChangeLogID = 28)
BEGIN
--some action
END
How about putting all this in one query? This is my best guess as to the logic you want:
Select *
from Core.TaskChangeLog
where NewRollback = (SELECT COALESCE(NewRollback, 0)
FROM Core.TaskChangeLog
WHERE TaskChangeLogID = XX
);
Your code fails because the NewRollback in the IF is undefined. You could use a variable, but that would just complicate the code. And, the code should be simplified rather than made more complicated.

Need to load huge dataset (32 Million) into table using SSIS

I have a huge dataset to return in SQL Server( about 32 million rows) This is implemented in view and source code is as follows :
SELECT Idenitifier = ISNULL(mle.MIdeer, mle.Ider) + em.MemberId,
EffectiveDate = ISNULL(em.EffectiveDate,
(SELECT TOP 1 EffectiveDate
FROM c
WHERE SourceType = em.SourceType
AND GroupNumber = em.GroupNumber
AND ISNULL(GroupDivision, '') =
ISNULL(em.GroupDivision, '')))
FROM a em
JOIN b mle
ON mle.Identifier = em.GroupNumber + ISNULL('-' + em.GroupDivision, '')
-- Filter invalid legal entities
AND ISNULL(mle.Filter, 0) = 0
--- Gets a resultset of 531798 rows
CROSS JOIN -- this returns 63 rows , so
-- I am presuming 531798*63 rows here.
(SELECT *
FROM map
WHERE domaintype = 'MC')b;
I need to load this dataset using SSIS into a table. After 16 million rows, I am getting a system.out of memory exception in sql server when I am giving a select * from <<view>>. How to load this dataset in table using SSIS,avoiding this exception..
What other better methods to do this query efficiently as it takes more than 30 mins to run?
I'm still thinking through this, but you might need to separate the CROSS JOIN:
;WITH cte AS (SELECT ISNULL(mle.MIdeer, mle.Ider) + em.MemberId AS Idenitifier
, ISNULL(em.EffectiveDate,
( SELECT TOP 1
EffectiveDate
FROM c
WHERE SourceType = em.SourceType
AND GroupNumber = em.GroupNumber
AND ISNULL(GroupDivision, '') = ISNULL(em.GroupDivision,
'')
)) AS EffectiveDate
FROM a em
JOIN b mle ON mle.Identifier = em.GroupNumber + ISNULL('-'+ em.GroupDivision,'')
AND ISNULL(mle.Filter, 0) = 0)
SELECT *
FROM cte
CROSS JOIN ( SELECT *
FROM map
WHERE domaintype = 'MC') b;

how to limit a sql integer query result to <=1

how to limit an integer query result to 1. a return of 2 to be 1, a return 1 to be 1, and a return of 0.5 to be 0.5 because it is <= 1. i don't want to modify the tables, i just want to modify the results.
This is my exact query.
select ((select "V01" from sports where "UID" = '1') * 1.0 ) /
(select "V01" from master where "BALL" = 'REQUIREMENT') ;
I'm using postgres.
To limit, you'd do something like this:
select
case
when yourNumber >= 1 then 1
else yourNumber
end
...
Then you just apply this concept to your query.
As noted by Wiseguy, you could also do:
select LEAST(yourNumber, 1)
, since this is postgresql.
The first solution will work with any ANSI SQL compatible database.
Update
Applied to your query, I think (if I understood what you want correctly) it would be like this:
select LEAST(1,
((select "V01" from sports where "UID" = '1') * 1.0 ) /
(select "V01" from master where "BALL" = 'REQUIREMENT')
);
use the LEAST function , docs: http://www.postgresql.org/docs/8.3/static/functions-conditional.html. Also, check out GREATEST too
SELECT LEAST(1, <your value>)
EDIT replaced GREATEST with LEAST
try this:
select CASE
WHEN ((select V01 from sports where UID = '1') * 1.0 ) /
(select V01 from master where BALL = 'REQUIREMENT') >= 1
THEN 1
ELSE ((select V01 from sports where UID = '1') * 1.0 ) /
(select V01 from master where BALL = 'REQUIREMENT')
END;

Find closest numeric value in database

I need to find a select statement that will return either a record that matches my input exactly, or the closest match if an exact match is not found.
Here is my select statement so far.
SELECT * FROM [myTable]
WHERE Name = 'Test' AND Size = 2 AND PType = 'p'
ORDER BY Area DESC
What I need to do is find the closest match to the 'Area' field, so if my input is 1.125 and the database contains 2, 1.5, 1 and .5 the query will return the record containing 1.
My SQL skills are very limited so any help would be appreciated.
get the difference between the area and your input, take absolute value so always positive, then order ascending and take the first one
SELECT TOP 1 * FROM [myTable]
WHERE Name = 'Test' and Size = 2 and PType = 'p'
ORDER BY ABS( Area - #input )
something horrible, along the lines of:
ORDER BY ABS( Area - 1.125 ) ASC LIMIT 1
Maybe?
If you have many rows that satisfy the equality predicates on Name, Size, and PType columns then you may want to include range predicates on the Area column in your query. If the Area column is indexed this could allow efficient index-based access.
The following query (written using Oracle syntax) uses one branch of a UNION ALL to find the record with minimal Area >= your target, while the other branch finds the record with maximal Area < your target. One of these two records will be the record that you are looking for. Then you can ORDER BY ABS(Area - ?input) to pick the winner out of those two candidates. Unfortunately the query is complex due to nested SELECTS that are needed to enforce the desired ROWNUM / ORDER BY precedence.
SELECT *
FROM
(SELECT * FROM
(SELECT * FROM
(SELECT * FROM [myTable]
WHERE Name = 'Test' AND Size = 2 AND PType = 'p' AND Area >= ?target
ORDER BY Area)
WHERE ROWNUM < 2
UNION ALL
SELECT * FROM
(SELECT * FROM [myTable]
WHERE Name = 'Test' AND Size = 2 AND PType = 'p' AND Area < ?target
ORDER BY Area DESC)
WHERE ROWNUM < 2)
ORDER BY ABS(Area - ?target))
WHERE rownum < 2
A good index for this query would be (Name, Size, PType, Area), in which case the expected query execution plan would be based on two index range scans that each returned a single row.
SELECT *
FROM [myTable]
WHERE Name = 'Test' AND Size = 2 AND PType = 'p'
ORDER BY ABS(Area - 1.125)
LIMIT 1
-- MarkusQ
How about ordering by the difference between your input and [Area], such as:
DECLARE #InputValue DECIMAL(7, 3)
SET #InputValue = 1.125
SELECT TOP 1 * FROM [myTable]
WHERE Name = 'Test' AND Size = 2 AND PType = 'p'
ORDER BY ABS(#InputValue - Area)
Note that although ABS() is supported by pretty much everything, it's not technically standard (in SQL99 at least). If you must write ANSI standard SQL for some reason, you'd have to work around the problem with a CASE operator:
SELECT * FROM myTable
WHERE Name='Test' AND Size=2 AND PType='p'
ORDER BY CASE Area>1.125 WHEN 1 THEN Area-1.125 ELSE 1.125-Area END
If using MySQL
SELECT * FROM [myTable] ... ORDER BY ABS(Area - SuppliedValue) LIMIT 1