Venn operation in SQL query - sql

I have a table with list of employees who can be admin, dev, both or none
EMP_ID IS_ADMIN IS_DEV
1 Y Y
2 Y N
3 N Y
4 N N
I want to write a query so that when I request
IS_ADMIN=Y returns 1,2
IS_DEV=Y returns 1,3
IS_DEV=Y, IS_ADMIN=Y returns 1,2,3
IS_DEV=N, IS_ADMIN=N or nothing returns 4
Is there anyway to incorporate this login in one query?

You specify all the options as parameters, passing null to any parameter you don't care for and checking for null as a query condition. Your logic is a bit bent so it have to be programmed for exactly, every combination:
SELECT
emp_id
FROM
emps
WHERE
(is_admin = 'Y' AND :isadmin = 'Y' AND :isdev is null)
OR
(is_dev = 'Y' AND :isdev = 'Y' AND :isadmin is null)
OR
(:isadmin = 'Y' AND :isdev = 'Y' AND (is_admin = 'Y' OR is_dev = 'Y'))
OR
(COALESCE(:isadmin, 'N') = 'N' AND COALESCE(:isdev, 'N') = 'N' AND is_admin = 'N' AND is_dev = 'N')
Your calling language of choice would set the parameters to 'Y', 'N' or null if it had no opinion, e.g. in c# for your case 1:
sqlCommand.Parameters["isadmin"].Value = "Y";
sqlCommand.Parameters["isdev"].Value = DBNull.Value;
using(var reader = sqlCommand.ExecuteReader()) ....

Related

1 result using COUNT in multiple columns Using sql

I have table called questions Survey. I sent them a survey in Jan_2018, March_2018, Sept_2018, Jan_2017, March_2017, Sept_2017. I'm trying to get the sum of people that received the email and answer the questions. The table only has YES( Y), NO (N)]. Not sure, if this queries is the best to use as it gave me a lower numbers that I think is incorrect. I used this queries:
SELECT COUNT (*) AS 'Questions_Results'
FROM [DEV].[dbo].[Questions_survey]
WHERE [Jan_2018] = 'Y'
AND [March_2018] = 'Y'
AND [Sept_2018] = 'Y'
AND [Jan_2017] = 'Y'
AND [March_2017] = 'Y'
AND [Sept_2017] = 'Y'
AND [2017_Jan_Test_open] = 'Y'
AND [2017_March_Test_open] = 'Y'
AND [2017_Sept_Test_open] = 'Y'
If you want the overall number of people who answered your survey, just use OR instead of AND :
SELECT COUNT (*) AS 'Questions_Results'
FROM [DEV].[dbo].[Questions_survey]
WHERE [Jan_2018] = 'Y'
OR [March_2018] = 'Y'
OR [Sept_2018] = 'Y'
OR [Jan_2017] = 'Y'
OR [March_2017] = 'Y'
OR [Sept_2017] = 'Y'
OR [2017_Jan_Test_open] = 'Y'
OR [2017_March_Test_open] = 'Y'
OR [2017_Sept_Test_open] = 'Y'
I think this is the best way to do it.
AND returns the count of records where survey has been generated for all months. If you want total individual survey numbers use OR
SELECT COUNT (*) AS 'Questions_Results' FROM [DEV].[dbo].[Questions_survey] WHERE [Jan_2018] = 'Y' OR [March_2018] = 'Y' OR [Sept_2018] = 'Y' OR [Jan_2017] = 'Y' OR [March_2017] = 'Y' OR [Sept_2017] = 'Y' OR [2017_Jan_Test_open] = 'Y' OR [2017_March_Test_open] = 'Y' OR [2017_Sept_Test_open] = 'Y'
If you want the number of emails sent, then presumably you want:
SELECT COUNT(*) AS Questions_Results
FROM [DEV].[dbo].[Questions_survey]
WHERE 'Y' IN (Jan_2018, March_2018, Sept_2018, Jan_2017, March_2017, Sept_2017);
I'm not sure what the "test_open" columns are. They are not mentioned in the question itself. Are they related to "answering the questions"?
If a "person" can be on more than one row, then you may need COUNT(DISTINCT) using whatever column specifies the person:
SELECT COUNT(DISTINCT person_id) AS Questions_Results
FROM [DEV].[dbo].[Questions_survey]
WHERE 'Y' IN (Jan_2018, March_2018, Sept_2018, Jan_2017, March_2017, Sept_2017);

