SQL Subquery to replace all values - sql

I have a query which returns a bunch of different data, however I want to have it replace all the values upon a certain condition.
What I have written below kind of gives me the result I want but not really. It creates a new column instead of replacing the other one:
SELECT
CASE
WHEN T4.[U_DestType] = '6'
THEN (SELECT
'Company Limited' AS [ShipToCode]
)
END AS [ShipToCode],
T2.[ShipToCode],
T6.[StreetS],
T6.[StreetNoS],
T6.[CityS],
T6.[ZipCodeS],
T6.[CountryS],
T5.[LicTradNum],
T2.[CardCode],
T4.[Phone1],
T4.[E_Mail],
T4.[U_DestType],
CASE
WHEN T4.[Country] = 'GB'
THEN 'EN'
ELSE T4.[Country]
END AS [Country],
T4.[U_ShortName]
FROM[...]
The end goal is to replace all of the columns with some preset values instead of just ShipToCode as above.
I tried putting an EXIST subquery after FROM too but that didn't work either.
Is this possible? I'm probably missing something very obvious.
Many thanks!

You can use an ELSE in your CASE expression to combine the two "columns":
CASE
WHEN T4.[U_DestType] = '6'
THEN (SELECT
'Company Limited' AS [ShipToCode]
)
ELSE T2.[ShipToCode]
END AS [ShipToCode],
And by the way, you didn't need to use a Sub-Select. This would work just as well and is easier to read:
CASE
WHEN T4.[U_DestType] = '6' THEN 'Company Limited'
ELSE T2.[ShipToCode]
END AS [ShipToCode],

Related

How do I use conditions properly in PSQL?

I wanted to do a condition wherein I put values (000000) in DATE_COMPLETED if it see's the FLAG_CLOSED = Y and if its not Y then do nothing
SELECT
"JOB",
"SUFFIX",
"SUFFIX",
"DATE_COMPLETED",
"FLAG_CLOSED",
CASE "DATE_COMPLETED"
WHEN "FLAG_CLOSED"='Y'
THEN "DATE_COMPLETED"='000000'
END "DATE_COMPLETED"
FROM "JOB_OPERATIONS"
What I got
SQL Execution Error
[LNA][PSQL][SQL Engine]Syntax Error: SELECT
"JOB",
"SUFFIX",
"SUFFIX",
"DATE_COMPLETED",
"FLAG_CLOSED",
CASE "DATE_COMPLETED" WHEN "FLAG_CLOSED" << ??? >> = 'Y' THEN "DATE_COMPLETED" = '000000' END "DATE_COMPLETED"
FROM JOB_OPERATIONS
It looks like you're attempting to change the DATE_COMPLETED column in your table. You can't do that with a SELECT statement. CASE / WHEN / THEN helps construct output. UPDATE statements allow clauses like DATE_COMPLETED='000000' that change columns.
Try something like this.
SELECT "JOB", "SUFFIX", "SUFFIX", "DATE_COMPLETED", "FLAG_CLOSED",
CASE WHEN "FLAG_CLOSED"='Y' THEN '000000'
ELSE "DATE_COMPLETED" END "CLOSED_DATE_COMPLETED"
FROM "JOB_OPERATIONS"
I named your CASE-computed output column CLOSED_DATE_COMPLETED so it won't collide with the DATE_COMPLETED colum you already mentioned.
Syntax is either:
CASE a WHEN b
... or:
CASE when a=b
To return the value of DATE_COMPLETED depending on the flag, you can do this:
CASE "FLAG_CLOSED"
WHEN 'Y' THEN '000000'
ELSE "DATE_COMPLETED"
END AS "DATE_COMPLETED"
Beware that you need to produce a coherent column type. If DATE_COMPLETED is not text, you'll need to cast it.

Case statement handling logic differently than expected

I'm trying to assign a status based on the number of IDs using a metric. This is the query I've written (and it works):
select
x.yyyy_mm_dd,
x.prov_id,
x.app,
x.metric,
x.is_100,
case
when ((x.is_100 = 'true') or size(collect_set(x.list)) >10) then 'implemented'
when ((x.is_100 = 'false') and size(collect_set(x.list)) between 1 and 10) then 'first contact'
else 'no contact'
end as impl_status,
size(collect_set(x.list)) as array_size,
collect_set(x.list) as list
from(
select
yyyy_mm_dd,
prov_id,
app,
metric,
is_100,
list
from
my_table
lateral view explode(ids) e as list
) x
group by
1,2,3,4,5
However, the impl_status is incorrect for the second condition in the case statement. In the result set, I can see rows with is_100 = false, array_size between 1 and 10, however the impl_status ends up being 'no contact' instead of 'first contact'. I was thinking maybe between isn't inclusive but it seems to be according to the docs.
I am curious if this works:
(case when x.is_100 or count(distinct x.list) > 10
then 'implemented'
when (not x.is_100) and count(x.list) > 0
then 'first contact'
else 'no contact'
end) as impl_status,
This should be the same logic without the string comparisons -- here is an interesting viewpoint on booleans in Hive. I also think that COUNT() is clearer than the array functionality.
Be sure you have not some hidden space in the string
when (( trim(x.is_100) = 'false') and size(collect_set(x.list)) between 1 and 10) then 'first contact'

