SQL where clause with value computed from a query - sql

I'd like to do something along the lines of
select * from table where column < myValue,
and myValue is obtained by
select myValue from table where id = #id --there should only be one.
How can I combine these?
I tried where in, but with no success.

I would use a JOIN.
select t1.* from mytable as t1
join mytable as t2 on t1.column < t2.myValue
where t2.id = #id

What about something like this?
declare #myValue int -- value type
select top(1) #myValue = myValue from table where id = #id --there should only be one.
select * from table where column < ISNULL(#myValue,0);

A simple subquery should be fine.
select * from table where column < (select myValue from table where id = #id LIMIT 1)

Related

Finding row until condition is met

This is my table:
PackingNr
SerienNr
PN185971
PN185972
PN185972
PN185974
PN185974
PN185978
PN185978
R005478
PN185968
R000547
PN185725
R004987
As an input I get PackingNr and I need to select SerienNr which is like Rxxxxx not PNxxxxx.
So for example, if I have input PN175971, I need to get SerienNr = R005478.
How can I do this inside of select query? I tried CASE but this won't work as I don't know how many times I have to go again.
My select query is selecting also other columns from different tables.
SELECT
... ,
CASE
WHEN PSPD.SerienNr LIKE '%PN%'
THEN
(SELECT SerienNr FROM PSAPacking_Det
WHERE PSAPacking_Det.PackingNr = PSPD.SerienNr)
ELSE PSPD.SerienNr
END AS SerienNr
...
FROM
PSAPacking PSPD
JOIN
...
WHERE
PSPD.PackingNr = 'PN185971'
You need a recursive CTE. Something like this:
WITH cte AS (
SELECT t.PackingNr, t.SerienNr
FROM YourTable t
WHERE t..PackingNr = 'YourValueHere'
UNION ALL
SELECT t.PackingNr, t.SerienNr
FROM YourTable t
JOIN cte ON cte.SerienNr = t.PackingNr
)
SELECT TOP (1)
*
FROM cte
WHERE cte.SerienNr LIKE 'R%';
try this
declare #var2 varchar(max) = 'PN185971' --PUT YOUR INPUT HERE
declare #var1 varchar(max);
while(#var2 not like 'R%')
begin
set #var1 = #var2
set #var2 = (select max(SerienNr) from PSAPacking where PackingNr = #var1)
end
select #var2
if it doesn't find the value starting with R it returns null

SQL how to update the last row with a where conditon

Update table1 set status='open' where user='test' order by id DESC
i want to update the last row with a where conditon
You can use window function row_number() to get the first row in descending order of id.
with cte as
(
select *,row_number()over(order by id desc)rn from table1
)
Update cte set status='open' where user='test' and rn=1
Or you can use subquery to achieve same result:
UPDATE table1 SET status='open'
WHERE ID=(SELECT MAX(ID)FROM table1 where user='test') and user='test'
In order to find the record you want, you must first find the record you want and then change that record in the table. To do this, you need to create a temporary table and put the desired record in it, then update the table using the information obtained.
--Container to Insert Id which are to be iterated
Declare #temp1 Table
(
ID int
)
--Container to Insert records in the inner select for final output
Insert into #temp1
SELECT top 1 t.id FROM table1 t
WHERE t.user = 'test'
order by t.id desc
-- Keep track of #temp1 record processing
Declare #columnID int
Declare #columnValue varchar(100)
Begin
Set #columnID=(Select Top 1 id From #temp1)
Set #columnValue = 'open'
UPDATE table1 SET status = #columnValue WHERE id = #columnID
Delete #temp1 Where ID=#columnID
End
This should work, presume DBMS is MySQL
UPDATE table1
SET status = "open"
WHERE id in
(SELECT *
FROM
(SELECT id
FROM table1
WHERE USER = "test"
ORDER BY id DESC
LIMIT 1) tmp_tbl);

how to use a field of a table in the parameter of the contains function?

I am trying to use a field of a table as parameter of the contains method, but I don't know how to do it.
I am trying this:
SELECT * FROM tableA AS t1 WITH(UPDLOCK), TableB AS t2
WHERE CONTAINS(t1.FieldX, '"' + t2.FieldY + '"')
AND t2.ID IN(1,2,3,4,5);
However I get an error that says that is expected a ")" before the first "+".
How can I do it?
You could do it without contains and full-text-search, I mean using like operator:
select * from tableA as t1 with(UPDLOCK), TableB as t2
where t1.FieldX like '%"'+t2.FieldY+'"%'
and t2.ID IN(1,2,3,4,5);
The function you are looking for is CHARINDEX or PATINDEX...
where CHARINDEX('"' + t2.FieldY + '"', t1.FieldX) <> 0
not sure if you need the '"'
If you want to use wildcards then use the PATINDEX function
Let me know if this works.
You can't do this in one query with SQL Server full text. You're essentially trying to run a different full text query against each row.
You would have to actually run a separate query for each row like this:
-- put all tableA.ID values in table var so we can loop through them
declare #tableARowsToSearch table (ID int)
INSERT #tableARowsToSearch
SELECT ID FROM tableA WITH(UPDLOCK)
declare #fullTextResults table (ID int, FieldX varchar(max), ...)
-- for each tableA.ID...
declare #currentID int, #fullTextCondition nvarchar(4000)
set #currentID = (SELECT TOP 1 ID FROM #tableARowsToSearch ORDER BY ID)
while (#currentID is not null) begin
-- construct full text condition based on TableB.FieldY
set #fullTextCondition = (
SELECT t2.FieldY FROM tableA AS t1 WITH(UPDLOCK), TableB AS t2
WHERE t1.ID = #currentID
AND t2.ID IN(1,2,3,4,5)
)
-- run full text query against one row in tableA
INSERT #fullTextResults
SELECT t1.ID, t1.FieldX, ... FROM tableA AS t1 WITH(UPDLOCK)
WHERE t1.ID = #currentID
AND CONTAINS(t1.FieldX, #fullTextCondition)
set #currentID = (SELECT TOP 1 ID FROM #tableARowsToSearch WHERE ID > #currentID ORDER BY ID)
end
This is likely going to be very slow. You're better off using LIKE (see Tan_Blaytan's answer) or consider redesigning your tables.

How to use case statement inside an SQL select Query

I need to get the output of a selected query depending on certain conditions
Means if(id=uid)
then I need the below query
select * from table1 where id=5;
else
I need the below one
select * from table1 where id=10
I know i can use if condition for this. But my query is very long one so when I use if else then it would look like
if(#id=#uid)
begin
select * from table1 where id=5;// query 1
end
else
select * from table1 where id=10;//query 2
but here I need to replace the entire query once again for a single check. I hope I can do something like this:
declare #id int=4;
declare #uid=10;
select * from table1 where
case
when #id=#uid
then
id=5
else
id=10;
end
Updation
I need one more condition too
in this case id=5 and uid=10
then if(id=uid)
then
select * from table1 where id=5
and
if(id!=uid)
then
select * from table1
something like this
You can use the case expression to return the value id should be equal to:
SELECT *
FROM table1
WHERE id = CASE WHEN #id = #uid THEN 5 ELSE 10 END;
EDIT:
The updated requirement in the question is to return all rows when #id != #uid. This can be done by comparing id to id:
SELECT *
FROM table1
WHERE id = CASE WHEN #id = #uid THEN 5 ELSE id END;
Alternatively, with this updated requirement, a simple or expression might be simpler to use:
SELECT *
FROM table1
WHERE #id = #uid OR id = 5;
SELECT * FROM table1
WHERE (id=5 AND #id=#uid) OR (id=10 AND #id<>#uid)
SELECT
*
FROM
table1
WHERE
(
#id = #uid
AND
id =5
)
OR
(
not #id = #uid
AND
id=10
)

SELECT based on the result of another SELECT

Is it possible to run another SELECT based on the result of the first SELECT?
For example:
SELECT COUNT(*) FROM table1
If the result is 0, I want to display the result of:
SELECT A, B, C FROM table2
If the result of the first SELECT is NOT 0, display the result of the first query and IGNORE the second.
You can certainly run a second select based on the results of the first:
You could do this:
declare #count integer = (select count(*) from table1)
if #count = 0
select ... from table1
else
select ... from table2
shouldn't need a variable for your problem
if EXISTS (select * from table1)
select A, B, C from table2
The result of the first query is the count, so you can use the variable to avoid re-running the query.
DECLARE #count int = ( SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS )
IF #count > 0
BEGIN
SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS
END
ELSE
BEGIN
SELECT #count AS total
END