Sql-Filter the Select - sql

SELECT DISTINCT x1.NUM_KANBAN_ID ID,
TO_CHAR(x1.DT_CREATE,'YYYY-MM-DD') CREATED,
x5.TXT_PLANT_CD CD,
TO_CHAR(x4.DT_FIRST_VIEWED,'YYYY-MM-DD') VIEWED,
TO_CHAR(x4.DT_DUE,'YYYY-MM-DD') DUE, x4.
TXT_SHUTTLE_NUMBER SHUTTLE,
(select count(*)
from WEDI_ASN_TO_DIMENSION t8
where t8.TXT_MATCH_CD='1'
AND t8.NUM_DIMENSION_ID=x2.NUM_DIMENSION_ID AND t8.NUM_MATCH_ID = x1.NUM_KANBAN_ID) ASN,
x1.TXT_JIT_CALL_NUM,
x2.NUM_VENDOR_ID VENDOR_ID
FROM WEDI_KANBAN x1, WEDI_DIMENSION x2, WEDI_USER_VENDORS x3, WEDI_KANBAN_TO_DIMENSION x4, WEDI_PLANT x5
WHERE x5.NUM_PLANT_ID = x2.NUM_PLANT_ID AND
x1.TXT_STATUS_CD = 'C' AND
x2.NUM_VENDOR_ID = x3.NUM_VENDOR_ID AND
x4.NUM_DIMENSION_ID = x2.NUM_DIMENSION_ID AND
x1.NUM_KANBAN_ID = x4.NUM_KANBAN_ID AND
x1.DT_CREATE < SYSDATE - 15 AND
x5.TXT_PLANT_CD LIKE '%' AND
x2.TXT_MATERIAL_NUM LIKE '%' AND
((x4.TXT_SHUTTLE_NUMBER IS NULL) OR (x4.TXT_SHUTTLE_NUMBER LIKE '%')) AND
x4.DT_DUE < SYSDATE - 10
ORDER BY VENDOR_ID
In the above query i should display the id's whose ASN is only 1 or 2 . If the ASN has like this 0,1,2 i Should not display those IDs. Generally if the id's ASN has 0 i should not display.
Pls suggest

Simplest solution is:
select *
from (your query)
where 0 not in (select ASN from (your query))
In order to not write the query twice:
with (your query) as A
select *
from a
where 0 not in (select asn from a)
or
with (your query) as A
select *
from a
where not exists (select * from a where asn = 0)
However, exists the posibility to rewrite your query to return no rows when exists an ASN equal to zero, but the query is hard to understand, and almost sure something is wrong because you need a DISTINCT clause. That's bad sign.

Add something like (ASN = 1) Or (ASN = 2) in your Where statement

Related

How do I get Average IF statement in SQL?

I have table in MS Access with columns Year, Period (values just 1 and 2), Costs_Per_Capita and CALCULATED_Period_Avg_Costs, PK is ID.
I need to calculate CALCULATED_Period_Avg_Costs. It should return average of Costs_Per_Capita for given period from Period column. In Excel I do this with SUMIF/COUNTIF which returns Average IF.
Do you have some advice how to write a code in SQL to do that?
Results should look like:
Costs_Per_Capita Period CALCULATED_Period_Avg_Costs
15,505 1 15976.27582
16,368 1 15976.27582
16,037 1 15976.27582
15,995 1 15976.27582
15,000 2 16000
17,000 2 16000
I used statement:
SELECT
Costs_Per_Capita, Period
IFF (Period = 1,
(Select AVG(Costs_Per_Capita) From Costs Where Period = 1),
(Select AVG(Costs_Per_Capita) From Costs Where Period = 2)
AS result
FROM Costs;
Still gets "syntax error (missing operator) in a query expression ..."
I think I know what you're asking for and I believe this is what you're looking for -
Select
Costs_Per_Capita,
Related_Period_ID,
(Select
Case when Related_Period_ID = 1 then
(Select
AVG(Costs_Per_Capita)
From Costs_Per_Capita_Table
Where Related_Period_ID = 1)
else
(Select
AVG(Costs_Per_Capita)
From Costs_Per_Capita_Table
Where Related_Period_ID = 2)
END
)
From
Costs_Per_Capita_Table
Changing CASE to IFF
Select
IFF (Related_Period_ID = 1,
(Select
AVG(Costs_Per_Capita)
From Costs_Per_Capita_Table
Where Related_Period_ID = 1),
(Select
AVG(Costs_Per_Capita)
From Costs_Per_Capita_Table
Where Related_Period_ID = 2)
I did this with:
SELECT Costs.Costs_Per_Capita, Costs.Period,
IIF(Costs.Period = 1,
(Select AVG(Costs_Per_Capita) From Costs Where Period = 1),
(Select AVG(Costs_Per_Capita) From Costs Where Period = 2))
AS result
FROM Costs;
other way, better if more periods apper is using subquery:
SELECT Costs.Period, Costs.Costs_Per_Capita, tmpQry.CALCULATED_Period_Avg_Costs
FROM Costs INNER JOIN (SELECT Costs.Period, Avg(Costs.Costs_Per_Capita)
AS CALCULATED_Period_Avg_Costs FROM Costs
GROUP BY Costs.Period) AS tmpQry ON Costs.Period = tmpQry.Period;
maybe someone will use it later on...
Select CostsPerCapital, Period, avg(CostPerCapita) over (partition by Period)
From Table
Where....
Order by ...

Multiple assignments in SQL - correct syntax

Multiple assignments in SQL. The one variable form works and I have extended to use two variables: A and B. But I cannot see how I would extend the format. The following is what I am trying.
SELECT TOP 1 #MYA = A; #MYB = CB FROM WHERE X='MYX' ORDER BY X Total select #MYA #MYB
Here is my original statement:
SELECT TOP 1 #MYA = A FROM WHERE X='MYX' ORDER BY X Total select #MYA
How can I return two variables or more?
Use commas:
SELECT TOP 1 #MYA = A, #MYB = CB
FROM
WHERE X='MYX'
ORDER BY X, Total;
select #MYA, #MYB;
The ; goes at the end of the statement.

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;

How to filter MySQL SELECT by an aggregate function?

SELECT h11, HA11
FROM florin.h11
WHERE (3>d1 AND 3<d2) OR (3>d1 AND 3=d2 AND id=MAX(id))
UNION (3=d1 AND 3<d2 AND id=MIN(id));
Here a screenshot of my table stucture:
I think what you would like to do is something like this:
SELECT h11, HA11
FROM florin.h11
WHERE (3>d1 AND 3<d2)
OR (3>d1 AND 3=d2 AND id = (SELECT MAX(t2.id)
FROM florin.h11 AS t2))
OR (3=d1 AND 3<d2 AND id = (SELECT MIN(t3.id)
FROM florin.h11 AS t3));
First wrong thing is
Please mention if, florin is database and h11 is table.
If florin is table then write only "select h11,HA11 from florin", don't write column name.
Second wrong thing is
Union operator is used to join results of two query. For more info surf www.w3school.com
So, fire query like
select h11, HA11
from florin
where (3 > d1 and 3 < d2) or (3 > d1 and 3 = d2 and id = MAX(id))
union
select h11, HA11
from florin
where (3 = d1 and 3 < d2 and id = MIN(id))
Here may this query doesn't return desired result but this was my imagine that you want such type of query.

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