SQL case expression in UPDATE statement

I'm trying to map this particular SQL code for data warehousing purpose.
I have two columns (TARGET) and (NET_SALARY), purpose is to map NET_SALARY with 0 when TARGET is 700, in other cases sub-string net salary 1, 30
I'm receiving missing right parenthesis error
Both columns are varchar2 datatype
CASE
WHEN SRC_CUSTOMER.TARGET = '700' THEN SRC_CUSTOMER.NET_SALARY = '0'
ELSE SUBSTR(SRC_CUSTOMER.NET_SALARY,1,30)
END
If this is in a context of an ODI mapping/interface, you can only use SQL and not PL/SQL. You can't assign the value to SRC_CUSTOMER.NET_SALARY in the first THEN. You actually only need to set the value you want and it will be mapped to your target attribute.
Try with
CASE
WHEN SRC_CUSTOMER.TARGET = '700' THEN '0'
ELSE SUBSTR(SRC_CUSTOMER.NET_SALARY,1,30)
END
Move assignment before case keyword and put SRC_CUSTOMER.TARGET as the inner expression:
SRC_CUSTOMER.NET_SALARY =
CASE SRC_CUSTOMER.TARGET
WHEN '700' THEN '0'
ELSE SUBSTR(SRC_CUSTOMER.NET_SALARY,1,30)
END
Can be rewritten with decode function:
SRC_CUSTOMER.NET_SALARY = decode(SRC_CUSTOMER.TARGET,'700','0',SUBSTR(SRC_CUSTOMER.NET_SALARY,1,30))

CASE WHEN SQL Syntax Error

