Compare values in select statement and insert into new table - sql-server

I have a column where the values need to be cleansed. I would like to find a way where I can directly compare the values from my select distinct statement and compare with all the values in the column and insert into a new table
Currently I am using a case statement but that is taking too long because the distinct values are many. I dont want to type them, is there an easier way that I can do this
select id, name,
case category
when 'Madras' then 'Chennai'
when 'Madres' then 'Chennai'
when 'Medres' then 'Chennai'
when 'Bombay' then 'Mumbai'
when is null then 'unknown'
else 'default values'
end
from city

Related

CASE returns Chinese characters when asked to return a VARBINARY column value

I am trying to retrieve values from a key/value table using the following query. In case the value of the key column is "OrderNumber" or "CustomerNumber", then, instead of the val column, I would like to have another column's value (valHash) from the same key/value table (we can almost call it a key/value/hashvalue table).
But when I run the query I get Chinese characters when my CASE meets its first condition:
SELECT IssueId,
customfield,
CASE
WHEN customfield IN ('OrderNumber', 'CustomerNumber') THEN valHash
ELSE val
END AS Value,
valHash
FROM MyTable
The valHash column data type is VARBINARY.
The problem may occur in Val. Since one column has one datatype, you could opt for this:
SELECT IssueId,
customfield,
CASE
WHEN customfield IN ('OrderNumber', 'CustomerNumber') THEN valHash
ELSE CAST (val AS VARBINARY (500))
END AS Value,
valHash
FROM MyTable
If you want everything as a string, you might want to use this:
SELECT IssueId,
customfield,
CASE
WHEN customfield IN ('OrderNumber', 'CustomerNumber') THEN CONVERT (NVARCHAR (50), Valhash, 2)
ELSE val )
END AS Value,
valHash
FROM MyTable
If you insist on differentiation between VARCHAR and VARBINARY is different cases, you need an extra column.

How to loop with different values in T-SQL query?

I have some specific set of values that I want to filter on a column, I don't want to do an 'in' clause in SQL Server. I want to use loop to pass in different set of values each time.
For example if there is a name column in my data, and I want to run query 5 times with different filter value.
Please look at the loop query attached below.
DECLARE #cnt INT = 1;
WHILE #cnt < 94
BEGIN
SELECT Name, COUNT(*) AS Number_of_Names
FROM Table
WHERE name IN ('John')
AND value IS NOT NULL
GROUP BY Name
SET #cnt = #cnt + 1;
END;
I want to pass in different values under 'name' column at each loop like john in the case above, then mary in the next loop likewise based on set of values I pass in the variable like #values = John,Mary,Nicole,matt etc..
Considering the comments on your question, this should give you an idea on how to achieve a solution without using loops and still get all the names even when the name is not present on the table.
SELECT Name,
COUNT(value) AS Number_of_Names --Only count when value is not null
FROM (VALUES('John'), ('Mary'), ('Nicole'), ('Matt'))Names(name) --This can be replaced by a table-valued parameter or temp table.
LEFT JOIN Table t ON Names.name = t.name
--WHERE name IN ('John') /*No longer needed*/
--AND value IS NOT NULL /*Removed this because it would make the OUTER JOIN behave as an INNER JOIN*/
GROUP BY Name;

TSQL Distinct List of departments based on current user

