Multiple values in same cell - sql

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

Related

Oracle SQL Developer query not sorting alphabetically

My query:
SELECT
pmmr.REQUEST_NO, pmmr.item_code itemCode, Pmmr.Form_No Form_No,
NVL(Pmf.Form_Name, Pmmr.Form_No) formName, pmmr.MRN,
NVL(p.FIRST_NAME || DECODE(p.FAMILY_NAME, NULL, '', ' ' || p.FAMILY_NAME),pmmr.MRN) PATIENT_NAME,
pmmr.ASSIGNED_TO, pmmr.DRUG_GENERIC_NAME, pmmr.LAST_STATUS,
NVL(initcap(( hr1.FIRST_NAME || ' ' || hr1.LAST_NAME)), pmmr.LAST_PERFORMER_ID) LastActionBy,
NVL(hr2.DEPARTMENT || ' - ' || hr2.SECTION_NAME,'') ORGANIZATION_UNIT,
NVL(initcap(( hr2.FIRST_NAME || ' ' || hr2.LAST_NAME)), pmmr.REQUESTER_ID) RequesterName,
pmmr.REQUEST_DATE
FROM
inhouse_apps.PHRM_MFRP_MEDICATION_REQUEST pmmr
LEFT OUTER JOIN
inhouse_apps.Hr_Employee hr1 ON Pmmr.Last_Performer_Id = Hr1.Employee_Number
LEFT OUTER JOIN
inhouse_apps.Hr_Employee hr2 ON inhouse_apps.Pmmr.Requester_Id = Hr2.Employee_Number
LEFT OUTER JOIN
EAPPTMT.PATIENT p ON inhouse_apps.Pmmr.Mrn = P.Mrn
LEFT OUTER JOIN
inhouse_apps.Phrm_Mfrp_Form pmf ON Pmmr.Form_No = Pmf.Form_No;
WHERE
LAST_STATUS IN ('Approved')
AND Pmmr.Form_No = 2
ORDER BY
pmmr.DRUG_GENERIC_NAME ASC
I need the DRUG_GENERIC_NAME sorted alphabetically, but it's not returning the result sorted ..
EDIT: as mentioned below the semicolon needed to be removed, that's all
You have semicolon ";" before your "Where clause". You need to remove it from there to make Oracle take account of both your "Where clause" and your "Order by clause"
SELECT pmmr.REQUEST_NO, pmmr.item_code itemCode, Pmmr.Form_No Form_No, nvl(Pmf.Form_Name, Pmmr.Form_No) formName, pmmr.MRN, nvl (p.FIRST_NAME || DECODE(p.FAMILY_NAME, NULL, '', ' ' || p.FAMILY_NAME),pmmr.MRN) PATIENT_NAME,pmmr.ASSIGNED_TO,
pmmr.DRUG_GENERIC_NAME,pmmr.LAST_STATUS, nvl(initcap(( hr1.FIRST_NAME || ' ' || hr1.LAST_NAME)),pmmr.LAST_PERFORMER_ID) LastActionBy,
nvl(hr2.DEPARTMENT || ' - ' || hr2.SECTION_NAME,'') ORGANIZATION_UNIT, nvl(initcap(( hr2.FIRST_NAME || ' ' || hr2.LAST_NAME)),pmmr.REQUESTER_ID) RequesterName, pmmr.REQUEST_DATE
FROM inhouse_apps.PHRM_MFRP_MEDICATION_REQUEST pmmr
left outer join inhouse_apps.Hr_Employee hr1 on Pmmr.Last_Performer_Id = Hr1.Employee_Number
left outer join inhouse_apps.Hr_Employee hr2 on inhouse_apps.Pmmr.Requester_Id = Hr2.Employee_Number
left outer join EAPPTMT.PATIENT p on inhouse_apps.Pmmr.Mrn = P.Mrn
left outer join inhouse_apps.Phrm_Mfrp_Form pmf on Pmmr.Form_No = Pmf.Form_No
WHERE LAST_STATUS IN ('Approved')
and Pmmr.Form_No = 2
order by pmmr.DRUG_GENERIC_NAME ASC
;

How can i turn this pl/sql into a procedure

