I have a following SQL Query:(Oracle 10)
SELECT
A.ID,
SUM(A.AMT_CR) - SUM(A.AMT_DR) AS balAmt,
P.NAME
FROM TABLE1 A, TABLE2 P
WHERE P.ID BETWEEN 'C0100' AND 'C0200'
AND P.ID = A.ID
AND A.TRANS_DATE < '01-FEB-2013'
GROUP BY A.ID, P.NAME
ORDER BY A.ID
Above query executes nicely, but this query has a condition AND A.TRANS_DATE < '01-FEB-2013'. This condition is for getting the balAmt before the TRANS_DATE. But the issue with this query is that it only gets the IDs with respect to AND A.TRANS_DATE < '01-FEB-2013' condition. If a ID doesn't have TRANS_DATE less than '01-FEB-2013' then it doesn't show the record for that ID.
So I want to get All IDs from database. But I want to get balAmt with respect to AND A.TRANS_DATE < '01-FEB-2013' condition..
Any suggestion will be appreciated.
Thanks in advance.
SELECT
A.ID,
SUM(case when A.TRANS_DATE < '01-FEB-2013'
then nvl(A.AMT_CR,0) - nvl(A.AMT_DR,0)
else 0
end) AS balAmt,
P.NAME
FROM TABLE1 A, TABLE2 P
WHERE P.ID BETWEEN 'C0100' AND 'C0200'
AND P.ID = A.ID
GROUP BY A.ID, P.NAME
ORDER BY A.ID
SELECT Q.ID, W.balmt, W.NAME
FROM TABLE1 Q
LEFT JOIN (
SELECT
A.ID,
SUM(A.AMT_CR) - SUM(A.AMT_DR) AS balAmt,
P.NAME
FROM TABLE1 A, TABLE2 P
WHERE P.ID BETWEEN 'C0100' AND 'C0200'
AND P.ID = A.ID
AND A.TRANS_DATE < '01-FEB-2013'
GROUP BY A.ID, P.NAME
) W
ON Q.ID = W.ID
ORDER BY A.ID
This should do:
SELECT
A.ID,
SUM(A.AMT_CR) - SUM(A.AMT_DR) AS balAmt,
P.NAME
FROM TABLE1 A
LEFT JOIN TABLE2 P ON P.ID = A.ID
AND A.TRANS_DATE < '01-FEB-2013'
AND P.ID BETWEEN 'C0100' AND 'C0200'
GROUP BY A.ID, P.NAME
ORDER BY A.ID
Related
I've below query, into which I'm creating using a subquery which is returning
ORA-01427: single-row subquery returns more than one-row error.
But I want all the values that subquery is returning, and there is no other column left for the join condition. Below is my sample query.
select name,
dob,
cdate,
(select value
from item a,
books b
where a.id = b.id
and a.newid = b.newid
and a.id = s.id
and a.bid = s.cid
and a.eventid=1) col_value,
(select value2
from item a,
books b
where a.id = b.id
and a.newid = b.newid
and a.id = s.id
and a.bid = s.cid
and a.eventid=1) col_value2
from sample s,
purchase p
where s.id = p.id
and s.cid = p.cid
Desired Output
Do I need to apply a Group By? Please let me know your suggestions.
It is little bit more difficult without data but try:
select name -- please use table alias so you know which table the value is from (s, p or cv)
, dob
, cdate
, cv.value
from sample s
left join purchase p on s.id=p.id and s.cid=p.cid --or just join
left join (select value, a.id, a.bid --or just join
from item a
left join books b --or just join
on a.id=b.id and a.newid=b.newid) cv
on cv.id = s.id and cv.bid = s.cid
left join (select value2
from item a
left join books b
on a.id = b.id and a.newid = b.newid) cv2
on cv2.id = s.id and cv2.bid = s.cid
where cv2.eventid=1;
select name,
dob,
cdate,
(select value
from
books b
where a.id = b.id
and a.newid = b.newid ) col_value,
(select value2
from
books b
where a.id = b.id
and a.newid = b.newid ) col_value2
from sample s,
purchase p,item a
where s.id = p.id
and s.cid = p.cid
and a.id(+)=s.id
and a.bid(+)=s.cid
and a.eventid(+)=1
I know this is simple for you sql people, but I am trying to combine two simple queries into one. It's probably obvious from the code that job.ActiveJob.ID = job.EstimateTbl.ID_Job.
I'm trying to get: id, JobName, sum(itemAmount)
Thanks for your help.
SELECT a.id, a.JobName
FROM job.ActiveJobsTbl AS a
WHERE a.ID = '100'
SELECT SUM(itemAmount)
FROM job.EstimateTbl
WHERE ID_Job = '100'
You can JOIN the tables by the ON E.ID_Job = A.ID and get the values in SELECT with GROUP BY
SELECT A.id, A.JobName, SUM(E.itemAmount) AS Amount
FROM job.ActiveJobsTbl AS A
INNER JOIN job.EstimateTbl E ON E.ID_Job = A.ID
WHERE A.ID = '100'
GROUP BY A.id, A.JobName;
using LEFT JOIN
SELECT a.id, a.JobName,EstimateTbl.itemAmount
FROM job.ActiveJobsTbl AS a
left join
(
SELECT SUM(itemAmount) itemAmount,ID_Job
FROM job.EstimateTbl
group by ID_Job
) EstimateTbl on EstimateTbl.ID_Job = a.ID
WHERE a.ID = '100'
You can use APPLY :
select a.id, a.JobName, t.itemAmount
from job.ActiveJobsTbl AS a OUTER APPLY
(SELECT SUM(t.itemAmount) AS itemAmount
FROM job.EstimateTbl AS t
WHERE t.ID_Job = a.ID
) t
WHERE a.ID = 100;
Try this:
SELECT A.id, A.JobName, SUM(E.itemAmount) AS Amount
FROM job.ActiveJobsTbl AS A
INNER JOIN job.EstimateTbl E ON E.ID_Job = A.ID
WHERE A.ID = '100'
GROUP BY A.id, A.JobName;
Hi I have following select statement
select
a.amount
,b.des
,a.id
,SUM(a.amount) as total
,b.id
from t_sales a
left outer join t_location b on(b.id=a.orgId)
where a.Id=#salesId and
a.sId=#supId
GROUP BY a.amount, b.des, a.Id,b.id;
Everything is working fine, except total. I am trying to get total of a.amount which is returning 15 values so I want to have total of all 15 values. Please let me know how to fix it.
Thanks
You should remove a.amount column from select list ( aggregate column should not exists in select list)
select b.des, a.id, a.amount ,SUM(a.amount) over(partition by 1) as total, b.id from t_sales a left outer join t_location b on(b.id=a.orgId)
where a.Id=#salesId and a.sId=#supId GROUP BY b.des, a.Id, b.id;
Please try:
select
a.amount
,b.des
,a.id
,SUM(a.amount) over(partition by 1) as total
,b.id
from t_sales a
left outer join t_location b on(b.id=a.orgId)
where
a.Id=#salesId and
a.sId=#supId;
Can you try
select a.amount, b.des, a.id, b.id,
(select sum(a.amount)
from t_sales a
left outer join t_location b on (b.id = a.orgId)
where a.Id = #salesId
and a.sId = #supId
GROUP BY b.des, a.Id, b.id) as total
from t_sales a
left outer join t_location b on (b.id = a.orgId)
where a.Id = #salesId
and a.sId = #supId
GROUP BY a.amount, b.des, a.Id, b.id;
I have a table(A) that looks something like:
ID Date
1 2012/01/12
2 2012/01/01
3 2012/01/03
4 2012/03/12
If I wanted to grab the MIN date for this query, would I just group by?
select
a.ID,
MIN(a.DATE),
b.name,
c.price
FROM
tablea a inner join tableb b on a.ID = b.ID
inner join tablec c b.ID = c.ID
You want a window function. The correct expression is:
select a.id,
min(a.date) over () as mindate,
b.name, c.price
. . .
This says to get the min of the date over the data. There is no partition, so it gets it over all the data.
If you are looking for those that had the minimum date, then you can do this:
select
a.ID,
a.DATE,
b.name,
c.price
FROM tablea a
INNER JOIN
(
SELECT Id, MIN(Date) AS MinDate
FROM tablea
GROUP BY Id
) As minA ON a.date = mina.mindate AND a.id = mina.id
inner join tableb b on a.ID = b.ID
inner join tablec c b.ID = c.ID
WITH recordList
as
(
select a.ID,
a.DATE,
b.name,
c.price,
DENSE_RANK() OVER (PARTITION BY a.ID
ORDER BY a.Date ASC) rn
FROM tablea a
inner join tableb b on a.ID = b.ID
inner join tablec c b.ID = c.ID
)
SELECT ID, DATE, name, Price
FROM recordList
WHERE rn = 1
In SQL Server, I have two tables. One "main" table with all the data and a unique id per entry. The other table is an audit log, where that id from main will be stored multiple times in the audit table.
My query looks like:
SELECT
a.title, a.id, a.name, t.user, t.time
FROM
MainTable a
INNER JOIN
AuditLog AS t ON a.id = t.id
WHERE
a.NAME LIKE 'Something%'
AND a.ACTIVE = 'Y'
Which gives a result like:
TITLE ID NAME USER TIME
----------------------------------------------------------------
Something1 someth1 Some 1 User5 468534771
Something1 someth1 Some 1 User7 468574887
Something2 someth2 Some 2 User6 468584792
Which returns multiple results of the ID. I only want the oldest (from AuditLog) entry and not every one. So the result I would want looks like:
TITLE ID NAME USER TIME
----------------------------------------------------------------
Something1 someth1 Some 1 User5 468534771
Something2 someth2 Some 2 User6 468584792
How can this be done? I'm trying some subqueries within the join.
In sql server 2005+, you can use row_number()
select title, id, name, user, time
from
(
SELECT a.title, a.id, a.name, t.user, t.time,
row_number() over(partition by a.id order by t.time) rn
FROM MainTable a
INNER JOIN AuditLog AS t
ON a.id = t.id
WHERE a.NAME LIKE 'Something%'
AND a.ACTIVE='Y'
) src
where rn = 1
See SQL Fiddle with Demo
Or you can use a sub-query to get the min time:
SELECT a.title, a.id, a.name, l.user, l.time
FROM MainTable a
INNER JOIN AuditLog l
ON a.id = l.id
INNER JOIN
(
select min(time) Mintime, id
from AuditLog
group by id
) AS t
ON l.id = t.id
AND l.time = t.mintime
WHERE a.NAME LIKE 'Something%'
AND a.ACTIVE='Y';
SELECT TOP 1 a.title, a.id, a.name, t.user, t.time
FROM MainTable a
INNER JOIN AuditLog AS t
ON a.id = t.id
WHERE a.NAME LIKE 'Something%'
AND a.ACTIVE='Y'
ORDER BY T.DATE DESC
You could use outer apply, like:
select *
from MainTable a
outer apply
(
select top 1 *
from AuditLog t
where a.id = t.id
order by
t.time
) t
where a.name like 'Something%'
and a.active = 'y'
Give this a try
SELECT a.title, a.id, a.name, t.user, t.time
FROM MainTable a
JOIN AuditLog AS t ON a.id = t.id
JOIN (SELECT ID, MAX(TIME) AS LASTTIME FROM AUDITLOG) AS c
ON c.ID = t.id AND c.LASTTIME = t.time
WHERE a.NAME LIKE 'Something%'
AND a.ACTIVE = 'Y'