I couldn't even think of how to phrase this properly for the title.
I have an SSRS report with a multi-valued parameter called Department.
If the user IS IN Department A..We want to default to all departments EXCEPT department A
If the user IS NOT IN Department A..We want to default to only their department
Department A will never be in the parameter list but being a member of department A impacts what you will see.
I know that I could resolve this with an ALL parameter option, but I would prefer the only parameter values to be valid department names
My parameter is populated with two datasets.
The first dataset has three options for valid departments: EUR, REM, LIFA
The second dataset only determines the current user's department and would populate the default. IF the current user's department is CS we want to select the other three departments as the default. If their department <> CS we want to default to only their department.
I thought the code below would work but the concatenated string is not an option in the first dataset so it cannot be the default option
SELECT DISTINCT
CASE
WHEN EmployeePracticeArea = 'CS'
THEN 'EUR, LIFA, REM'
ELSE EmployeePracticeArea
END AS 'EmployeePracticeArea'
FROM DimEmployee
WHERE
(EmployeePracticeArea <> '')
AND (UserLogin = #CurrentUser)
The problem with the case statement is that it tries to set a default value of EUR, LIFA, REM. This string does not exist in the 'options' list of values. The options are the three seperate strings EUR, LIFA, REM.
Case statements cannot return multiple values so I need to evaluate the current user's department and then return a list without it
Here is something which will generate the dataset for you
IF OBJECT_ID('tempdb..#TestData') IS NOT NULL
DROP TABLE #TestData;
WITH Data (EmployeePracticeArea) AS (
SELECT 'LIFA'
UNION
SELECT 'REM'
UNION
SELECT 'EUR'
UNION
SELECT 'CS'
)
SELECT * INTO #TestData FROM Data ;
The end result is like this:
User1 in the LIFA department has his parameter defaulted to just LIFA
User2 in the CS department has his parameter defaulted to EUR, LIFA, REM
DECLARE #t TABLE(Dept varchar(4))
DECLARE #CurrentUserDept varchar(4) = (SELECT EmployeePracticeArea FROM dimEmployee WHERE UserLogin = #CurrentUser)
IF #CurrentUserDept = 'CS'
BEGIN
INSERT INTO #t VALUES ('EUR'), ('LIFA'), ('REM')
END
ELSE
BEGIN
INSERT INTO #t SELECT #CurrentUserDept
END
SELECT * FROM #t

Update inserts different hash values than a select does

I am trying to update a new column in my SQL Server user table with the hash of another column.
when I test the conversion with a select statement it will return the correct MD5 hash that I get from online hash generators.
select CONVERT(VARCHAR(32), HashBytes('MD5', 'valuetohash'), 2)
when I use this same conversion in an update statement as shown below I get a different value, inserted then the select statement with the same value hashed.
UPDATE users SET [newcolumn1] = CONVERT(VARCHAR(32), HashBytes('MD5', column1), 2)
what am I doing wrong?
The value you have in users.column1 does not exactly match the value you are manually passing through HashBytes as a test. To confirm that this works when the values are the same, try:
DECLARE #users TABLE (
column1 VARCHAR(100),
newcolumn1 VARCHAR(32)
)
INSERT INTO #users
SELECT 'some text', NULL
SELECT CONVERT(VARCHAR(32), HashBytes('MD5', 'some text'), 2)
UPDATE #users SET newcolumn1 = CONVERT(VARCHAR(32), HashBytes('MD5', column1), 2)
SELECT newcolumn1 FROM #users
You'll see that the results you get from each SELECT are the same, because the values of 'some text' and #users.column1 are identical.
Try comparing your values first:
SELECT CASE WHEN column1 = 'expectedValue'
THEN 'MATCH'
ELSE 'DIFFERENCE'
END AS MatchCheck
FROM users
or
SELECT column1
FROM users
WHERE column1 = 'expectedValue'
If you get results from the first query where MatchCheck = 'MATCH' or results from the second query at all, then you should also get results form your UPDATE which give the hash you expect, as the values are the same.
As mentioned by ughai in the comments, it's most likely you have some spaces or non-printable characters in the values in your database which you are not including when you dry-run the hashing, hence the different results.

Displaying NULL values as 'unknown' in SQL Server

I have a table that has two columns; one for Name (datatype nvarchar), the other for ID (datatype int and allows null).
I am trying to display all data from the table including those with null values but I want the query result to display the null value as 'unknown'.
I ran the following query:
Select Name, ID
Case
When ID is null then 'unknown'
When id is not null then (ID)
End
From table
The problem is I am getting this message:
Conversion failed when converting the varchar value 'unknown' to data type int
I guess you could cast your integers to a varchar
You can also use COALESCE instead of case when dealing with nulls.
Select Name, COALESCE(CAST(ID AS VARCHAR(10)),'unknown') AS ID
From table
You can use COALESCE function
Select Name, coalesce(convert(varchar(20),ID), 'unknown')
From table

Resources