I am attempting to us the CASE statement for the first time and I cannot understand why I am getting a syntax error on the last WHEN and ELSE. I am trying to extract a substring if a value starts with a specific set of characters. My Code is below:
SELECT
CASE
WHEN LEFT ([RCode],2) = 'BB' THEN SUBSTRING([RCode],3,LEN([RCode]))
WHEN LEFT ([RCode],4) = 'APT-' THEN SUBSTRING([RCode],5,LEN([RCode])
WHEN LEFT ([RCode],4) = 'PS-' THEN SUBSTRING([RCode],4,LEN([RCode])
ELSE [RCode]
END
FROM [Xperdyte].[dbo].[tJCLines]
Any guidance would be appreciated.
This won't (necessarily) fix your syntax problem, but I would recommend that you use like for the comparisons:
SELECT (CASE WHEN RCode LIKE 'BB%' THEN SUBSTRING([RCode], 3, LEN([RCode]))
WHEN RCode LIKE 'APT-%' THEN SUBSTRING([RCode], 5, LEN([RCode]))
WHEN RCode LIKE 'PS-%' THEN SUBSTRING([RCode], 4, LEN([RCode]))
ELSE [RCode]
END)
FROM [Xperdyte].[dbo].[tJCLines];
Then you don't have to count characters -- and the third condition will match.
Missed off two right parenthesis.
SELECT CASE WHEN LEFT([RCode],2) = 'BB'
THEN SUBSTRING([RCode],3,LEN([RCode]))
WHEN LEFT([RCode],4) = 'APT-'
THEN SUBSTRING([RCode],5,LEN([RCode]))
WHEN LEFT([RCode],4) = 'PS-'
THEN SUBSTRING([RCode],4,LEN([RCode]))
ELSE [RCode]
END
FROM [Xperdyte].[dbo].[tJCLines]

Error: Error converting data type varchar to numeric, using Hashbytes function in SQL

I have a legacy SSIS package that needs updating. Specifically it used to only add new records and must now update and end date or delete records as appropriate. elsewhere in the package I've been using the Hashbytes function with great success to evaluate which rows need to be updated by taking matching datasets from both databases and then comparing them as part of a conditional split. The problem I'm having revolves around a case statement in the source query:
SELECT DISTINCT
DTBL_STUDENTS.STUDENT_ID,
FTBL_TEST_SCORES.TEST_STUDENT_GRADE,
DTBL_TESTS.TEST_NAME,
DTBL_SCHOOL_DATES.DATE_VALUE AS Assessment_Date,
DTBL_SCHOOL_DATES.SIS_SCHOOL_YEAR AS Assessment_Year,
left( CASE
WHEN FTBL_TEST_SCORES.TEST_SCORE_TEXT = 'NA'
THEN CASE
WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'INTE' THEN 'High'
WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'STRA' THEN 'Some'
WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'BNCH' THEN 'Low'
WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT IN ('High', 'Some', 'Low') THEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT
ELSE FTBL_TEST_SCORES.TEST_SCORE_TEXT
END
ELSE CASE
WHEN FTBL_TEST_SCORES.TEST_SCORE_TEXT LIKE '%.0000'
THEN REPLACE(FTBL_TEST_SCORES.TEST_SCORE_TEXT, '.0000', '')
ELSE FTBL_TEST_SCORES.TEST_SCORE_TEXT
END
END,12) AS TEST_SCORE_TEXT,
CASE
WHEN FTBL_TEST_SCORES.TEST_SCORE_TEXT = 'NA'
THEN CASE
WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'INTE' THEN '1'
WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'STRA' THEN '3'
WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'BNCH' THEN '4'
WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT = 'High' THEN '1'
WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT = 'Some' THEN '3'
WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT = 'Low' THEN '4'
ELSE '0'
END
ELSE FTBL_TEST_SCORES.TEST_SCORE_VALUE
END AS TEST_SCORE_VALUE,
FTBL_TEST_SCORES.TEST_PERCENTILE_SCORE,
DTBL_SCHOOLS.SCHOOL_HR_ID
FROM K12INTEL_DW.DTBL_TESTS
JOIN K12INTEL_DW.FTBL_TEST_SCORES ON FTBL_TEST_SCORES.TESTS_KEY =
DTBL_TESTS.TESTS_KEY
JOIN K12INTEL_DW.DTBL_SCHOOL_DATES ON DTBL_SCHOOL_DATES.SCHOOL_DATES_KEY =
FTBL_TEST_SCORES.SCHOOL_DATES_KEY
JOIN K12INTEL_DW.DTBL_STUDENTS ON DTBL_STUDENTS.STUDENT_KEY =
FTBL_TEST_SCORES.STUDENT_KEY
JOIN K12INTEL_DW.DTBL_SCHOOLS ON DTBL_SCHOOLS.SCHOOL_KEY =
FTBL_TEST_SCORES.SCHOOL_KEY
WHERE DTBL_SCHOOL_DATES.SIS_SCHOOL_YEAR = 2014
AND DTBL_STUDENTS.STUDENT_CURRENT_DISTRICT_CODE = '2180'
AND FTBL_TEST_SCORES.TEST_STUDENT_GRADE IN ('PS', 'PK', 'KG', '01', '02',
'03', '04', '05', '06', '07', '08')
AND DTBL_TESTS.TEST_VENDOR IS NOT NULL
AND FTBL_TEST_SCORES.TEST_HIGHEST_SCORE_INDICATOR IN ('Yes', '--')
The 3 values I need to hash for comparison are:
TEST_SCORE_TEXT
TEST_SCORE_VALUE
Assessment_Date
It looks like it's choking on TEST_SCORE_VALUE in the function:
HASHBYTES('SHA1',ISNULL(#Dware.TEST_SCORE_TEXT,'')+convert(varchar(10),ISNULL(TEST_SCORE_VALUE,''))+convert(varchar(50),(ISNULL(Assessment_Date,'')))) as SourceHash
This is where I get the error "Error converting data type varchar to numeric". I've tried putting my source query into a subquery and doing a select*, (function) from that source query. I've tried putting the case statement into the hashbytes function, and I've tried using a temp table. My assumption is that it's getting the underlying value rather than the value generated by the case statement but I don't know why,or how to fix it so that I get the numeric values I'm expecting/wanting.
Many thanks for any assistance!
Assuming FTBL_TEST_SCORES.TEST_SCORE_VALUE is numeric, then look at your CASE statement that creates TEST_SCORE_VALUE. You create a string by evaluating TEST_PRIMARY_RESULT_CODE and TEST_PRIMARY_RESULT, etc, but your final ELSE statement is probably returning a numeric value (FTBL_TEST_SCORES.TEST_SCORE_VALUE).
I believe Sql Server determines the output type of the CASE statement by the last return value. (In any case, itt has an algorithm for determining the return type when individual THEN statements are mixed.)
So, it sees your CASE statement as typed to whatever FTBL_TEST_SCORES.TEST_SCORE_VALUE is, which is probably inconsistent with the earlier varchar return values of the CASE statement.
Fix that, and the HASHBYTES function should work, as is.
+convert(varchar(10),ISNULL(TEST_SCORE_VALUE,''))
Turns out that should've been:
+convert(varchar(10),ISNULL(TEST_SCORE_VALUE,0))
and then it all worked fine.