LPAD and RPAD on a CASE statement - sql

I'm trying to pad to the left and right of a case statement with 3 asterisks. It runs but the values don't show up for the Null values. Any ideas?
SELECT p.patientfirstname || ' ' || p.patientlastname AS "Patient"
,CASE WHEN i.insuranceid IS NULL THEN RPAD(LPAD('No insurance', 3, '*'), 3, '*')
ELSE i.insurancename
END "Insurance Name"
FROM patient p
FULL OUTER JOIN insurance i ON (p.insuranceid = i.insuranceid);

As I wrote in my comment, if you want a constant string, just use one and do away with the padding:
SELECT p.patientfirstname || ' ' || p.patientlastname AS "Patient"
,CASE WHEN i.insuranceid IS NULL THEN '***No insurance***'
ELSE i.insurancename
END "Insurance Name"
FROM patient p
FULL OUTER JOIN insurance i ON (p.insuranceid = i.insuranceid);
Padding is used to ensure a fixed-size string when working with transforming strings that are of variable shorter sizes. See example:
select lpad('Hola',7, '*'), lpad('Namaste',7, '*'), lpad('Hello',7, '*') from dual;
***Hola |Namaste |**Hello
select length(lpad('Hola',7, '*')), length(lpad('Namaste',7, '*')), length(lpad('Hello',7, '*')) from dual;
7 |7 |7

Related

How to append data to a concatenation, from another table, only if that data is available

