I have 2 query.
I am trying to join them so I just write export from one instead of manually joining them in excel.
(SELECT
b.OUT_NO,
a.ACCNO,
a.BILL_ACCNO,
a.NAME,
a.HOUSE_NO,
a.STREET,
a.HOUSE_NO2,
a.ZIP,
a.ID,
b.TIME_STAMP,
b.REST_DATE,
c.RESTORED_TIME,
b.OUT_CMNT
FROM brook.account a,
brook.problem b,
brook.history c
WHERE c.OUT_NO = b.OUT_NO
AND a.ID = c.ID
AND ( (a.NAME Is Not Null)
AND (a.DISC Is Null)
AND (b.TIME_STAMP>?)
AND (c.RESTORED_TIME<?))
)
and
(SELECT
b.OUT_NO,
a.ACCNO,
a.BILL_ACCNO,
a.NAME,
a.HOUSE_NO,
a.STREET,
a.HOUSE_NO2,
a.ZIP,
a.ID,
b.TIME_STAMP,
b.REST_DATE,
c.RESTORED_TIME,
b.OUT_CMNT
FROM brook.account a,
brook.problem b,
brook.history c
WHERE c.OUTAGE_NO = b.OUTAGE_NO
AND a.ID = c.ID
AND ( (a.NAME Is Not Null)
AND (a.DISC Is Null)
AND (b.TIME_STAMP > ? And b.TIME_STAMP < ?)
AND (c.RESTORED_TIME > ? And c.RESTORED_TIME < ?)
)
)
How can I join these 2? into 1, I tried UNION ALL but I get ora-01847 day of month must be between 1 and last day of month ERROR.
? are the parameter, it is linked to cells on spreadsheet.
format of excel data parameter. 11/04/2013 00:00:00
Thanks
Error is about a date format, not about union.
If you pass cell values as string parameters Oracle tries to convert it to dates to comapre with columns of date or timestamp values in table columns. To do this conversion Oracle uses it's internal default date representation format wich is not mm/dd/yyyy hh24:mi:ss in your case.
There are 2 possibilities to fix a situation:
Pass parameters with date type to query and convert values to dates before passing it to Oracle. Check examples on MSDN and description of CreateParameter and Parameters.Append methods.
Convert values to dates in query with to_date Oracle function.
Change conditions in query from
AND (b.TIME_STAMP>?)
AND (c.RESTORED_TIME<?))
and
AND (b.TIME_STAMP > ? And b.TIME_STAMP < ?)
AND (c.RESTORED_TIME > ? And c.RESTORED_TIME < ?)
to
AND (b.TIME_STAMP > to_date(?,'mm/dd/yyyy hh24:mi:ss') )
AND (c.RESTORED_TIME < to_date(?,'mm/dd/yyyy hh24:mi:ss') ))
and
AND (
b.TIME_STAMP > to_date(?,'mm/dd/yyyy hh24:mi:ss')
And
b.TIME_STAMP < to_date(?,'mm/dd/yyyy hh24:mi:ss')
)
AND (
c.RESTORED_TIME > to_date(?,'mm/dd/yyyy hh24:mi:ss')
And
c.RESTORED_TIME < to_date(?,'mm/dd/yyyy hh24:mi:ss')
)
Related
I have written 2 sql queries by using multiple join statements.
Now I want to combine both the query results as below.
First query shows these columns
UDC_ID, EXT_ID, VALUE
The second query shows these columns
UDC_ID, EXT_ID, VALUE
In both the queries UDC_ID and EXT_ID columns are the same, but the VALUE column in each is different
So the final output I want to display is,
UDC_ID, EXT_ID, VALUE (From Query1), VALUE (from Query 2)
Can anyone suggest how this can be achieved?
These are my queries:
Query 1 joins three tables:
SELECT
DEV.UDC_ID,
SR.EXT_ID,
SRA.VALUE
FROM SERVICE_REQUEST SR
JOIN DEVICE DEV
ON SR.DEVICE_ID = DEV.ID
JOIN SERVICE_REQUEST_ATTR SRA
ON SR.ID = SERVICE_REQUEST_ID
WHERE SR.SUB_TYPE_CD = 'HMI_22'
--AND DEV.SUB_TYPE = 'ESME'
AND SRA.NAME = 'CommsHubGUID'
AND SR.INSERT_TIME >= TO_DATE('2016-09-21 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
AND SR.INSERT_TIME <= TO_DATE('2016-09-28 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
ORDER BY SR.INSERT_TIME DESC;
The difference between query 1 and this query is the where clause criterion for SRA.NAME field, otherwise both the queries are same.
SELECT
DEV.UDC_ID,
SR.EXT_ID,
SRA.VALUE
FROM SERVICE_REQUEST SR
JOIN DEVICE DEV
ON SR.DEVICE_ID = DEV.ID`enter code here`
JOIN SERVICE_REQUEST_ATTR SRA
ON SR.ID = SERVICE_REQUEST_ID
WHERE SR.SUB_TYPE_CD = 'HMI_22'
--AND DEV.SUB_TYPE = 'ESME'
AND SRA.NAME = 'Service Location'
AND SR.INSERT_TIME >= TO_DATE('2016-09-21 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
AND SR.INSERT_TIME <= TO_DATE('2016-09-28 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
ORDER BY SR.INSERT_TIME DESC
SELECT COALESCE(q1.UDC_ID,q2.UDC_ID),
COALESCE(q1.EXT_ID, q2.EXT_ID),
q1.VALUE ,
q2.VALUE
FROM (query 1) q1
FULL OUTER JOIN (query 2) q2 ON q1.UDC_ID=q2.UDC_ID and q1.EXT_ID=q2.EXT_ID
Here is my original query that I was using in postgres -
SELECT a.id,
(SELECT val
FROM database.detail x
WHERE name = 'blablah'
AND x.id = b.id) AS myGroup,
c.username,
a.someCode,
a.timeTaken,
a.date ::timestamp WITH time ZONE AT time ZONE 'PST' AS date,
SUM (CASE WHEN (b.name = 'name1') THEN b.val ::INTEGER ELSE 0 END ) AS name11,
SUM (CASE WHEN (b.name = 'name2') THEN b.val ::INTEGER ELSE 0 END ) AS name12
FROM
database.myTable a,
database.detail b,
database.client c
WHERE
a.id = b.id
AND a.c_id = c.c_id
AND a.date > current_date - interval '2 weeks'
GROUP BY 1, 2, 3, 4, 5, 6
Following is how I converted this query into Amazon redshift query.
SELECT a.id,
b.val AS myGroup,
c.username,
a.someCode,
a.timeTaken,
convert_timezone('PST', a.date) AS date,
SUM (CASE WHEN (b.name = 'name1') THEN b.val ::INTEGER ELSE 0 END ) AS name11,
SUM (CASE WHEN (b.name = 'name2') THEN b.val ::INTEGER ELSE 0 END ) AS name12
FROM
database.myTable a,
database.detail b,
database.client c
WHERE
a.id = b.id
AND b.name = 'blablah'
AND a.c_id = c.c_id
AND a.date > current_date - interval '2 weeks'
GROUP BY 1, 2, 3, 4, 5, 6 LIMIT 10
The CASE statement does not seem to be executing the way it is expected, basically the values for name11 and name12 are all zero. My postgres query returns valid values for these but the redshift query does not.
Also, this query is very very slow. Postgres query takes some 150 ms and this query takes 2 mins.
How can we do this better?
Redshift Query optimization comes from Cluster, Table Design, DataLoading, Data Vacuuming &Analyzing over the table.
Let me answer some core touch points in the above list.
1. Make Sure your table mytable, detail, client has proper SORT_KEY, DIST_KEY
2. Make Sure all your tables in join are analzed and vaccumed properly.
Here is another version of your same SQL written in Redshift format.
Few Tweaks I made are
Used "With Clause" to Optimized Cluster level computation
Used Joins the proper way and make sure left/right join matters
based on data.
Used date_range with clause table for kind of object orientation.
Used Group By in the main SQL below.
My Version of Redshift SQL
/** Date Range Computation **/
with date_range as (
select ( current_Date - interval '2 weeks' ) as two_weeks
),
/** Filter main ResultSet**/
myGroupSet as (
SELECT b.val AS myGroup,
c.username,
a.someCode,
a.timeTaken,
(case when (b.name == 'name1') THEN b.val::INTEGER ELSE 0 END ) as name11,
(case when (b.name == 'name2') THEN b.val::INTEGER ELSE 0 END ) as name12
FROM database.myTable a,
join date_range dr on a.date > dr.two_weeks
join database.detail b on b.id = a.id
join database.client c on c.c_id = a.c_id
where a.date > current_Date - interval '2 weeks'
)
/** Apply Aggregation **/
select myGroup, username, someCode, timeTaken, date,
sum(name1), sum(name2)
from myGroupSet
group by myGroup, username, someCode, timeTaken, date
I have the following query that groups every tender id and description and shows its total Sum:
3020 American Express 20
1000 Cash - primary currency 9903.25
3120 House Card 2605.56
4070 Purchase Order 668.25
3000 Visa 26005.19
SELECT B.TENDER_TYPE_ID, A.TENDER_TYPE_DESC, SUM (B.TENDER_AMT)
FROM POS_TENDER_TYPE_HEAD A, SA_TRAN_TENDER B, SA_TRAN_HEAD C
WHERE A.TENDER_TYPE_ID = B.TENDER_TYPE_ID AND B.TRAN_SEQ_NO = C.TRAN_SEQ_NO
GROUP BY B.TENDER_TYPE_ID, A.TENDER_TYPE_DESC
In the table C (SA_TRAN_HEAD), there is a field of TRAN_DATETIME.
I want the query to return the results falling between an interval of dates but do not want the date to appear in the query columns.
What could I do to achieve this ?
Just add the desired date range to the WHERE clause:
SELECT B.TENDER_TYPE_ID,
A.TENDER_TYPE_DESC,
SUM (B.TENDER_AMT)
FROM POS_TENDER_TYPE_HEAD A,
SA_TRAN_TENDER B,
SA_TRAN_HEAD C
WHERE A.TENDER_TYPE_ID = B.TENDER_TYPE_ID AND
B.TRAN_SEQ_NO = C.TRAN_SEQ_NO AND
C.TRAN_DATETIME BETWEEN TO_DATE('01-JAN-2015', 'DD-MON-YYYY')
AND TO_DATE('31-MAR-2015', 'DD-MON-YYYY')
GROUP BY B.TENDER_TYPE_ID,
A.TENDER_TYPE_DESC
I also suggest you get used to using ANSI join syntax, as it makes the joins much clearer and is more transportable (particularly for outer joins). The following should be equivalent:
SELECT B.TENDER_TYPE_ID,
A.TENDER_TYPE_DESC,
SUM (B.TENDER_AMT)
FROM POS_TENDER_TYPE_HEAD A
INNER JOIN SA_TRAN_TENDER B
ON B.TENDER_TYPE_ID = A.TENDER_TYPE_ID
INNER JOIN SA_TRAN_HEAD C
ON C.TRAN_SEQ_NO = B.TRAN_SEQ_NO
WHERE C.TRAN_DATETIME BETWEEN TO_DATE('01-JAN-2015 00:00:00', 'DD-MON-YYYY HH24:MI:SS')
AND TO_DATE('31-MAR-2015 23:59:59', 'DD-MON-YYYY HH24:MI:SS')
GROUP BY B.TENDER_TYPE_ID,
A.TENDER_TYPE_DESC
This makes it clear what the join criteria are, as opposed to the filter criteria.
I have this query
SELECT *
FROM (SELECT mi.visit_id, mi.event_id, mi.patient_id, mi.mrn, mi.reg_date,
mi.d_date, mi.bml_count, mi.TYPE, mblp.baby_patient_id,
mblp.baby_birthdate
FROM ajmid.km0076_motherinfo_test mi LEFT JOIN alfayezb2.mbl_patients mblp
ON mblp.mother_patient_id = mi.patient_id
--works here
AND ( TO_CHAR (mblp.baby_birthdate, 'mm/dd/YYYY') =
TO_CHAR (mi.reg_date, 'mm/dd/YYYY')
OR TO_CHAR (mblp.baby_birthdate, 'mm/dd/YYYY') =
TO_CHAR (mi.reg_date - 1, 'mm/dd/YYYY')
OR TO_CHAR (mblp.baby_birthdate, 'mm/dd/YYYY') =
TO_CHAR (mi.reg_date + 1, 'mm/dd/YYYY')
)
) bml
LEFT OUTER JOIN --doesn't work here
(SELECT ROW_NUMBER () OVER (PARTITION BY vis.patient_id ORDER BY vis.admission_date_time)
num,
vis.admission_date_time, vis.visit_id, vis.patient_id,
vis.facility_id
FROM visit vis) v ON bml.baby_patient_id = v.patient_id
WHERE v.num = 1
ORDER BY bml.reg_date
bml by itself returns 118 rows while the whole query returns 117, the reason is bml returns 1 row with baby_patient_id as null, so I used left outer join to show it, but it's still not showing !!
what can I do to show all rows of bml ?
I'm using Toad 9.6
Thank you
check the query:
SELECT ROW_NUMBER () OVER (PARTITION BY vis.patient_id ORDER BY vis.admission_date_time)
num,
vis.admission_date_time, vis.visit_id, vis.patient_id,
vis.facility_id
FROM visit vis
does it return 118 not null patient_id's?
if it returns 117, that might be the reason.(LEFT OUTER JOIN doesnot pick the records which are null on both tables)
Also, are you sure the null value of baby_patient_id in bml table is actually a NULL value and not a empty charater?(' ').
The probable cause is your filter / criteria (where clause) is eliminating a row with a null value for v.num. The WHERE filters the results after the join.
WHERE v.num = 1 -- Are all v.num equal to 1 ?
The mere action of using a criteria against a field, by definition of what NULL means, eliminates that row from consideration because NULL cannot be evaluated. You can say "WHERE id != 1" and expect to get rows where id is null because null != 1 right? Wrong. id != NULL is not defined logically. It is why we say "IS or IS NOT NULL" when dealing with NULL.
it's working finally !
I added
OR bml.baby_patient_id IS NULL
to the where clause, so the final script is
SELECT *
FROM (SELECT mi.visit_id, mi.event_id, mi.patient_id, mi.mrn, mi.reg_date,
mi.d_date, mi.bml_count, mi.TYPE, mblp.baby_patient_id,
mblp.baby_birthdate
FROM ajmid.km0076_motherinfo_test mi LEFT JOIN alfayezb2.mbl_patients mblp
ON mblp.mother_patient_id = mi.patient_id
AND ( TO_CHAR (mblp.baby_birthdate, 'mm/dd/YYYY') =
TO_CHAR (mi.reg_date, 'mm/dd/YYYY')
OR TO_CHAR (mblp.baby_birthdate, 'mm/dd/YYYY') =
TO_CHAR (mi.reg_date - 1, 'mm/dd/YYYY')
OR TO_CHAR (mblp.baby_birthdate, 'mm/dd/YYYY') =
TO_CHAR (mi.reg_date + 1, 'mm/dd/YYYY')
)
) bml
LEFT OUTER JOIN
(SELECT ROW_NUMBER () OVER (PARTITION BY vis.patient_id ORDER BY vis.admission_date_time)
num,
vis.admission_date_time, vis.visit_id, vis.patient_id,
vis.facility_id
FROM visit vis) v ON bml.baby_patient_id = v.patient_id
WHERE v.num = 1
OR bml.baby_patient_id IS NULL
ORDER BY bml.reg_date
I don't know how this was helpful, I wish someone would explain for me !
Thanks all
I have a following oracle sql query in which START_DATE is a number column and a_date is DATE type and the input value is also of type DATE. kindly let me know how to compare the date columns with the input date.
select a.id ,a.v ,b.id,b.v
from DATA a ,FDC b where a.START_DATE = to_date('11-DEC-10','YYYYMMDD')
and a.START_DATE = b.a_date and b.code = 'JFK'
select a.id ,a.v ,b.id,b.v
from DATA a ,FDC b where a.START_DATE LIKE TO_DATE('11-DEC-10','DD-MON-YY')
and a.START_DATE = b.a_date and b.code = 'JFK'
If you stored your START_DATE as Number like 'YYYYMMDD':
a.START_DATE=TO_NUMBER(TO_DATE('20101211','YYYYMMDD'))
It depends entirely on what format your number start_date column is stored in.
However, it would probably be easier if you used the predicate on the true date column, and joined using a format mask just once.
For example:
SELECT a.id,
a.v,
b.id,
b.v
FROM data a,
fdc b
WHERE b.a_date = to_date('11-DEC-2010','DD-MON-RRRR')
AND a.start_date = TO_NUMBER(TO_CHAR(b.a_date, 'DDMMRRRR'))
AND b.code = 'JFK'
Please note that the date format matches the format of the date you are comparing - b.a_date = to_date('11-DEC-2010','DD-MON-RRRR'). This query assumes that the a.start_date column is stored in the format DDMMRRRR. You would need to amend this for whichever format your date is stored in e.g. a.start_date = TO_NUMBER(TO_CHAR(b.a_date, 'J')) for a Julian date.
P.s. Why use a number to store a date?
select * from tbltlcrconfighistory where TO_DATE(STARTDATE,'dd-mon-yyyy') = TO_DATE('14-dec-2010','dd-mon-yyyy');
select * from tbltlcrconfighistory where STARTDATE = TO_DATE('14-dec-2010','dd-mon-yyyy');