Can set the value of the previous query - tsql

how to SET return value to new query ?
query like :
DECLARE #count;
SELECT COUNT(*) FROM a WHERE x = 1;
SET #count = //result_last_query
SELECT * FROM b WHERE z = #count;

As simple as :
SELECT * FROM b
where z=(select count(*) FROM a FROM a WHERE x = 1;)}
You dont even require any variable declaration

thanks good solution
I modified the code of answers
SELECT *
FROM B
WHERE id IN (
SELECT COUNT(*) AS count
FROM A
WHERE x = 1
)

If you want get the resultset of the select query and want to access the row count in next statement you could use ##rowcount
Example Usage:
Select top 10 * from SomeTable
SELECT ##rowcount
First query in above script will return 10 rows and the second query will return 10.

You are almost done. You can set in query as the below:
DECLARE #count INT
SELECT #count = COUNT(*) FROM a WHERE x = 1
SELECT * FROM b WHERE z = #count

All you need to do is to put the variable in the query itself, in order to set the variable's value with the row count.
Then you can use the variable's value in the next query.
DECLARE #count;
SELECT #count = COUNT(*) FROM a WHERE x = 1;
SELECT * FROM b WHERE z = #count;
But, be careful that the variable will only be visible during execution so you need to execute this entire script all at once in order for the #count variable to work for the last query.

Related

Using variables in simple PostgresSQL queries

I have to perfrom a lot of queries where the same value is being reused. I thought of something like:
varName = 'value';
select * from sometable t where
t.field1 = varName
or t.field2 = varName;
How can this be done with PostgreSQL 12?
I tried a lot of stuff I found, but nothing seems to work.
I found a solution meanwhile
with varName as (select 'value'::text)
select * from sometable t where
t.field1 = (select * from varName)
or t.field2 = (select * from varName);
Alternatively you can use VALUES inside of your CTE. This will enable you to have multiple values in the same "variable".
Data Sample:
CREATE TABLE t (c1 int, c2 text);
INSERT INTO t VALUES (42,'foo'),(1,'xpto');
Query
WITH j (var) AS (VALUES ('foo'),('bar'))
SELECT t.c1,j.var FROM t
JOIN j ON j.var = t.c2;
c1 | var
----+-----
42 | foo

Update a value in DB with ascending values with no duplicates?

