I would like to return the column names for all columns containing an email address (... LIKE '%#%.%'). Is there a way to search fields for emails without doing it exhaustively? That is as soon as one email instance is found in the field the next is searched as oppose to looking at all its values? This is to scale better to large databases.
In the case below 'Foo' and 'Email' should be returned without searching all their records.
You could use conditional aggregation here:
SELECT
CASE WHEN SUM(Foo LIKE '%#%.%') > 0 THEN 'YES' ELSE 'NO' END AS Foo,
CASE WHEN SUM(Bar LIKE '%#%.%') > 0 THEN 'YES' ELSE 'NO' END AS Bar,
CASE WHEN SUM(Email LIKE '%#%.%') > 0 THEN 'YES' ELSE 'NO' END AS Email,
CASE WHEN SUM(Name LIKE '%#%.%') > 0 THEN 'YES' ELSE 'NO' END AS Name
FROM yourTable;
I'm creating a yes/no flag for SQL data and I have something similar to:
'''
CASE WHEN col_name IS NULL OR col_name = 0 THEN "N"
ELSE "Y"
END AS col_name_flag
'''
Is there any way to be more concise so I don't have to have the column name written out twice? Many of the column names are very long so I was wondering if there would be a way to make it more visually pleasing.
Probably the simplest method is to reverse the comparison:
(CASE WHEN col_name <> 0 THEN 'Y' ELSE 'N' END) AS col_name_flag
You could also use:
CASE IsNull(col_name,0) =0 THEN 'N' ELSE 'Y' END as col_name_flag
But I would go with Gordon's answer for performance...
I need to merge 3 rows into one with following condition - if at least one J exists in any of the columns then all columns should be overwritten with J. If there are all N I should get one row with all N.
I am thiking something like -
SELECT BRGNR
, AFTLST
,CASE WHEN EGMK IN ('J','N') THEN 'J' ELSE EGMK END EGMK
,CASE WHEN TDMK IN ('J','N') THEN 'J' ELSE TDMK END TDMK
,CASE WHEN UDMK IN ('J','N') THEN 'J' ELSE UDMK END UDMK
, CASE WHEN FUMK IN ('J','N') THEN 'J' ELSE FUMK END FUMK
FROM IF.TIF_BRUGER_BT
GROUP BY BRGNR
But the problem is then in that case when I have all N all values will be overwritten to J anyway, and I need to have N if all values are N
I am going to interpret the question as:
If a there is a 'J' in a column, then result is 'J'.
Otherwise, if all are 'N', then result in 'N'.
I will assume that the only values are 'J' and 'N'. My guess is that 'J' --> "yes" and 'N' --> "no" and you want "yes" if any value is "yes".
If so, you can use MIN():
SELECT BRGNR, AFTLST,
MIN(EGMK), MIN(TDMK), MIN(UDMK), MIN(FUMK)
FROM IF.TIF_BRUGER_BT
GROUP BY BRGNR, AFTLST
I am trying to figure out how to turn multiple check box results in differnet fileds into seperate columns.
The current case statement below only tracked the lowest score into a a single filed called 'Activities Registered For (1) – (5)'. I would like to convert them into 5 columns 'a-e' where 'a' is always filled with a result, and if two options are checked the results are in 'a' and 'b'. The form can be filled in with up to all selections checked. The else statement appears to be an error, since there are to be at least one of the five boxes checked.
I am new to SQL and I adopted this from someone else, so I am sorry for not showing my previous attempts to resolve my issue.
,CASE
WHEN [1524#1] = 'Y' THEN '1'
WHEN [1525#1] = 'Y' THEN '2'
WHEN [1526#1] = 'Y' THEN '3'
WHEN [1527#1] = 'Y' THEN '4'
WHEN [1528#1] = 'Y' THEN '5'
ELSE ' ' END AS 'Activities Registered For (1) – (5)'
You could use a PIVOT but multiple CASEs are just as effective, use about the same amount of code and is easier for beginners to decipher.
CASE WHEN [1524#1] = 'Y' THEN 1 ELSE 0 END AS ACTIVITY_1,
CASE WHEN [1525#1] = 'Y' THEN 1 ELSE 0 END AS ACTIVITY_2,
CASE WHEN [1526#1] = 'Y' THEN 1 ELSE 0 END AS ACTIVITY_3,
CASE WHEN [1527#1] = 'Y' THEN 1 ELSE 0 END AS ACTIVITY_4,
CASE WHEN [1528#1] = 'Y' THEN 1 ELSE 0 END AS ACTIVITY_5
I don't think the ELSE is necessarily an error. I often add an ELSE than shouldn't be used in case there is unexpected data (no Y in any field in your example).
Here's some info on PIVOTs if you want to check it out:
http://www.codeproject.com/Tips/500811/Simple-Way-To-Use-Pivot-In-SQL-Query
I have a SQL Select statement where I need to return certain values depending on a condition. I need to return multiple values each time, but my understanding of the Case statement is that you can only return a single value for each case.
I'm getting around this by using UNION statements at the moment, but it all looks a bit cumbersome - is there a better way to do this? Basically, I have a bunch of prompts, each with a response of either "Yes", "No" or "In Future" (I actually have more responses, but I'll just use 3 for the example to keep it short!) - I need to produce a column for each response type, with a 1 as the value for the appropriate response, and a 0 for all others. It's probably clearer to understand if you look at the SQL...
My (simplified) query looks like this:
SELECT branch,
promptType,
response,
1 AS 'Yes',
0 AS 'No',
0 AS 'Not Discussed'
FROM prompts
WHERE response = 'Y'
UNION
SELECT branch,
promptType,
response,
0 AS 'Yes',
1 AS 'No',
0 AS 'Not Discussed'
FROM prompts
WHERE response = 'N'
UNION
SELECT branch,
promptType,
response,
0 AS 'Yes',
0 AS 'No',
1 AS 'Not Discussed'
FROM prompts
WHERE response = 'D'
Something like...
SELECT branch,
prompttype,
CASE WHEN response = 'Y' THEN 'Yes'
WHEN response = 'N' THEN 'No'
WHEN response = 'D' THEN 'Not Discussed'
FROM prompts;
might be what you are after.
After your comment, perhaps...
SELECT branch,
prompttype,
CASE WHEN response = 'Y' THEN 1 ELSE 0 AS Yes,
CASE WHEN response = 'N' THEN 1 ELSE 0 AS No,
CASE WHEN response = 'D' THEN 1 ELSE 0 AS Not_Discussed
FROM prompts;
might do it.
Have you considered creating a decoding table for the responses, and joining to that?
For example, this would create a table for decoding the responses:
CREATE TABLE decoder (response CHAR(1), [Yes] BIT, [No] BIT, [Not Discussed] BIT)
INSERT INTO decoder VALUES ('Y', 1, 0, 0)
INSERT INTO decoder VALUES ('N', 0, 1, 0)
INSERT INTO decoder VALUES ('D', 0, 0, 1)
...and then you could join to it to get similar (the same?) results as you're getting with your UNION:
SELECT
prompts.branch,
prompts.prompttype,
prompts.response,
decoder.yes,
decoder.no,
decoder.[Not Discussed]
FROM
prompts INNER JOIN decoder ON prompts.response = decoder.response
Might be an approach worth considering; it's a more relational solution than your union, and probably easier to maintain.
You need to add grouping, I think. I did this with quarterly projections. If you have a unique ID for each response, it would be something like this (otherwise it will pick max for the whole branch/prompttype/response):
SELECT uniqueID,
branch,
prompttype,
response,
MAX(CASE WHEN response = 'Y' THEN 1 ELSE 0 END) AS Yes,
MAX(CASE WHEN response = 'N' THEN 1 ELSE 0 END) AS [No],
MAX(CASE WHEN response = 'D' THEN 1 ELSE 0 END) AS Not_Discussed
FROM prompts
GROUP BY uniqueID,
branch,
prompttype,
response;
SELECT branch,
prompttype,
response,
CASE WHEN response = 'Y' THEN 1 ELSE 0 END AS Yes,
CASE WHEN response = 'N' THEN 1 ELSE 0 END AS [No],
CASE WHEN response = 'D' THEN 1 ELSE 0 END AS Not_Discussed
FROM prompts;
If this proposed CASE statement of yours returned multiple values in a single column, what would the data type be: an array, a list, a table, an XML document, a business object, etc? For a truly relational database management system (TRDBMS), the answer would be a relation variable. But we are talking about SQL Server, here.
I think the answer you are looking for is that SQL Server's data types are scalar, not multivalued.