SQL Server CASE statement with mupltiple conditionals syntax

I have a need to add a case statement into a select, but I cannot seem to get the syntax right, could anyone help?
SELECT
uuid = pnt.ID
,extras = (CASE (SELECT pnt.TypeID as [type], pnt.Source as source)
WHEN source = 7 THEN 'a'
WHEN source = 1 AND [type] = 0 THEN 'b'
WHEN source = 8 THEN 'c'
WHEN source = 2 AND [type] = 0 THEN 'd'
WHEN source = 3 AND [type] IN (5,6,7,8) THEN 'e'
ELSE NULL
END)
FROM
Mydata as pnt
There are multiple problems, the select within the case is incorrect, the condition source = 7 is wrong, the combining conditions with an AND is wrong and the condition using IN is incorrect.
I used the answer to Multiple Criteria In Case Statement as a basis for the case statement.
SELECT
#uuid = pnt.ID
,#extras = (CASE WHEN source = 7 THEN
'a'
WHEN source = 1 AND [type] = 0 THEN
'b'
WHEN source = 8 THEN
'c'
WHEN source = 2 AND [type] =0 THEN
'd'
WHEN source = 3 AND [type] IN (5,6,7,8) THEN
'e'
ELSE NULL
END
)
FROM
Mydata as pnt
There are two types of case statements:
A simple case statement that compares an expression to a set of simple expressions to return specific values.
A searched case statement that evaluates a set of Boolean expressions to return specific values.
https://msdn.microsoft.com/en-us/library/ms144841(v=sql.105).aspx
In your script your're "mixing" them, so that your script doesn't work.
This could be a good solution:
SELECT
pnt.ID
,CASE
WHEN pnt.source = 7 THEN 'a'
WHEN pnt.source = 1 AND pnt.TypeID = 0 THEN 'b'
WHEN pnt.source = 8 THEN 'c'
WHEN pnt.source = 2 AND pnt.TypeID = 0 THEN 'd'
WHEN pnt.source = 3 AND pnt.TypeID IN (5, 6, 7, 8) THEN 'e'
ELSE NULL
END
FROM
#Mydata AS pnt
Warning!
If you need to populate single variables (uuid, extras) you have to be sure that your query's result will have only 1 record
SELECT
PNT.ID AS UUID
, CASE
WHEN PNT.source = 7 THEN 'a'
WHEN PNT.source = 1 AND PNT.[type] = 0 THEN 'b'
WHEN PNT.source = 8 THEN 'c'
WHEN PNT.source = 2 AND PNT.[type] = 0 THEN 'd'
WHEN PNT.source = 3 AND PNT.[type] IN (5, 6, 7, 8) THEN 'e'
ELSE NULL
END AS EXTRAS
FROM Mydata AS PNT
As you are already working within the table Mydata a case expression has access to the values held in [source] and [type] without an added select.
I have put the column aliases at the end of each column definition, I believe this is more generally supported by databases than using = for that purpose.
SELECT ID As uuid, CASE WHEN Source = 7 THEN
'a'
WHEN Source = 1 AND TypeID= 0 THEN
'b'
WHEN Source = 8 THEN
'c'
WHEN Source = 2 AND TypeID= 0 THEN
'd'
WHEN Source = 3 AND TypeID IN (5,6,7,8) THEN
'e'
ELSE
NULL
END
AS extras FROM Mydata

counting records on the same table with different values possibly none sql server 2008