I am using this query to update a column with ascending values:
DECLARE #counter NUMERIC(10, 0)
SET #counter = 1400000
UPDATE SomeTable
SET #counter = SomeColumn = #counter + 1
Question is, how can I not put duplicates there? For example the column already has 1400002 as value. Normally it has NULLs, but sometimes it doesnt. I could add
where SomeColumn is null
but this would not avoid duplicates. Any ideas?
Thanks
I am not sure that this will help or not but you can put your existing data into temp table and then use that temp table to remove duplicates like:
WHERE (#counter + 1) not in ( select SomeColumn from #temp)
If above is not correct then please explain your question a little more.
This worked for me in SQL Server 2008:
DECLARE #StartNumber int, #EndNumber int;
SET #StartNumber = 100;
SELECT #EndNumber = #StartNumber + COUNT(*) - 1 FROM SomeTable;
WITH numbers AS (
SELECT #StartNumber AS Value
UNION ALL
SELECT
Value + 1
FROM numbers
WHERE Value < #EndNumber
),
validnumbers AS (
SELECT
n.Value,
rownum = ROW_NUMBER() OVER (ORDER BY n.Value)
FROM numbers n
LEFT JOIN SomeTable t ON n.Value = t.Value
WHERE t.Value IS NULL
),
RowsToUpdate AS (
SELECT
Value,
rownum = ROW_NUMBER() OVER (ORDER BY Value)
FROM SomeTable
WHERE Value IS NULL
OR Value NOT IN (SELECT Value FROM numbers)
)
UPDATE r
SET Value = v.Value
FROM RowsToUpdate r
INNER JOIN validnumbers v ON v.rownum = r.rownum;
Basically, it implements the following steps:
Create a number table.
Exclude the numbers present in SomeTable.
Rank the rest of the rows.
Exclude the values from SomeTable that are present in the number table.
Rank the rest of the rows.
Update the ranked rows of SomeTable from the ranked number list.
Not sure how good this solution would be for big tables, though...

How to filter records for all rows?

I am designing a SQL query to extract all records from a given table. But the trick here is that this logic is based on a numeric database field. So there are 4 choices: 0,1,2,3. If user selects 0,1, or 2, then my query returns rows with the specified value. But if they choose 3, it should return all of the rows. How do I do this in SQL? I know if this was a string, I could do something like:
WHERE = CASE WHEN = 3 THEN '%' ELSE END
But in this case, is an integer. Sounds relatively simple but I'm getting errors.
Try this:
SELECT *
FROM <YOUR_TABLE>
WHERE
(
<YOUR_COLUMN> = #InputValue OR
3 = #InputValue
)
Where #InputValue is the name of parameter sent to the query.
The simplest way is to do this:
select MyColumn
from MyTable
where ( MyValue = #MyParameter or #MyParameter = 3)
If your interested in better optimization, then you can do this, but it is less maintainable:
if (#MyParameter = 3)
select MyColumn
from MyTable
else
select MyColumn
from MyTable
where MyValue = #MyParameter
If I were forced to implement this functionality, then I would probably do this, just to make things clear:
declare #AllRecords nchar(1)
if (#MyParameter = 3)
set #AllRecords = N'Y'
else
set #AllRecords = N'N'
select MyColumn
from MyTable
where (MyValue = #MyParameter or #AllRecords = N'Y')
Hopefully, I won't ever have to implement a system that mixes flags and data value in this way.
UPDATED
Here is a version that should work with your expanded requirements (this requires one of the newer versions of SQL Server, I think):
declare #SelectedLevels table (LevelId int not null primary key)
if #LevelId = 3
insert into #SelectedLevels (LevelId) values (1), (2)
else if #LevelId = 5
insert into #SelectedLevels (LevelId) values (0), (1), (2)
else
insert into #SelectedLevels (LevelId) values (#LevelId)
select mt.MyColumn
from MyTable mt
inner join #SelectedLevels sl on sl.LevelId = MyTable.LevelId
if #Param = 3
begin
select *
from #T
end
else
if #Param = 2
begin
select *
from #T
where id in (0,1)
end
else
begin
select *
from #T
where id = #Param
end

tsql - using internal stored procedure as parameter is where clause

I'm trying to build a stored procedure that makes use of another stored procedure. Taking its result and using it as part of its where clause, from some reason I receive an error:
Invalid object name 'dbo.GetSuitableCategories'.
Here is a copy of the code:
select distinct top 6 * from
(
SELECT TOP 100 *
FROM [dbo].[products] products
where products.categoryId in
(select top 10 categories.categoryid from
[dbo].[GetSuitableCategories]
(
-- #Age
-- ,#Sex
-- ,#Event
1,
1,
1
) categories
ORDER BY NEWID()
)
--and products.Price <=#priceRange
ORDER BY NEWID()
)as d
union
select * from
(
select TOP 1 * FROM [dbo].[products] competingproducts
where competingproducts.categoryId =-2
--and competingproducts.Price <=#priceRange
ORDER BY NEWID()
) as d
and here is [dbo].[GetSuitableCategories] :
if (#gender =0)
begin
select * from categoryTable categories
where categories.gender =3
end
else
begin
select * from categoryTable categories
where categories.gender = #gender
or categories.gender =3
end
I would use an inline table valued user defined function. Or simply code it inline is no re-use is required
CREATE dbo.GetSuitableCategories
(
--parameters
)
RETURNS TABLE
AS
RETURN (
select * from categoryTable categories
where categories.gender IN (3, #gender)
)
Some points though:
I assume categoryTable has no gender = 0
Do you have 3 genders in your categoryTable? :-)
Why do pass in 3 parameters but only use 1? See below please
Does #sex map to #gender?
If you have extra processing on the 3 parameters, then you'll need a multi statement table valued functions but beware these can be slow
You can't use the results of a stored procedure directly in a select statement
You'll either have to output the results into a temp table, or make the sproc into a table valued function to do what you doing.
I think this is valid, but I'm doing this from memory
create table #tmp (blah, blah)
Insert into #tmp
exec dbo.sprocName

TSQL Hack needed for getting a filter for data

A UI (before the report shows) shows a look up (Combo) that has
(ID = 0).All Organization Units
(ID =4).HR
(ID = 5).DEV
I need to:
Be able to show data of (4) + (5) if
(0) is selected.
Only (4) OR (5) if either HR or DEV is selected.
Lookup combo code (Selected Feeds the parameter in the below query.)
Select 0 AS ID,'All Org' AS Name from DP_ORG_OrganizationUnit
where DP_ORG_OrganizationUnit.Code IN {AccessData}
Union
SELECT
DP_ORG_OrganizationUnit.ID,
DP_ORG_OrganizationUnit.Name
FROM DP_ORG_OrganizationUnit where DP_ORG_OrganizationUnit.Code IN ('HR','DEV')
Report data row query
SET CONCAT_NULL_YIELDS_NULL OFF
DECLARE #EmpID as int;
DECLARE #OrganizationUnit as int;
DECLARE #StartDate as datetime;
DECLARE #EndDate as datetime;
SET #EmpID = ?;
SET #StartDate = ?;
SET #EndDate = ?;
SET #OrganizationUnit = ?;
SELECT
Employee.Code,
Employee.Name1+' '+Employee.Name2+' '+Employee.Name3+' '+Employee.Name4+' '+Employee.Name5 AS FullName,
Employee.OrganizationUnit,
ContractType.Name,
EmployeeContract.StartDate,
EmployeeContract.EndDate
FROM Employee INNER JOIN (ContractType INNER JOIN EmployeeContract
ON ContractType.ID = EmployeeContract.ContractType)
ON Employee.ID = EmployeeContract.Employee
WHERE (Employee.ID = #EmpID OR #EmpID=0)
AND
(Employee.OrganizationUnit = #OrganizationUnit OR #OrganizationUnit=0)
AND NOT((EndDate < #StartDate or StartDate > #EndDate));
Any way I can achieve it from the looks of it? 0=0 would show all the data from other
departments too..
Anybody :-o?
First off, your lookup combo code could be tightened up a bit:
-- the FROM clause was superfluous
SELECT 0 AS ID,'All Org' AS Name
UNION ALL
-- the two-part identifiers were superfluous (only one table)
SELECT ID, Name
FROM DP_ORG_OrganizationUnit
WHERE Code IN ('HR','DEV')
For the report query, the simplest form would be:
WHERE
((#OrganizationUnit > 0 AND Employee.OrganizationUnit = #OrganizationUnit) OR
(#OrganizationUnit = 0 AND Employee.OrganizationUnit IN (4,5)))
something like this should work
Where (Employee.OrganizationUnit = case when #OrganizationUnit=0 then 4 else #OrganizationUnit end OR case when #OrganizationUnit=0 then 5 else #OrganizationUnit end)
Try this, which should use indexes on your query...
DECALRE #FilterValues (FilterValue int not null primary key)
IF #Param=0
BEGIN
INSERT INTO #FilterValues VALUES (4)
INSERT INTO #FilterValues VALUES (5)
END
ELSE ID #PAram IS NOT NULL
BEGIN
INSERT INTO #FilterValues VALUES (#Param)
END
SELECT
....
FROM YourTable y
INNER JOIN #FilterValues f ON y.Value=f.Value
WHERE .....
KM's version will work, but this query does not need a temp table...
SELECT *
FROM Employee
WHERE (
#OrganizationUnit = 0
OR
(
#OrganizationUnit <> 0
AND
Employee.OrganizationUnit = #OrganizationUnit
)
)
How about
WHERE (Employee.ID = #EmpID OR #EmpID=0)
AND
(Employee.OrganizationUnit BETWEEN ISNULL(NULLIF(#OrganizationUnit,0),0) AND ISNULL(NULLIF(#OrganizationUnit,0),99))
AND NOT((EndDate < #StartDate or StartDate > #EndDate));