In the following I am looking up a value in a legacy database my company has.
SELECT DISTINCT DLR.CIRCUIT_DESIGN_ID AS "CID",
DLR.ECCKT AS "CIRCUIT",
CI.LOCATION_ID_2 AS "SITE ID",
CI.EXCHANGE_CARRIER_CIRCUIT_ID AS "ID",
CI.RATE_CODE as "Rate",
DLR.ACCESS_CUSTOMER_NAME AS "CUSTOMER SITE NAME",
ADR.HOUSE_NBR || ' ' || ADR.STREET_NM || ' ' || ADR.STREET_SUF || ' ' || ADR.CITY_NAME || ' ' || ADR.STATE_CODE || ' ' || ADR.ZIP_CODE AS "CUSTOMER ADDRESS"
FROM DESIGN_LAYOUT_REPORT DLR, CIRCUIT CI, MSAG_ADDR_LOC ADR
WHERE CI.CIRCUIT_DESIGN_ID = DLR.CIRCUIT_DESIGN_ID
AND CI.LOCATION_ID_2 = ADR.LOCATION_ID
AND CI.CIRCUIT_DESIGN_ID IN (
SELECT DISTINCT CIRCUIT_DESIGN_ID
FROM DLR_CIRCUIT_DESIGN_LINE
WHERE LOCATION LIKE '% <some value from other code> %'
)
My problem comes from the fact that ADR only has info for some of the values I search which is causing this query to not include all the values I need. DLR and CI always have values. How would I make this query return everything and just give me blank returns for the values that do not match an ADR entry?
You would just need an outer join:
SELECT DISTINCT DLR.CIRCUIT_DESIGN_ID AS "CID",
DLR.ECCKT AS "CIRCUIT",
CI.LOCATION_ID_2 AS "SITE ID",
CI.EXCHANGE_CARRIER_CIRCUIT_ID AS "ID",
CI.RATE_CODE as "Rate",
DLR.ACCESS_CUSTOMER_NAME AS "CUSTOMER SITE NAME",
ADR.HOUSE_NBR || ' ' || ADR.STREET_NM || ' ' || ADR.STREET_SUF || ' ' || ADR.CITY_NAME || ' ' || ADR.STATE_CODE || ' ' || ADR.ZIP_CODE AS "CUSTOMER ADDRESS"
FROM DESIGN_LAYOUT_REPORT DLR, CIRCUIT CI, MSAG_ADDR_LOC ADR
WHERE CI.CIRCUIT_DESIGN_ID = DLR.CIRCUIT_DESIGN_ID
AND CI.LOCATION_ID_2 = ADR.LOCATION_ID (+)
AND CI.CIRCUIT_DESIGN_ID IN (
SELECT DISTINCT CIRCUIT_DESIGN_ID
FROM DLR_CIRCUIT_DESIGN_LINE
WHERE LOCATION LIKE '% <some value from other code> %')
Note the extra (+). This is old-style join, you should now use ANSI joins instead.
Related
I'm wondering if it is possibly to complete a string replace on a joined SQL statement. For example, my query is:
SELECT (SITE_NAME || ', ' || LOT_NUMBER || ' ' || UNIT_TYPE || ' ' || LEVEL_NUMBER
|| ' ' || UNIT_NUMBER || ' ' || ROAD_NUMBER_1 || ' ' || ROAD_NUMBER_2 || ' ' || ROAD_NAME
|| ' ' || ROAD_TYPE || ' ' || ROAD_SUFFIX || ', ' || SUBURB || ', ' || STATE) AS address
FROM ADDRESS_LOOKUP_TOOL
WHERE ADD_ID = :P1_ADD_ID;
This statement works perfectly.... providing every single address field is populated. If only some sections are populated (i.e. there is no site name, or road suffix), there are additional commas or spaces.
Here is an example of a good select:
House of Dom, Lot 1 Suite 4 4D 119 Fake St South, Domtopia, QLD
Here is an example of a flawed select:
, Lot 1 Suite 4 4D 119 Fake St , Domtopia, QLD
Is it possibly to do a string replace on the alias where I could say, for example replace(address, ' ,', ',') (Where "space comma" just becomes "comma"), or is there a better way I should be structuring my select to pick this up in one go?
An additional note: This is all being completed with in Oracle's Application Express (ApEx) if this makes a difference.
I am very new to SQL, so I apologise in advance if I ask any basic follow up questions!
Thank you!
Dominic
You don't need to do it on the alias. Just do it on the expression itself.
SELECT REPLACE(
(SITE_NAME || ', ' || LOT_NUMBER || ' ' || UNIT_TYPE || ' ' || LEVEL_NUMBER
|| ' ' || UNIT_NUMBER || ' ' || ROAD_NUMBER_1 || ' ' || ROAD_NUMBER_2 || ' ' || ROAD_NAME
|| ' ' || ROAD_TYPE || ' ' || ROAD_SUFFIX || ', ' || SUBURB || ', ' || STATE),
' ,', ',') AS address
FROM ADDRESS_LOOKUP_TOOL
WHERE ADD_ID = :P1_ADD_ID;
CREATE OR REPLACE FORCE EDITIONABLE VIEW "VU_REPORT5" ("Selling Report") AS
SELECT a2.FIRST_NAME || a2.SUR_NAME ||', living in ' || a4.COUNTRY ||
', ' || a4.CITY || ' ' || a4.LINE_1 || a4.LINE_2 ||
a4.LINE_3 || a4.LINE_4 || ', bought an ' || a1.MAKE || ' ' ||
a1.MODEL || ' from employee ' || a3.FIRST_NAME || ' ' ||
a3.SUR_NAME || ' at ' || a1.SOLD_DATE || ', Making a profit of ' ||
to_char(a1.SOLD_PRICE - a1.PURCHASE_PRICE) ||' pounds.' AS "Selling Report",
to_char(SELECT sum(a5.SOLD_PRICE)-sum(a5.PURCHASE_PRICE)
FROM CAR a5
where (to_date(a5.SOLD_DATE,'mm-dd-yyyy') <= to_date(a1.SOLD_DATE,'mm-dd-yyyy'))
ORDER BY a5.SOLD_DATE
GROUP BY a5.SOLD_DATE) AS "OVERALL Report"
FROM CAR a1,
CUSTOMER a2,
staff a3,
ADDRESS a4
WHERE a1.BOUGHT_BY_CUSTOMER_NO = a2.CUSTOMER_NO and
a1.SOLD_BY_STAFF_NO = a3.STAFF_NO and
a4.ADDRESS_NO = a2.ADDRESS_NO
ORDER BY a1.SOLD_DATE
One issue is that the view is defined as returning a single column ("Selling Report"), but the query actually returns two columns ("Selling Report" and "OVERALL Report").
Another issue is that you can't put a sub-select into a function call; in this case
to_char(SELECT sum(a5.SOLD_PRICE)-sum(a5.PURCHASE_PRICE)
FROM CAR a5
where (to_date(a5.SOLD_DATE,'mm-dd-yyyy') <= to_date(a1.SOLD_DATE,'mm-dd-yyyy'))
ORDER BY a5.SOLD_DATE
GROUP BY a5.SOLD_DATE)
simply isn't valid. I'm not sure what you're trying to do with this sub-query so I can't really advise you on how to correct the problem.
Best of luck.
I'm trying to make a description of a track including all details related to it.
SELECT
(SELECT
UPPER(Track.Name) || ' is a ' ||
CAST(Track.Milliseconds/1000 AS INT) || ' seconds long track in the album ' ||
UPPER(Album.Title) || ' of ' ||
Artist.Name || ' composed by ' ||
CASE WHEN Track.Composer IS NULL THEN 'an unknown composer' ELSE Track.Composer END ||
'. ' || 'It is available as a ' ||
MediaType.Name || ' for $' ||
Track.UnitPrice || ', and it can be found in the following playlists: ' ||
Playlist.Name )
AS 'Track Description' FROM Track
LEFT JOIN Album
ON Track.AlbumId=Album.AlbumId
INNER JOIN Artist
ON Artist.ArtistId=Album.ArtistId
INNER JOIN MediaType
ON Track.MediaTypeId=MediaType.MediaTypeId
INNER JOIN PlaylistTrack
ON PlaylistTrack.TrackId = Track.TrackId
INNER JOIN Playlist
ON Playlist.PlaylistId = PlaylistTrack.PlaylistId
ORDER BY RANDOM()
LIMIT 1;
I'm up to working with playlist.name. One track can be in more than one playlist and currently it only outputs the top playlist. I want to know how i can output all playlists the track is in separated by commas after and it can be found in the following playlists: ' ||
One strategy would be to use GROUP_CONCAT to aggregate all the playlist names in which a given track appears. To do this, you can GROUP BY every column associated with a track except for the playlist name. The subquery computes your output in pretty format from the inner query.
SELECT UPPER(t.trackName) || ' is a ' ||
CAST(t.trackMillis/1000 AS INT) || ' seconds long track in the album ' ||
UPPER(t.albumTitle) || ' of ' ||
t.artistName || ' composed by ' ||
CASE WHEN t.trackComposer IS NULL THEN 'an unknown composer' ELSE t.trackComposer END ||
'. ' || 'It is available as a ' ||
t.mediaTypeName || ' for $' ||
t.trackUnitPrice || ', and it can be found in the following playlists: ' || t.playlistNames
FROM
(
SELECT Track.Name AS trackName, Track.Milliseconds AS trackMillis,
Album.Title AS albumTitle, Artist.Name AS artistName,
Track.Composer AS trackComposer, MediaType.Name AS mediaTypeName,
Track.UnitPrice AS trackUnitPrice, GROUP_CONCAT(Playlist.Name) AS playlistNames
FROM Track
LEFT JOIN Album
ON Track.AlbumId = Album.AlbumId
INNER JOIN Artist
ON Artist.ArtistId = Album.ArtistId
INNER JOIN MediaType
ON Track.MediaTypeId = MediaType.MediaTypeId
INNER JOIN PlaylistTrack
ON PlaylistTrack.TrackId = Track.TrackId
INNER JOIN Playlist
ON Playlist.PlaylistId = PlaylistTrack.PlaylistId
GROUP BY Track.Name, Track.Milliseconds, Album.Title, Artist.Name,
Track.Composer, MediaType.Name, Track.UnitPrice
) t
I have this Query
SELECT NAME_NO
,(
SELECT FNAME || ' ' || LNAME || ' ' || BIRTH_DT || ' ' || ' ' || PHONE
FROM NAMES
WHERE NAME_NO = 1
) AS "NAME1: NAME, DOB, PHONE"
,(
SELECT FNAME || ' ' || LNAME || ' ' || BIRTH_DT || ' ' || ' ' || PHONE
FROM NAMES
WHERE NAME_NO = 2
) AS "NAME2: NAME, DOB, PHONE"
,
FROM NAMES;
I get this error:
01427. 00000 - "single-row subquery returns more than one row"
I need multiple records.
What is the best method to solve this?
Try this one:
SELECT NAME_NO, FNAME || ' ' || LNAME || ' ' || BIRTH_DT || ' ' || ' ' || PHONE AS "NAME1: NAME, DOB, PHONE"
FROM NAMES
UNION
SELECT FNAME || ' ' || LNAME || ' ' || BIRTH_DT || ' ' || ' ' || PHONE AS "NAME2: NAME, DOB, PHONE"
FROM NAMES
WHERE NAME_NO = 2
or this one:
WITH N1 AS (
SELECT NAME_NO,FNAME || ' ' || LNAME || ' ' || BIRTH_DT || ' ' || ' ' || PHONE AS "VAL"
FROM NAMES
WHERE NAME_NO = 1),
N2 AS (
SELECT FNAME || ' ' || LNAME || ' ' || BIRTH_DT || ' ' || ' ' || PHONE AS "VAL"
FROM NAMES
WHERE NAME_NO = 2)
SELECT
NAME_NO,VAL
FROM N1,N2;
You need to use PIVOT. Try this
Select A "NAME1: NAME, DOB, PHONE" , B "NAME2: NAME, DOB, PHONE" from (SELECT FNAME || ' ' || LNAME || ' ' || BIRTH_DT || ' ' || ' ' || PHONE N, NAME_NO
FROM NAMES)
Pivot
(Max(N) for NAME_NO in (1 as A, 2 as B)
);
I have complex Select statement in Oracle, with Case When conditions and they select all Concatenate values.
So something similar to this:
END
END
FROM something
...
What I need is to put Other value from other table instead of My Value in concatenate.
So Instead of (My Value) I would have:
(Select textValue from textView A where A.textID = '395')
If I run this statement alone, it will take out one exact value I want. However if I put it instead of (My Value) into concatenate it gives me error: ora-00936 missing expression
(Yes '395' is string in that other table)
Any Ideas please?
You can use inline views inside the case clause in Oracle. Isn't that what you are trying to do? "Missing expression" error is probably a missing bracket or some similar code error.
select case object_type
when 'TABLE' then
'select * from ' || object_name
when 'SYNONYM' then
'describe ' || object_name
when 'PACKAGE' then
(select to_char (count (*))
from user_source s
where s.type = o.object_type and s.name = o.object_name)
else
(select object_type from dual)
end
as objects
from user_objects o
Or simply create a function that returns that does this for you and call it.
create function gettextval (p_textid in varchar2)
return varchar2 is
l_returnval varchar2 (32767);
begin
select text_val
into l_returnval
from v_texts s
where s.text_id = p_textid;
return l_returnval;
exception
when no_data_found then
return p_textid;
end;
In this example I make it return the input string of nothing is found.
Then you can reference the function in your previous select.
' || gettextval('395') || '
can you post you query with the "select text" bit inside?
When use case->when i do like that:
SELECT
CASE A.LIST_TYPE_CD
WHEN '1' THEN '<A HREF="censured?thresholdId=censured' || GET_SITE_SUFFIX() || chr(38) || 'task=runSQL' || chr(38) || 'parseParams=true' || chr(38) || 'list_id=' || A.LIST_ID || chr(38) || 'list_name=' || A.LIST_NAME ||
'">' || (Select textValue from textView A where A.textID = '395') || '</A>'
WHEN '3' THEN '<A HREF=censured' || GET_SITE_SUFFIX() || chr(38) || 'task=runSQL' || chr(38) || 'parseParams=true' || chr(38) || 'list_id=' || A.LIST_ID ||
'">' || (Select textValue from textView B where B.textID = '395') || '</A>'
END
FROM something A