Adding a custom logic in SQL select - sql

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.

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

SQL query group by and select the maximum absolute value

"Table1" structure is as shown below:
source table table1
Player_NAME || Player_NUMBER || Client_name || Client_country || Player_country|| Rating
GERALD || A1234 || BENFIELD || IND || IND || 76
GERALD ||A6578 || ROTFIELD || USA || USA || 64
KUMAR || P1234 || LFV || ARG || ARG || -24
KUMAR || P5678 ||JEURASIN || ARG || TUR ||-32
KUMAR || P0101 ||ARGENIA ||ARG ||POL ||-16
ANDREW ||R1234 || GENMAD || GER || GER || 23
I need to select the records from above table “Table1” and copy them to “Table2”.
I need to select the player record from table1 which satisfy the below conditions :
If a player has multiple client_names or multiple client_country, then select the record which has the maximum value of rating . If it is negavie, then take the absolute value of that value. i.e if the rating is -10 and -34, then take the absolute value which is greatest. i. e by taking absolute value it is 10,34 and 34 is greatest one.
For ex: Kumar has 3 diff client names or 3 diff client_country ,so for kumar the record with rating 32 should be selected ,after taking the absolute value of it.
Below is the expected output:
Player_NAME || Player_NUMBER ||Client_name || Client_country ||Player_country|| Rating
GERALD || A1234 || BENFIELD|| IND|| IND|| 76
KUMAR || P5678 || JEURASIN ||ARG ||TUR || -32
ANDREW || R1234 || GENMAD ||GER ||GER || 23
destination table-'table2'
You can try something like this:
INSERT INTO Table2
(
Player_Name,
Player_Number,
Cliet_Name,
Client_country,
Player_country,
Rating
)
SELECT
Player_Name,
Player_Number,
Cliet_Name,
Client_country,
Player_country,
MAX(ABS(Rating)) OVER (PARTITION BY player_Name ORDER BY Cliet_Name,
Client_country) as Rating
FROM
table1
If your DBMS supports Analytical Function you can utilize ROW_NUMBER:
select ... -- all columns but rn
from
(
select ... -- all columns
,row_number()
over (partition by player_name
order by abs(Rating) desc as rn
from table1
) as dt
where rn = 1;
Otherwise use a Correlated Subquery:
select *
from table1 as t1
where abs(rating) =
( select max(abs(rating))
from table1 as t2
where t1.player_name = t2.player_name
)
If you got multiple rows with the same max(abs(rating)) #1. will select one of them randomly, but #2 will select all.
I guess, this query will work:
select
max(abs(Rating))
from Table1
group by Player_NAME
To insert data into Table2, you can do it like so:
INSERT INTO Table2 (
Player_Name,
Player_Number,
Cliet_Name,
Client_country,
Player_country,
Rating
)
SELECT
t1.Player_Name,
t1.Player_Number,
t1.Cliet_Name,
t1.Client_country,
t1.Player_country,
t1.Rating
FROM Table1 t1
INNER JOIN (
SELECT
Player_NAME,
MAX(ABS(Rating)) as Rating
FROM Table1
GROUP BY Player_NAME
) t2 ON t2.Player_NAME = t1.Player_NAME AND ABS(t1.Rating) = t2.Rating

SELECT with lower case + unaccent + multiple columns in PostgreSQL

Table schools
id | address | name
1 | Rybničná 59, Bratislava | Stredná odborná škola elektrotechnická
2 | Ul. Sibírska 1, Trnava | Stredná odborná škola elektrotechnická
What I want
From client If I want to type:
Stredná odborná
stredná odborná
stredna odborna
It must find rows with id 1 and 2
If I want to type Bratislava or bratis It must find row with id 1
What I have
SELECT * FROM schools WHERE unaccent(address) LIKE ('%' || 'bratis' || '%');
I need to select from 2 columns (address and name)
To make the search case insentive, use ILIKE instead of LIKE. Then, you would want to remove the accents from the input string as well. At last, just use AND or OR to combine the two criteria (note that you could use the same search term for both columns - use OR in this case)
SELECT * FROM schools
WHERE unaccent(address) ILIKE ('%' || unaccent('bratis') || '%')
AND unaccent(name) ILIKE ('%' || unaccent('Stredná odborná') || '%')
I hope this works
SELECT * FROM schools
WHERE unaccent(address|| ' ' ||name) ILIKE ('%' || 'bratis' || '%');

SQL Search rows that contain strings from 2nd table list

I have a master table that contains a list of strings to search for. it returns TRUE/FALSE if any string in the cell contains text from the master lookup table. Currently I use excel's
=SUMPRODUCT(--ISNUMBER(SEARCH(masterTable,[#searchString])))>0
is there a way to do something like this in SQL? LEFT JOIN or OUTER APPLY would be simple solutions if the strings were equal; but they need be contains..
SELECT *
FROM t
WHERE col1 contains(lookupString,lookupColumn)
--that 2nd table could be maintained and referenced from multiple queries
hop
bell
PRS
2017
My desired results would be a column that shows TRUE/FALSE if the row contains any string from the lookup table
SEARCH_STRING Contained_in_lookup_column
hopping TRUE
root FALSE
Job2017 TRUE
PRS_tool TRUE
hand FALSE
Sorry i dont have access to the DB now to confirm the syntax, but should be something like this:
SELECT t.name,
case when (select count(1) from data_table where data_col like '%' || t.name || '%' > 0) then 'TRUE' else 'FALSE' end
FROM t;
or
SELECT t.name,
case when exists(select null from data_table where data_col like '%' || t.name || '%') then 'TRUE' else 'FALSE' end
FROM t;
Sérgio
You can use a combination of % wildcards with LIKE and EXISTS.
Example (using Oracle syntax) - we have a v_data table containing the data and a v_queries table containing the query terms:
with v_data (pk, value) as (
select 1, 'The quick brown fox jumps over the lazy dog' from dual union all
select 2, 'Yabba dabba doo' from dual union all
select 3, 'forty-two' from dual
),
v_queries (text) as (
select 'quick' from dual union all
select 'forty' from dual
)
select * from v_data d
where exists (
select null
from v_queries q
where d.value like '%' || q.text || '%');

Oracle - Concatenate Field on Where

I'm using a Concatenate Field and I'd like to use it on the WHERE of it
TABLE T_EXAMPLE
RED - FERRARI - F50
BLUE - PORSHE - S20
GREEN - CAMARO - T40
I have to show all this fields on a Grid, 'cause of this that I need to put all of them in one field, but I have to filter the Grid with One information that can be any one of the three, example:
SELECT
T.COLOR || T.CAR,T || T.Model AS FIELD1
FROM T_EXAMPLE T
WHERE FIELD1 LIKE '%FER%'
Here I want to filter the Ferrari, but I've tried to do like this but I got an error (Invalid Identifier).
Can anyone help me??
The alias FIELD1 can't be used in the WHERE clause, so just repeat the column concatenation in the WHERE clause. Like this:
SELECT
T.COLOR || T.CAR || T.Model AS FIELD1
FROM T_EXAMPLE T
WHERE T.COLOR || T.CAR || T.Model LIKE '%FER%'
Or, if you don't like the repetition, another option would be this:
SELECT FIELD1
FROM (
SELECT
T.COLOR || T.CAR || T.Model AS FIELD1
FROM T_EXAMPLE T
)
WHERE FIELD1 LIKE '%FER%'