I have 2 tables:
L0INS (ID_INS, Nume_INS)
1 ANB
2 ENEL
3 DIGI
L1AVZ (ID_AVZ, FK_INS, Nume_AVZ)
1 1 APA
2 1 CAN
3 1 HID
4 2 ELE
I want to make a query that displays the following:
Query1 (ID_INS, CONCAT(Nume_INS, Nume_AVZ) )
1 ANB, APA
1 ANB, CAN
1 ANB, HID
2 ENEL, ELE
3 DIGI, n/a
SO it only adds Name_T2 to the concatenation, if an entry in Table2 exists that has L0INS.ID_INS = L1AVZ.FK_INS
I made this version that does display a L0INS entry for each Nume_AVZ append but also one that includes 'n/a'. I'd Like to remove the 'n/a' entry, if there is another one.
SELECT DISTINCT "L0INS"."ID_INS",
COALESCE ( "NUME_INS", 'n/a' ) || ', ' || CASE WHEN "L1AVZ"."FK_INS" = "L0INS"."ID_INS" THEN "L1AVZ"."NUME_AVZ" ELSE 'n/a' END "INS_SELECT",
LOWER ( COALESCE ( "NUME_INS", 'n/a' ) || ', ' || CASE WHEN "L1AVZ"."FK_INS" = "L0INS"."ID_INS" THEN "L1AVZ"."NUME_AVZ" ELSE 'n/a' END ) "INS_SEARCH"
FROM "L1AVZ", "L0INS"
WHERE "L0INS"."ID_INS" IS NOT NULL
I sense there's something in the WHERE part missing, that I can't wrap my head around.
Isn't a LEFT JOIN simpler?
SELECT l1."ID_INS",
("NUME_INS" || ', ' || OALESCE(l0."NUME_AVZ", 'n/a') AS INS_SEARCH"
FROM "L1AVZ" l1 LEFT JOIN
"L0INS" lO
ON l1.id_ins = l0.fk_ins;
SELECT L.ID_INS,L.Nume_INS +','+COALESCE(AVZ.Nume_AVZ,'N/A')AS X
FROM L0INS AS L
LEFT JOIN L1AVZ AS AVZ ON L.ID_INS=AVZ.FK_INS

Adding a custom logic in SQL select

I have requirement where I want show a column as Carryover/new.
The logic is as below.
if color exists in palette then mark the column 'Dev type' as new else carryover.
I have tried to put the business scenario using a hypothetical table structure and simillar query.
Pal table
ID PalName year
1 Pal 1 2017
2 Pal 2 2016
3 pal 3 2017
4 pal 4 2016
5 pal 5 2017
Color table
ID Color name requestedpalette
1 Red pal 1, pal 5,
2 Green na,
3 Black na,pal 1,pal 3
Season Table
ID Color ID Palette ID Season name
1 1 3 Summer
2 2 4 Winter
Query
WITH masterdata AS
(SELECT season name,
color name,
season.is AS SeasonID,
color.id AS ColorID
FROM season
INNER JOIN color ON color.id=season.colorid
INNER JOIN palette ON palette.id=season.paletteid
WHERE palette.year=2017 )
SELECT colorname,
CASE
WHEN EXISTS
( SELECT 1
FROM masterdata
WHERE ',' || color.requestedpalette LIKE '%,' || masterdata.PalName || ',%' ) THEN 'New'
ELSE 'Carryover'
END DevelopmentType
FROM color
Is there a better way to fetch the above without using WITH?
How to set a value of a column based on the entire result set in a SQL Query
Try:
SELECT color,
nvl((SELECT distinct 'New'
FROM pal
WHERE regexp_like(color.requestedpalette,
'^([^,]*, *)*' || PalName || '(,.*)*$')
AND year = 2017
), 'Carryover') DevelopmentType
FROM color
You don't have PalName in your with clause, so I don't think what you have would work as is. Since you are only comparing the requestedpalette to the PalName I didn't join all 3 tables by ids. If you need just palettes that have a season, then bring that table in to the subquery column.
Really, after cleaning up dataentry errors, you could just move the masterdata query into your main query as a subquery and left join it on
color.requestedpalette LIKE masterdata.PalName || ',%'
or color.requestedpalette LIKE '%, ' || masterdata.PalName || ',%'
or color.requestedpalette LIKE '%, ' || masterdata.PalName
or color.requestedpalette = masterdata.PalName
and it will work per your original design.
SELECT distinct colorname,
(case when PalName is not null
then 'New' else 'Carryover' end) DevelopmentType
FROM color
LEFT JOIN (
SELECT PalName
FROM season
INNER JOIN color ON color.id=season.colorid
INNER JOIN palette ON palette.id=season.paletteid
WHERE palette.year=2017
) masterdata
ON color.requestedpalette LIKE masterdata.PalName || ',%'
OR color.requestedpalette LIKE '%, ' || masterdata.PalName || ',%'
OR color.requestedpalette LIKE '%, ' || masterdata.PalName
OR color.requestedpalette = masterdata.PalName
Edited 16-Mar-2017 to account for PalName possibly being a substring of the PalName enclosed or not enclosed in commas in color.requestedpalette.

SQL return email, if no email return phone number, if no phone number return cell (all one column)

This an example I received but after research I still am stuck. He wants me to return the email address, if no email return telephone phone number, if no telephone number return cell (all one column). I have joined my tables but not sure if I should use a WHERE NOT EXISTS or an IF/ELSE.
SELECT *
FROM entity e
LEFT OUTER JOIN telephone t ON t.id_number = e.id_number
LEFT OUTER JOIN email eml ON eml.id_number = e.id_number
you can use coalesce function which returns first not null result, not sure what do you mean by returning the cell, but i think you got the idea
with xx as
(select 'email#mail.com' email, null telephone, null cell
from dual
union all
select null email, '123456' telephone, null cell
from dual
union all
select null email, null telephone, '5' cell
from dual)
select coalesce(email, telephone, cell) first_not_null from xx
You can use the COALESCE function that will return the first non-null value.
I ended up getting it to work like this:
CASE WHEN TRIM(eml.email_address) IS NOT NULL THEN eml.email_address
WHEN TRIM(t.telephone_number) IS NOT NULL THEN 'H: (' || t.area_code || ')' || SUBSTR(t.telephone_number, 1, 3) || '-' || SUBSTR(t.telephone_number, 4, 4)
WHEN TRIM(t2.telephone_number) IS NOT NULL THEN 'C: (' || t2.area_code || ')' || SUBSTR(t2.telephone_number, 1, 3) || '-' || SUBSTR(t2.telephone_number, 4, 4)
ELSE 'No Email/Phone Found'
END AS "EMAIL/PHONE"
This would be the answer :
SELECT Case When eml.emailaddress is not null then eml.emailaddress
When eml.emailaddress IS NULL
AND t.Phonenumber is NOT NULL THEN t.Phonenumber
Else t.cellNumber
End as ContactInfo
FROM entity e
LEFT OUTER JOIN telephone t ON t.id_number = e.id_number
LEFT OUTER JOIN email eml ON eml.id_number = e.id_number

Select Value Match - SQL

Can you advise if it is possible, to select a count for numerous substrings in a query
so if I have a message field which contains for example, text messages and I could do
SELECT COUNT(1)
FROM MESSAGES
WHERE MESSAGE_BODY LIKE '%hello%'
but what I want to do is more:
SELECT STRING, COUNT(1)
FROM MESSAGES
WHERE MESSAGE_BODY IN (list of strings with wild card)
is this possible?
to break down example:
ID | Message_Body
1 | Hello, How Are You?
2 | Hi, Great Thanks
3 | Hello, How is things?
4 | Ciao
Output wanted:
hello , 2
ciao, 1
SELECT (input strings), COUNT(1)
FROM TABLE
WHERE (input strings) IN ('%hello%','%ciao%')
If I understood you correctly, you can try something like this:
SELECT t.string,
CASE WHEN t.MESSAGE_BODY LIKE '%laptop%' then 1 else 0 END +
CASE WHEN t.MESSAGE_BODY LIKE '%one%' then 1 else 0 END +
CASE WHEN t.MESSAGE_BODY LIKE '%two%' then 1 else 0 END as count_col
FROM YourTable t
If you just want multiple LIKE comaparison, use REGEXP_LIKE() :
SELECT STRING, COUNT(1)
FROM MESSAGES
where regexp_like(MESSAGE_BODY, 'one|two|laptop')
EDIT: You can use a derived table containing all strings you are intrested on and left join to the original table for count:
SELECT t.wrd,COUNT(s.id) as cnt
FROM (
SELECT 'hello' as wrd FROM DUAL
UNION ALL
SELECT 'ciao' as wrd FROM DUAL) t
LEFT OUTER JOIN messages s
ON(s.message_body LIKE '%' || t.wrd || '%')
GROUP BY t.wrd
Here is with looking for whole words:
SELECT a.word, COUNT (message.message_body)
FROM ( SELECT REGEXP_SUBSTR ('hello,ciao', '[^,]+', 1, LEVEL) word
FROM DUAL
CONNECT BY REGEXP_SUBSTR ('hello,ciao', '[^,]+', 1, LEVEL) IS NOT NULL) a
LEFT OUTER JOIN MESSAGES ON REGEXP_INSTR (MESSAGE_BODY, '(^|\s)' || a.word || '(\s|$)', 1, 1, 0, 'i') > 0
GROUP BY a.word

Re-qwrite Oracle SQL using ANSI Oracle

I am new to oracle and sql, I would like to know how can I re-write the following sql query using Oracle ANSI join conditions.
SELECT emp_no,
(SELECT emp_title
FROM hr_v_employee
WHERE organization_code LIKE
SUBSTR (emp.depart_code, 0, 4) || '00'
AND emp_position_code =
(SELECT MIN (emp_position_code)
FROM hr_v_employee
WHERE organization_code LIKE
SUBSTR (emp.depart_code,
0,
4
)
|| '00'))
|| ' '
|| NVL (employee_deptartment, '-')
employee_deptartment
FROM employees e, employee_details o
WHERE emp.emp_no = o.emp_no(+)
Edit 1
This what I have tried, my question is it possible to use join or ANSI standard for sub-query as well?
SELECT emp_no,
(SELECT emp_title
FROM hr_v_employee
WHERE organization_code LIKE
SUBSTR (emp.depart_code, 0, 4) || '00'
AND emp_position_code =
(SELECT MIN (emp_position_code)
FROM hr_v_employee
WHERE organization_code LIKE
SUBSTR (emp.depart_code,
0,
4
)
|| '00'))
|| ' '
|| NVL (employee_deptartment, '-')
employee_deptartment
FROM employees e left outer join employee_details o (emp.emp_no = o.emp_no)
Apart from the missing ON keyword for the LEFT OUTER JOIN, your query should be fine:
SELECT emp_no,
(SELECT emp_title
FROM hr_v_employee
WHERE organization_code LIKE SUBSTR(emp.depart_code,
0,
4) || '00'
AND emp_position_code =
(SELECT MIN(emp_position_code)
FROM hr_v_employee
WHERE organization_code LIKE SUBSTR(emp.depart_code,
0,
4) || '00')) || ' ' ||
NVL(employee_deptartment,
'-') employee_deptartment
FROM employees e
LEFT OUTER JOIN employee_details o
ON emp.emp_no = o.emp_no
Please note that you have a typo in your column names - it should be called employee_department instead of employee_deptartment.