Table
RawID data
1 A
2 B
3 C
4 D
I have value RawID list (2,4,5). I want to know (2,4,5) is existed or not.
i have tried below
SELECT CASE WHEN EXISTS(SELECT * FROM table WHERE rawid IN (2,4,5)) THEN 1 ELSE 0 END
But 2, 4 is existed on table, it returned '1'.
But i want to get '0' because (2,4,5) all value is not existed on table.
if (1,2,3), return 1
if (2,3), return 1,
if (1,3,4) return 1
if (1,5) return 0
if (2,6) return 0
Could you give to me idea to check that all data is existed on table or not using SQL Query??
check for number no rows that matches the input. Example for rawid 2, 4, 5 there should be 3 rows
select case when (select count(*) from table where rawid in (2, 4, 5)) = 3
then 1
else 0
end
select case when (select count(*) from table where rawid in (2, 3)) = 2
then 1
else 0
end
If you want flexibility, you can do:
with vals as (
select *
from (values (2, 4, 5)) v(val)
)
select (case when count(*) = max(c.cnt) then 1 else 0 end)
from t join
vals
on t.rawid = v.val cross join
(select count(*) as cnt from vals) c;
This looks a little more complicated than other solutions, but you only have to change the values() line in the query for it to work on any number of values.
(This assumes that rowid has no duplicates.)
Related
I have a table bawe_services. i want to fetch all data that match with given keys
like i have fields
id | Service_id |bawe_id
1 2 2
2 3 3
3 2 3
if i pass service =2 i need all record of service_id=2 if i pass service=1,2,3 than i want 0 rows because 1 service is not given by any bawe so. i got 0 rows.
I use this query
select * from aspnet_bawe_services where ser_id in(1,2,3)
Thanx in advance
The count of the parameters in the "in" statement must match the having equal number.
select bawe_id from [dbo].[aspnet_bawe_services]
where Service_id in (2)
group by bawe_id
having count(Service_id)=1;
bawe_id
-----------
2
3
select bawe_id from [dbo].[aspnet_bawe_services]
where Service_id in (2,3)
group by bawe_id
having count(Service_id)=2;
bawe_id
-----------
3
select bawe_id from [dbo].[aspnet_bawe_services]
where Service_id in (1,2,3)
group by bawe_id
having count(Service_id)=3;
bawe_id
-----------
(0 row(s) affected)
TRY THIS: It's really tedious but unique requirement and I think to accomplish this, we have to use function
1-Function returns distinct count of service_id
2-Function to split comma separated value and return in table format
--Function returns distinct count of service_id
CREATE FUNCTION [dbo].[getCount](#service_id varchar(500))
RETURNS INT
AS
BEGIN
DECLARE #count int
SELECT #count = COUNT(DISTINCT(t.service_id))
FROM tmptos t
INNER JOIN [dbo].[SplitValue](#service_id, ',') tt on t.service_id = tt.items
RETURN #count
END;
--Function to split comma separated value and return in table format
--Function copied from
--separate comma separated values and store in table in sql server
CREATE FUNCTION [dbo].[SplitValue](#String varchar(MAX), #Delimiter char(1))
RETURNS #temptable TABLE (items VARCHAR(MAX))
AS
BEGIN
DECLARE #idx int
DECLARE #slice varchar(8000)
SELECT #idx = 1
if len(#String)<1 or #String is null return
WHILE #idx!= 0
BEGIN
set #idx = charindex(#Delimiter,#String)
IF #idx!=0
set #slice = left(#String,#idx - 1)
else
set #slice = #String
IF(LEN(#slice)>0)
INSERT INTO #temptable(Items) values(#slice)
SET #String = right(#String,len(#String) - #idx)
IF LEN(#String) = 0 break
END
RETURN
END;
--Table with Sample Data
create table tmptos(id int, Service_id int, bawe_id int)
insert into tmptos values
(1, 2, 2),
(2, 3, 3),
(3, 2, 3)
declare #service_id varchar(50) = '2,3'
select *
from tmptos t
inner join [dbo].[SplitValue](#service_id, ',') tt on t.Service_id = tt.items
where [dbo].[getCount](#service_id) = (select count(distinct(items)) from [dbo].[SplitValue](#service_id, ','))
OUTPUT:
id Service_id bawe_id items
1 2 2 2
2 3 3 3
3 2 3 2
It's bit lengthy but works perfectly.
select * from aspnet_bawe_services
where Service_id in (1,2,3)
and
( select count(distinct Service_id) from aspnet_bawe_services where Service_id in (1,2,3) ) = 3
last number in query (in this case "3") is elements count, which you have in IN list.
You can get the service ids that you want using group by and having:
select service_id
from t
where bawe_id in (1, 2, 3)
group by service_id
having count(distinct bawe_id) = 3;
The "= 3" is the number of ids in the IN list.
You can then use in or join or exists to get the full records:
select t.*
from t
where t.service_id in (select service_id
from t
where bawe_id in (1, 2, 3)
group by service_id
having count(distinct bawe_id) = 3
);
I am basically trying to run these two queries:
SELECT * FROM ProductTable;
SELECT CAST(CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS BIT)
FROM UserTable WHERE id = 41;
Both queries work properly. The first one returns me all the data in ProductTable. The second query returns me either 1 or 0 after checking if the row ID 41 exists
Running them together:
SELECT * FROM ProductTable SELECT CAST(CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS BIT)
FROM UserTable WHERE id = 41
However, when I run this, the second query does not return any value, this is because I have not set a SQL variable name to it.
How can I set a Variable name to the second query such that I can read that value when reading the SQL response?
DECLARE #val BIT
SELECT #val = CAST(CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS BIT)
FROM UserTable WHERE id = 41
SELECT P.*, #val FROM ProductTable P
If you need either 1 or 0 after checking if the row ID 41 exists then (following Pinwar13 answer) this code performs better, needn't count all rows
DECLARE #val BIT = CASE WHEN EXISTS (SELECT 1 FROM UserTable WHERE id = 41)
THEN 1 ELSE 0 END;
SELECT P.*, #val FROM ProductTable P
Try like this,
SELECT *
,(
SELECT CAST(CASE
WHEN COUNT(*) > 0
THEN 1
ELSE 0
END AS BIT)
FROM UserTable
WHERE id = 41
) AS UserCount
FROM ProductTable;
you can use cross apply also..
SELECT p.*,t.[BIT] FROM ProductTable p
CROSS APPLY (SELECT CAST(CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS [BIT])
FROM UserTable WHERE id = 41)t
Is there a way to have a custom table inside select statement?
Something like this:
select id from (1, 2, 3, 4) tbl
Assuming tbl is alias and the custom table has one column with 1, 2, 3, 4 rows.
Is this possible without creating a physical temp table?
Yes, you can do it (numbers table) like that in Oracle:
with tbl as (
-- generates table with id column with 1, 2, 3, 4 values
select level id
from dual
connect by level <= 4)
select id
from tbl
you can put the same in different syntax:
select id
from (select level id
from dual
connect by level <= 4) tbl
if you need arbitrary values, say 1, 5, 14, 127 you can achieve it like that:
with tbl as (
select 1 from dual
union all
select 5 from dual
union all
select 14 from dual
union all
select 127 from dual
)
select id
from tbl
Or
select id
from (select 1 from dual
union all
select 5 from dual
union all
select 14 from dual
union all
select 127 from dual) tbl
If you want to have syntax like from (1, 2, 3) you have to declare a type
create or replace type NumberTable is table of number;
...
select *
from table(NumberTable(1, 2, 3, 4)) tbl
create or replace type char_int is table of integer;
/
with numbers as (select column_value
from table(char_int(1,2,5,6,7)))
select numbers.column_value
, object_name
, object_id
from all_objects
join numbers on (substr(object_id,1,1) = numbers.column_value);
;
Output:
<snip>
1 V$HS_AGENT 1999
2 V$HS_SESSION 2001
<snip>
getName_as_Rows is an array which contains some names.
I want to set an int value to 1 if record found in data base.
for(int i = 0; i<100; i++)
{
using (var command = new SqlCommand("select some column from some table where column = #Value", con1))
{
command.Parameters.AddWithValue("#Value", getName_as_Rows[i]);
con1.Open();
command.ExecuteNonQuery();
}
}
I am looking for:
bool recordexist;
if the above record exist then bool = 1 else 0 with in the loop.
If have to do some other stuff if the record exist.
To avoid making N queries to the database, something that could be very expensive in terms of processing, network and so worth, I suggest you to Join only once using a trick I learned. First you need a function in your database that splits a string into a table.
CREATE FUNCTION [DelimitedSplit8K]
--===== Define I/O parameters
(#pString VARCHAR(8000), #pDelimiter CHAR(1))
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
--===== "Inline" CTE Driven "Tally Table" produces values from 0 up to 10,000...
-- enough to cover VARCHAR(8000)
WITH E1(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), --10E+1 or 10 rows
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS (--==== This provides the "zero base" and limits the number of rows right up front
-- for both a performance gain and prevention of accidental "overruns"
SELECT 0 UNION ALL
SELECT TOP (DATALENGTH(ISNULL(#pString,1))) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
),
cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter)
SELECT t.N+1
FROM cteTally t
WHERE (SUBSTRING(#pString,t.N,1) = #pDelimiter OR t.N = 0)
)
--===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found.
SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY s.N1),
Item = SUBSTRING(#pString,s.N1,ISNULL(NULLIF(CHARINDEX(#pDelimiter,#pString,s.N1),0)-s.N1,8000))
FROM cteStart s
GO
Second, concatenate your 100 variables into 1 string:
"Value1", "Value 2", "Value 3"....
In Sql Server you can just join the values with your table
SELECT somecolumn FROM sometable t
INNER JOIN [DelimitedSplit8K](#DelimitedString, ',') v ON v.Item = t.somecolumn
So you find 100 strings at a time with only 1 query.
Use var result = command.ExecuteScalar() and check if result != null
But a better option than to loop would be to say use a select statement like
SELECT COUNT(*) FROM TABLE WHERE COLUMNVAL >= 0 AND COLUMNVAL < 100,
and run ExecuteScalar on that, and if the value is > 0, then set your variable to 1.
I am having trouble trying to represent the below SQL (which returns the results I want) in LINQ:
select
case r.CategoryID
when 2 then
case r.PrimaryRecord
when 1 then r.RecordID
else (select RecordID from Record where RecordGroupID = r.RecordGroupID and PrimaryRecord = 1)
end
else
r.RecordID
end
as RecordID
, r.FooID
from Record r
where
r.FooID = 3
Each row in the Record table has a unique RecordID. Multiple RecordID's could be associated with a RecordGroupID for CategoryID 2, but only one of them will have the PrimaryRecord field value of 1.
Given the below table of data, my desired output is RecordID = 1, FooID = 3, i.e. the RecordID for the given RecordGroupID that is the PrimaryRecord, but the FooID for the given row that matches my Where clause.
RecordID RecordGroupID PrimaryRecord CategoryID FooID
1 1 1 2 1
2 1 0 2 1
3 1 0 2 3
I appreciate the SQL itself probably isn't the most efficient SQL in the world but it was the best I could come up with.
If anyone could help me create the LINQ statement to represent this query that would be great.
I think you don't really need the case in the original query. Try something like:
var matchingRecords = from r in Records
where r.FooId = fooId && r.CategoryId == catId && r.RecordGroupId == groupId
join r2 in Records on r.RecordGroupId == r2.RecordGroupId && r.CategoryId == r2.CategoryId && r2.PrimaryRecord
select r2;
Edit: added CategoryId in join, assuming RecordGroupId is only unique inside a category.