I have a inventory table with a condition i.e. new, used, other, and i am query a small set of this data, and there is a possibility that all the record set contains only 1 or all the conditions. I tried using a case statement, but if one of the conditions isn't found nothing for that condition returned, and I need it to return 0
This is what I've tried so far:
select(
case
when new_used = 'N' then 'new'
when new_used = 'U' then 'used'
when new_used = 'O' then 'other'
end
)as conditions,
count(*) as count
from myDB
where something = something
group by(
case
when New_Used = 'N' then 'new'
when New_Used = 'U' then 'used'
when New_Used = 'O' then 'other'
end
)
This returns the data like:
conditions | count
------------------
new 10
used 45
I am trying to get the data to return like the following:
conditions | count
------------------
new | 10
used | 45
other | 0
Thanks in advance
;WITH constants(letter,word) AS
(
SELECT l,w FROM (VALUES('N','new'),('U','used'),('O','other')) AS x(l,w)
)
SELECT
conditions = c.word,
[count] = COUNT(x.new_used)
FROM constants AS c
LEFT OUTER JOIN dbo.myDB AS x
ON c.letter = x.new_used
AND something = something
GROUP BY c.word;
try this -
DECLARE #t TABLE (new_used CHAR(1))
INSERT INTO #t (new_used)
SELECT t = 'N'
UNION ALL
SELECT 'N'
UNION ALL
SELECT 'U'
SELECT conditions, ISNULL(r.cnt, 0) AS [count]
FROM (
VALUES('U', 'used'), ('N', 'new'), ('O', 'other')
) t(c, conditions)
LEFT JOIN (
SELECT new_used, COUNT(1) AS cnt
FROM #t
--WHERE something = something
GROUP BY new_used
) r ON r.new_used = t.c
in output -
new 2
used 1
other 0
You can do it as a cross-tab:
select
sum(case when new_used = 'N' then 1 else 0 end) as N,
sum(case when new_used = 'U' then 1 else 0 end) as U,
sum(case when new_used = 'O' then 1 else 0 end) as Other
from myDB
where something = something

T-SQL IF-ELSE

Is it possible to do something like this with IF-ELSE, or something similar:
SELECT
MemberID,
ProfileTypeID
PrCountryID, -- 3
PrStateID, -- 4
PrStateInt
FROM Member
WHERE PrCity IS NOT NULL
IF #ShowUnclaimed = 'N'
AND Claimed = 'Y'
AND SBIcon = 'N'
END
AND Viewable = 'Y'
AND SystemID = 2
Many thanks in advance for any information.
neojakey
No need to use Case for this one
SELECT
MemberID,
ProfileTypeID
PrCountryID, -- 3
PrStateID, -- 4
PrStateInt
FROM Member
WHERE PrCity IS NOT NULL
AND Viewable = 'Y'
AND SystemID = 2
AND ( #ShowUnclaimed != 'N'
OR ( Clamed = 'Y' AND SBIcon = 'N' )
)
You're looking for the case expression (MSDN)
SELECT MemberID,
ProfileTypeID
PrCountryID, -- 3
PrStateID, -- 4
PrStateInt
FROM Member
WHERE PrCity IS NOT NULL
AND CASE
WHEN #ShowUnclaimed = 'N' AND Claimed = 'Y' AND SBIcon = 'N' THEN 1
END = 1
AND Viewable = 'Y'
AND SystemID = 2
If I understand your intention correctly there is no need for IF, or CASE for that matter.
Just something like this seems to be what you were trying to do...?
WHERE PrCity IS NOT NULL
AND (#ShowUnclaimed = 'Y'
OR (Claimed = 'Y'
AND SBIcon = 'N'))
AND Viewable = 'Y'
AND SystemID = 2
Give this a try using CASE:
SELECT
MemberID,
ProfileTypeID
PrCountryID, -- 3
PrStateID, -- 4
PrStateInt
FROM Member
WHERE PrCity IS NOT NULL
AND Viewable = 'Y'
AND SystemID = 2
AND Claimed = CASE WHEN #ShowUnclaimed = 'N' THEN 'Y' ELSE Claimed END
AND SBIcon = CASE WHEN #ShowUnclaimed = 'N' THEN 'N' ELSE SBIcon END
This is just one way to do it. Best of luck.

Using IF..ELSE in UPDATE (SQL server 2005 and/or ACCESS 2007)

I need to set a query like below:
UPDATE XXXXXX
IF column A = 1 then set column B = 'Y'
ELSE IF column A = 2 then set column C = 'Y'
ELSE IF column A = 3 then set column D = 'Y'
and so on and so forth...
I am able to do this using multiple queries but was wondering, if I can do it in just 1 statement instead.
this should work
update table_name
set column_b = case
when column_a = 1 then 'Y'
else null
end,
set column_c = case
when column_a = 2 then 'Y'
else null
end,
set column_d = case
when column_a = 3 then 'Y'
else null
end
where
conditions
the question is why would you want to do that...you may want to rethink the data model. you can replace null with whatever you want.
Yes you can use CASE
UPDATE table
SET columnB = CASE fieldA
WHEN columnA=1 THEN 'x'
WHEN columnA=2 THEN 'y'
ELSE 'z'
END
WHERE columnC = 1