Eliminating multiple delimiters in single column in oracle - sql

My table has single column info
Info
+aname + + + + + + +ano+ + + + + + + + + +agender+ + + + + + + + + + + + +arace
I should get output like
aname+ano+agender+arace
I have to eliminate multiple delimiters and replace with single +
I tried with regexp_replace and trim and working as below
select trim(REGEXP_REPLACE('+aname + + + + + + +
+ano + + + + + + + +
+agender+ + + + + + + + + + +
+arace', '\ + + ', '+'),'+') from dual;
i get output as
aname+++++++ano+++++++agender++++++++++arace

This regexp does the trick: '\++'
select REGEXP_REPLACE('+aname++++++ano+++++++++agender++++++++++++arace', '\++', '+') from dual;
To get rid of the leading + (like in your example), use ltrim (or trim to remove trailing + too).
select ltrim(REGEXP_REPLACE('+aname++++++ano+++++++++agender++++++++++++arace', '\++', '+'),'+') from dual;

Related

LEFT JOIN question - Pervasive SQL - combining multiple records from one table into a single column

I am having some trouble with getting data into a column from a combination of two tables.
I'm using pervasive SQL and don't have access to pivot tables. I did a left join and tried union but am not getting the results I want.
I have a primary table - table A - That for a given contract has 10 summary 'colors'.
I am using a select statement and a case clause to string the 10 unique colors together with commas to properly determine the number of commas I am checking for values in those color fields.
This works well - I get a single row with all of the colors listed (10 fields into 1)
Table B contains records for the same contract and can have almost up to 2000 colors (detail colors).
If table B has colors then Table A doesn't.
Is there a way to select all of the colors in Table B into a single row and column and show all of the other column data in Table A?
What I want :
Contract +---------+ PHONENO +----------+ Color +------+------+
TEST 555-555-5555 BLUE,RED,GREEN,YELLOW
Instead of what I'm currently getting:
Contract+---------+ PHONENO +----------+ Color +------+------+
TEST 555-555-5555 BLUE
TEST 555-555-5555 RED
TEST 555-555-5555 GREEN
TEST 555-555-5555 YELLOW
SELECT TableA.ContractNo AS Contract,
TableA.PhoneNo,
CASE
WHEN TableA.Color10 <> '' then (TableA.Color1 + ',' + TableA.Color2 + ',' + TableA.Color3 + ',' + TableA.Color4 + ',' + TableA.Color5 + ',' + TableA.Color6 + ',' + TableA.Color7 + ',' + TableA.Color8 + ',' + TableA.Color9 + ',' + TableA.Color10)
WHEN TableA.Color9 <> '' then (TableA.Color1 + ',' + TableA.Color2 + ',' + TableA.Color3 + ',' + TableA.Color4 + ',' + TableA.Color5 + ',' + TableA.Color6 + ',' + TableA.Color7 + ',' + TableA.Color8 + ',' + TableA.Color9)
WHEN TableA.Color8 <> '' then (TableA.Color1 + ',' + TableA.Color2 + ',' + TableA.Color3 + ',' + TableA.Color4 + ',' + TableA.Color5 + ',' + TableA.Color6 + ',' + TableA.Color7 + ',' + TableA.Color8)
WHEN TableA.Color7 <> '' then (TableA.Color1 + ',' + TableA.Color2 + ',' + TableA.Color3 + ',' + TableA.Color4 + ',' + TableA.Color5 + ',' + TableA.Color6 + ',' + TableA.Color7)
WHEN TableA.Color6 <> '' then (TableA.Color1 + ',' + TableA.Color2 + ',' + TableA.Color3 + ',' + TableA.Color4 + ',' + TableA.Color5 + ',' + TableA.Color6)
WHEN TableA.Color5 <> '' then (TableA.Color1 + ',' + TableA.Color2 + ',' + TableA.Color3 + ',' + TableA.Color4 + ',' + TableA.Color5)
WHEN TableA.Color4 <> '' then (TableA.Color1 + ',' + TableA.Color2 + ',' + TableA.Color3 + ',' + TableA.Color4)
WHEN TableA.Color3 <> '' then (TableA.Color1 + ',' + TableA.Color2 + ',' + TableA.Color3)
WHEN TableA.Color2 <> '' then (TableA.Color1 + ',' + TableA.Color2)
WHEN TableA.Color1 <> '' then (TableA.Color1)
WHEN TableB.Color <> '' then TableB.Color
ELSE 'n/a'
end as Color
FROM TableA
LEFT JOIN TableB ON (TableA.ContractNo = TableB.ContractNo)
ORDER BY TableA.ContractNo
Can anyone help out with this?

when using "SELECT varname = something + something etc. I cannot then do "WHERE varname = ..."

I have:
SELECT KEYWORDS = CAST(USRN AS VARCHAR(15)) + ' ' +
RTRIM(SD) + ' ' + RTRIM(NL.LOCALITY_NAME) + ' ' +
RTRIM(NT.TOWN_NAME) + ' ' + RTRIM(NA.AUTHORITY_NAME)
That gives me what looks like a column, but is not:
I want to have it so my code only selects the rows from KEYWORDS that match whatever the user is typing. Normally, if KEYWORDS was a column, I would write:
SELECT .... WHERE KEYWORDS = '%whateverTheUserIsTyping%'
but I cannot because keywords is not a real column and it is telling me that it does not exist.
How do I get around this? thanks
The column alias KEYWORDS isn't visible to the SQL Engine at the time that the WHERE clause is evaluated. You can just repeat your CAST statment, though.
SELECT
KEYWORDS = CAST(USRN AS VARCHAR(15)) + ' ' +
RTRIM(STREET_DESCRIPTOR) + ' ' + RTRIM(NSG_LOCALITY.LOCALITY_NAME) + ' ' +
RTRIM(NSG_TOWN.TOWN_NAME) + ' ' + RTRIM(NSG_AUTHORITY.AUTHORITY_NAME)
FROM yourTable
WHERE
CAST(USRN AS VARCHAR(15)) + ' ' +
RTRIM(STREET_DESCRIPTOR) + ' ' + RTRIM(NSG_LOCALITY.LOCALITY_NAME) + ' ' +
RTRIM(NSG_TOWN.TOWN_NAME) + ' ' + RTRIM(NSG_AUTHORITY.AUTHORITY_NAME)
LIKE '%whateverTheUserIsTyping%'
You can use derived table with an alias (here Q) and get the result from that by filtering in WHERE clause:
SELECT Q.KEYWORDS FROM (
SELECT KEYWORDS = CAST(USRN AS VARCHAR(15)) + ' ' +
RTRIM(STREET_DESCRIPTOR) + ' ' + RTRIM(NSG_LOCALITY.LOCALITY_NAME) + ' ' +
RTRIM(NSG_TOWN.TOWN_NAME) + ' ' + RTRIM(NSG_AUTHORITY.AUTHORITY_NAME)
) AS Q
WHERE Q.KEYWORDS LIKE '%whateverTheUserIsTyping%'
Because you can't use the column alias in the WHERE clause as you mentioned. Also instead of the KEYWORDS = '%whateverTheUserIsTyping%', you can use LIKE operator.

SQL select, sum and group

I'm struggling with an Access database:
I have a large database with the headers TAG, ZST, KL and R1H00 to R1H23 (24 of them, each one stands for one hour of a day) and I need to get a specific dataset out of it:
SELECT TAG, ZST, (R1H00 + R1H01 + R1H02 + R1H03 + R1H04 + R1H05 + R1H06 + R1H07 + R1H08 + R1H09 + R1H10 + R1H11 + R1H12 + R1H13 + R1H14 + R1H15 + R1H16 + R1H17 + R1H18 + R1H19 + R1H20 + R1H21 + R1H22 + R1H23) AS TOTAL
FROM Klassendaten
WHERE KL = "SWISS7_PW"
So far so good, but the result contains many items with the same ID (ZST). I need to sum all entries with the same ZST, but I couldn't manage to do it so far. (I tried to use the GROUP BY statement, but that only results in errors)
Any experienced SQL people here that could help me with this?
use group by
SELECT TAG, ZST, sum(R1H00 + R1H01 + R1H02 + R1H03 + R1H04 + R1H05 + R1H06 + R1H07 + R1H08 + R1H09 + R1H10 + R1H11 + R1H12 + R1H13 + R1H14 + R1H15 + R1H16 + R1H17 + R1H18 + R1H19 + R1H20 + R1H21 + R1H22 + R1H23) AS TOTAL
FROM Klassendaten
WHERE KL = "SWISS7_PW"
GROUP BY TAG, ZST;
Use the Sum() function
SELECT TAG, ZST, Sum(R1H00 + R1H01 + R1H02 + R1H03 + R1H04 + R1H05 + R1H06 + R1H07 + R1H08 + R1H09 + R1H10 + R1H11 + R1H12 + R1H13 + R1H14 + R1H15 + R1H16 + R1H17 + R1H18 + R1H19 + R1H20 + R1H21 + R1H22 + R1H23) AS TOTAL
FROM Klassendaten
where ZST = '(Whatever it is)'
group by tag, zst

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <,

When I run the following query I get the above error. I realize this is because the subquery is returning more than 1 result but am not sure how to fix it.
update a
set a.covtypeplus = (SELECT distinct
REPLACE(REPLACE(ISNULL([BI],'x') + '+' + ISNULL([PD],'x') + '+' +
ISNULL([COM],'x') + '+' + ISNULL([COMGL],'x') + '+' + ISNULL([COL],'x') + '+' + ISNULL([COLDW],'x') + '+' +
ISNULL([MED],'x') + '+' + ISNULL([PIP],'x') + '+' + ISNULL([PIPNI],'x') + '+' + ISNULL([PIPNR],'x') + '+' +
ISNULL([UM],'x') + '+' + ISNULL([UMBI],'x') + '+' + ISNULL([UMBA],'x') + '+' + ISNULL([UMS],'x') + '+' +
ISNULL([UMPD],'x') + '+' + ISNULL([UMPA],'x') + '+' +
ISNULL([UIM],'x') + '+'+ ISNULL([UIMBI],'x') + '+' + ISNULL([UIMC],'x') + '+' + ISNULL([UIS],'x') + '+' +
ISNULL([UIMPD],'x') + '+' + ISNULL([MEX],'x') + '+' +
ISNULL([ACC],'x') + '+' + ISNULL([CPI],'x') + '+' + ISNULL([INC],'x') + '+' + ISNULL([FUN],'x') + '+' + ISNULL([XMD],'x')
, 'x+', ''), '+x', '') AS CovTypePlus
FROM (SELECT distinct POLICYID, VERSION, COVCODE FROM Staging.Coverage) p LEFT JOIN (
SELECT *
FROM (
SELECT POLICYID, VERSION, COVCODE
FROM Staging.Coverage
WHERE SUBSTRING(COVCODE, 1, 2) IN ('BI','PD','CO','ME','PI','UM','UI','AC','CP','IN','FU','XM','LD','RA','RE','RO','SP','TO','SG','WM')) p
PIVOT (MAX(COVCODE) FOR COVCODE IN (
[BI], [PD], [COM], [COMGL], [COL], [COLDW],
[MED], [PIP], [PIPNI], [PIPNR],
[UM], [UMBI], [UMBA], [UMS], [UMPD], [UMPA],
[UIM], [UIMBI], [UIMC], [UIS], [UIMPD],
[ACC], [CPI], [INC], [FUN], [XMD], [LD], [MEX], [RA], [REN], [ROADS], [SPE], [TOW], [SGC], [WMAR]
)) AS pvt) vc ON p.POLICYID = vc.POLICYID AND p.VERSION = vc.VERSION)
from results_vehicle a
left join staging.coverage c on a.polnum =c.policyid and a.polver = c.version and a.covcode = c.COVCODE
When I run the following original query I created (not an update) it works fine so it must be something I am doing wrong in my update syntax:
SELECT DISTINCT p.POLICYID AS PolNum, p.VERSION As PolVer,
REPLACE(REPLACE(ISNULL([BI],'x') + '+' + ISNULL([PD],'x') + '+' +
ISNULL([COM],'x') + '+' + ISNULL([COMGL],'x') + '+' + ISNULL([COL],'x') + '+' + ISNULL([COLDW],'x') + '+' +
ISNULL([MED],'x') + '+' + ISNULL([PIP],'x') + '+' + ISNULL([PIPNI],'x') + '+' + ISNULL([PIPNR],'x') + '+' +
ISNULL([UM],'x') + '+' + ISNULL([UMBI],'x') + '+' + ISNULL([UMBA],'x') + '+' + ISNULL([UMS],'x') + '+' +
ISNULL([UMPD],'x') + '+' + ISNULL([UMPA],'x') + '+' +
ISNULL([UIM],'x') + '+'+ ISNULL([UIMBI],'x') + '+' + ISNULL([UIMC],'x') + '+' + ISNULL([UIS],'x') + '+' +
ISNULL([UIMPD],'x') + '+' + ISNULL([MEX],'x') + '+' +
ISNULL([ACC],'x') + '+' + ISNULL([CPI],'x') + '+' + ISNULL([INC],'x') + '+' + ISNULL([FUN],'x') + '+' + ISNULL([XMD],'x')
, 'x+', ''), '+x', '') AS CovTypePlus
FROM (SELECT DISTINCT POLICYID, VERSION, COVCODE FROM Staging.Coverage) p LEFT JOIN (
SELECT *
FROM (
SELECT POLICYID, VERSION, COVCODE
FROM Staging.Coverage
WHERE SUBSTRING(COVCODE, 1, 2) IN
('BI','PD','CO','ME','PI','UM','UI','AC','CP','IN','FU','XM','LD','RA','RE','RO','SP','TO','SG','WM')) p
PIVOT (MAX(COVCODE) FOR COVCODE IN (
[BI], [PD], [COM], [COMGL], [COL], [COLDW],
[MED], [PIP], [PIPNI], [PIPNR],
[UM], [UMBI], [UMBA], [UMS], [UMPD], [UMPA],
[UIM], [UIMBI], [UIMC], [UIS], [UIMPD],
[ACC], [CPI], [INC], [FUN], [XMD], [LD], [MEX], [RA], [REN], [ROADS], [SPE], [TOW], [SGC], [WMAR]
)) AS pvt) vc ON p.POLICYID = vc.POLICYID AND p.VERSION = vc.VERSION
Any help is greatly appreciated, I've tried playing around with the query and yield the same results. I also tried adding a SELECT TOP 1 and got the same results for all policies.
You are doing:
update a
set a.covtypeplus = (SELECT distinct . . .
This suggests that you are expecting more than one result from that subquery. Not allowed.
Perhaps this will fix it, but it may not be what you want:
update a
set a.covtypeplus = (SELECT top 1 . . .
It appears to be this part that is messing you up:
from results_vehicle a
left join staging.coverage c on a.polnum =c.policyid
and a.polver = c.version and a.covcode = c.COVCODE
This must be generating more than one result for some values of a.covcode.

How can I use SUM() to sum my result array?

My current method to add the rows together is like so:
$totalxp = $row['Attackxp'] + $row['Defencexp'] + $row['Strengthxp'] + $row['Hitpointsxp'] + $row['Rangedxp'] + $row['Prayerxp'] + $row['Magicxp'] + $row['Cookingxp'] + $row['Woodcuttingxp'] + $row['Fletchingxp'] + $row['Fishingxp'] + $row['Firemakingxp'] + $row['Craftingxp'] + $row['Smithingxp'] + $row['Miningxp'] + $row['Herblorexp'] + $row['Agilityxp'] + $row['Thievingxp'] + $row['Slayerxp'] + $row['Farmingxp'] + $row['Runecraftxp'] + $row['Constructionxp'];
But then I saw SUM() and I tried this:
SELECT SUM(xp) FROM skills WHERE playerName='Undercover'
It works but I needed all the values of xp, so I tried adding %xp but it wont work.
How could I use the Sum() function to add all the rows up instead of straining PHP?
Aggregate functions (IE: SUM, MIN, MAX, COUNT, etc) don't work across columns--they work on the values for the specific column, based on the grouping (GROUP BY) and filteration (JOIN and/or WHERE clause).
To add up values across columns, you need to add them like you would for normal mathematical equations:
SELECT Attackxp + Defencexp + Strengthxp + Hitpointsxp + Rangedxp + Prayerxp + Magicxp + Cookingxp+ Woodcuttingxp + Fletchingxp + Fishingxp + Firemakingxp + Craftingxp + Smithingxp + Miningxp + Herblorexp + Agilityxp + Thievingxp + Slayerxp + Farmingxp + Runecraftxp + Constructionxp AS total_xp
FROM skills
WHERE playerName = 'Undercover'
If you have more than one record associated to a playername, then you can use an aggregate function:
SELECT SUM(Attackxp + Defencexp + Strengthxp + Hitpointsxp + Rangedxp + Prayerxp + Magicxp + Cookingxp+ Woodcuttingxp + Fletchingxp + Fishingxp + Firemakingxp + Craftingxp + Smithingxp + Miningxp + Herblorexp + Agilityxp + Thievingxp + Slayerxp + Farmingxp + Runecraftxp + Constructionxp) AS total_xp
FROM skills
WHERE playerName = 'Undercover'
That depend of the table data if each player is one entity (row) then is enaught to add columns:
SELECT Attackxp + Defencexp + Strengthxp + Hitpointsxp +Rangedxp + Prayerxp + Magicxp + Cookingxp + Woodcuttingxp + Fletchingxp + Fishingxp + Firemakingxp + Craftingxp + Smithingxp + Miningxp + Herblorexp + Agilityxp + Thievingxp + Slayerxp + Farmingxp + Runecraftxp + Constructionxp
As totalSkills FROM skills WHERE playerName = 'Undercover'
But is there more rows per player then You will need to sum also the rows
SELECT SUM(Attackxp + Defencexp + Strengthxp + Hitpointsxp +Rangedxp + Prayerxp + Magicxp + Cookingxp + Woodcuttingxp + Fletchingxp + Fishingxp + Firemakingxp + Craftingxp + Smithingxp + Miningxp + Herblorexp + Agilityxp + Thievingxp + Slayerxp + Farmingxp + Runecraftxp + Constructionxp)
As totalSkills FROM skills WHERE playerName = 'Undercover'
SELECT SUM(`Attackxp`) + SUM(`Defencexp`) + ... AS `total_sum`
FROM skills
WHERE playerName='Undercover'