I had to write this query for an assignement. So we have a database and we are pulling information from it, this is going to work with some back end c# eventually. Is there anything i can do , knowing im going to reuse this, in order to make it better and more adaptable when the day comes when i have to connect it all.
set serveroutput on
DECLARE
LV_DATE HVK_RESERVATION.RESERVATION_START_DATE%TYPE;
LV_SERV VARCHAR(100);
CURSOR LCUR_RES IS
SELECT *
FROM HVK_RESERVATION R
INNER JOIN HVK_PET_RESERVATION PR
ON R.RESERVATION_NUMBER = PR.RES_RESERVATION_NUMBER
INNER JOIN HVK_PET P
ON P.PET_NUMBER = PR.PET_PET_NUMBER
INNER JOIN HVK_OWNER OW
ON OW.OWNER_NUMBER = P.OWN_OWNER_NUMBER
WHERE R.RESERVATION_START_DATE < LV_DATE
AND R.RESERVATION_END_DATE > LV_DATE;
CURSOR LCUR_SERVICE(PET_RES_NUM NUMBER) IS
SELECT *
FROM HVK_SERVICE S
INNER JOIN HVK_PET_RESERVATION_SERVICE PRS
ON PRS.SERV_SERVICE_NUMBER = S.SERVICE_NUMBER
AND PRS.PR_PET_RES_NUMBER = PET_RES_NUM;
BEGIN
LV_DATE := TO_DATE('&logdate', 'yy-mm-dd');
DBMS_OUTPUT.PUT_LINE('Kennel log for ' || '' || LV_DATE);
DBMS_OUTPUT.PUT_LINE('-------------------------------');
FOR I IN LCUR_RES LOOP
DBMS_OUTPUT.PUT_LINE('Run:' || '' || I.RUN_RUN_NUMBER || ' ' ||
'Pet: ' || '' || I.PET_NAME || ' ' ||
I.OWNER_LAST_NAME || ' Pet Reservation: ' || '' ||
I.PET_RES_NUMBER);
DBMS_OUTPUT.PUT_LINE('Reservation start/end ' || ' ' ||
I.RESERVATION_START_DATE || ' ' ||
I.RESERVATION_END_DATE);
DBMS_OUTPUT.PUT('Services : ');
FOR X IN LCUR_SERVICE(I.PET_RES_NUMBER) LOOP
DBMS_OUTPUT.PUT(X.SERVICE_DESCRIPTION || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
FOR LREC_LOG IN (SELECT *
FROM HVK_KENNEL_LOG KL
WHERE KL.PR_PET_RES_NUMBER = I.PET_RES_NUMBER
) LOOP
DBMS_OUTPUT.PUT_LINE('Notes: ' || '' ||
LREC_LOG.KENNEL_LOG_SEQUENCE_NUMBER || ' ' ||
'Log Note: ' || '' || LREC_LOG.KENNEL_LOG_NOTES);
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
END LOOP;
END;
It it supposed to output the run number , reservation number , pet name , and any relate notes.
you can replace DECLARE with CREATE OR REPLACE PROCEDURE my_proc(in_logdate in date) IS.
in that case my_proc will be the name of your procedure.
you should also use a parameter instead of &logdate
so e.g. parameter name in_logdate of type date
...
LV_DATE := in_logdate;
...

select in select inner join

I try to make an inner join on select. My select statement is like below
SELECT con.fpd_no,
con.contract_no,
cm.cust_name,
(select cm.cust_name, TRIM(cm.address) || ', ' || TRIM(cm.zipcode) || ', ' || TRIM(klm.kelurahan_desc) || ', ' || TRIM(kcm.kecamatan_desc) || ', ' || TRIM(kbm.kabupaten_desc) || ', ' || TRIM(prm.propinsi_desc)
from customer_master cm
inner join kelurahan_master klm on klm.kelurahan_id=cm.kelurahan_id
inner join kecamatan_master kcm on kcm.kecamatan_id=klm.kecamatan_id
inner join kabupaten_master kbm on kbm.kabupaten_id=kcm.kabupaten_id
inner join propinsi_master prm on prm.propinsi_id=kbm.propinsi_id;) as address,
con.principal_amount
FROM contract con
JOIN customer_master cm ON cm.cust_no = con.cust_no
WHERE con.deal_code = 'A005'
AND con.fpd_date BETWEEN '01-01-2016' AND '31-01-2016'
AND con.fpd_no = '0103006116'
AND con.objt_group = 'MOTOR';
but I get this error:
ORA-00911: invalid character.
try this:
remove semicolon on subselect and sure about select returns only one row
SELECT con.fpd_no, con.contract_no, cm.cust_name, (select distinct cm.cust_name, TRIM(cm.address) || ', ' || TRIM(cm.zipcode) || ', ' || TRIM(klm.kelurahan_desc) || ', ' || TRIM(kcm.kecamatan_desc) || ', ' || TRIM(kbm.kabupaten_desc) || ', ' || TRIM(prm.propinsi_desc)
from customer_master cm
inner join kelurahan_master klm on klm.kelurahan_id=cm.kelurahan_id
inner join kecamatan_master kcm on kcm.kecamatan_id=klm.kecamatan_id
inner join kabupaten_master kbm on kbm.kabupaten_id=kcm.kabupaten_id
inner join propinsi_master prm on prm.propinsi_id=kbm.propinsi_id) as address, con.principal_amount
FROM contract con
JOIN customer_master cm ON cm.cust_no = con.cust_no
WHERE con.deal_code = 'A005'
AND con.fpd_date BETWEEN '01-01-2016' AND '31-01-2016'
AND con.fpd_no = '0103006116'
AND con.objt_group = 'MOTOR';

Why keeps showing this error: ORA-00936: missing expression

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.

Query causing values to not be included

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.