I have this working query. It has count with subquery.
SELECT
COUNT(*) AS total
FROM
(SELECT
COUNT(aset)
FROM
`public_1`
WHERE `public_1`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8
GROUP BY aset) t
now I need to union with different table and get the total from both table. This code could get count record but the value is incorrect.
SELECT
COUNT(*) AS total
FROM
(SELECT
COUNT(aset)
FROM
`public_1`
WHERE `public_1`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8
UNION
SELECT
COUNT(aset)
FROM
`public_2`
WHERE `public_2`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8
GROUP BY aset) z
Please assist me in getting the query correct. Thanks in advance
Use SELECT COUNT(DISTINCT aset) to get your counts, and then add them together.
SELECT t1.total + t2.total AS total
FROM (
SELECT COUNT(DISTINCT aset) AS total
FROM `public_1`
WHERE `public_1`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8) AS t1
CROSS JOIN (
SELECT COUNT(DISTINCT aset) AS total
FROM `public_2`
WHERE `public_2`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8) AS t2
Related
I have one table which has the following data, I want to skip row 3, just want to fetch OPEN status only once, I am using below query but it skipping wor 5 as well.
SELECT t.*
FROM emailEvent t
JOIN
( SELECT MIN(id) AS minid
FROM emailEvent WHERE email_id = 3
GROUP BY status
) AS grp
ON grp.minid = t.id
WHERE (t.email_id = 3)
I came up with this as a solution but not sure if there are any other best solution for this
SELECT t.*
FROM emailEvent t
WHERE t.status != "Open" and t.email_id = 3
UNION
(
SELECT et.*
FROM emailEvent et
WHERE et.status = "Open" and et.email_id = 3
ORDER BY et.createdAt DESC LIMIT 1
)
I want the result to be look like something like this
SELECT *
FROM
(
SELECT t.*,
min(id) over (partition by status) as min_id
FROM emailEvent t
WHERE (t.email_id = 3) -- only email 3
) AS dt
WHERE id = min_id -- only for 'Open' status
OR status <> 'Open'
For older releases not supporting Windowed Aggregates:
select *
from emailEvent
where email_id = 3
and
(
e.status <> 'Open'
or id in (select min(id) -- only for 'Open' status
from emailEvent
where status = 'Open'
and email_id = 3)
)
With NOT EXISTS:
select e.* from emailEvent e
where e.status <> 'Open'
or not exists (select 1 from emailEvent where status = e.status and id < e.id)
I want to search both table with all the records for cid 23 here
Total is table1-cid:23&w_id:1+2->(500+300),
Advance is table1-cid:23&w_id:1+2(100+100)+table 2-w_id:1+2(100+100+100+150)
Pending is Total-Advance
Tried using below query to display last table in pic with no luck.
SELECT E.cid, SUM(E.total) as Total, SUM(E.advance)as Advance, (SUM(E.total)-SUM(E.advance)- SUM(R.advance)) as Pending
FROM table1 AS E
LEFT JOIN table2 R ON E.w_id=R.w_id
WHERE (E.cid =23)
This is not the best query I've done but I obtain the result you want:
wwtest1 = table-1 , wwtest2 = table 2.
SELECT w1.cid AS cid,
(SELECT SUM(total) FROM wwtest WHERE cid = 23) AS total,
((SELECT SUM(advance) FROM wwtest WHERE cid = 23) + (SELECT SUM(advance) FROM wwtest2)) AS advance,
((SELECT SUM(total) FROM wwtest WHERE cid = 23) - ((SELECT SUM(advance) FROM wwtest WHERE cid = 23) + (SELECT SUM(advance) FROM wwtest2))) AS pending
FROM wwtest w1
WHERE w1.cid = 23 GROUP BY w1.cid;
Basically I need to merge these into one single query:
SELECT COUNT( DISTINCT id ) AS totalRows1
FROM other_events WHERE status = "approved"
AND Location = 1
SELECT COUNT( DISTINCT Id ) AS totalRows2
FROM core_events WHERE Status = "Active"
AND Location_id = 1
When I do it like below, if there is no event with Location_id = 1 query returns 0. In that condition I need it to return the count of the first table only.
SELECT COUNT( DISTINCT t1.id ) + COUNT( DISTINCT t2.Id ) AS total
FROM other_events AS t1, core_events AS t2
WHERE t1.status = "approved"
AND t1.Location = 1
AND t2.Location_id = 1
AND t2.Status = 'Active'
ps. column names are exactly like above
Use a UNION statement to merge the result like this:
SELECT SUM(total) FROM (
SELECT COUNT(DISTINCT id) AS total
FROM other_events
WHERE (status = "approved" AND Location = 1)
UNION ALL
SELECT COUNT(DISTINCT Id) AS total
FROM core_events
WHERE (Location_id = 1 AND Status = 'Active')
) union_result
I have table called "users" and need to select 2 rows before and after specific row, sorted by users.score ASC
users table (structure):
id name score
1 John 2
2 Sara 1
3 san 3
4 test 2
5 jery 5
6 simon 6
7 bob2 7
8 jack 4
9 man 2
for example: need to select 2 rows before and after users.id = 5 order by users.score
result should be like:
id name score
3 san 3
8 jack 4
5 jery 5
6 simon 6
7 bob2 7
thanks,
Using union all and subqueries to limit the records should do it:
select * from users where id = 5
union all (
select * from users
where score < (select score from users where id = 5)
order by score desc limit 2
)
union all (
select * from users
where score > (select score from users where id = 5)
order by score asc limit 2
)
order by score
Sample SQL Fiddle
Edit: I think a better method is to number the rows according to score and then select the rows with number -2 and +2 from the rows of id 5:
select id, name, score
from (select
t.*, #rownum1 := #rownum1 + 1 as rank
from users t, (select #rownum1 := 0) r
order by score
) a,
(select rank from (
select t.*,
#rownum := #rownum + 1 as rank
from users t, (select #rownum := 0) r
order by score
) t
where id = 5
) b
where b.rank between a.rank -2 and a.rank+2
order by score;
Sample SQL Fiddle
Perhaps using union all
(
select * from users where id < 5 order by score limit 2
)
union all
(
select * from users where id > 5 order by score limit 2
)
(SELECT x.* FROM users x JOIN users y ON y.score <= x. score WHERE y.id = 5 ORDER BY score LIMIT 3)
UNION
(SELECT x.* FROM users x JOIN users y ON y.score >= x. score WHERE y.id = 5 ORDER BY score DESc LIMIT 3)
[ORDER BY score] ;
http://www.sqlfiddle.com/#!9/45c22/42
I just write the query, based on "jpw" solution (many thanks to him)
select * from users where id = 5
union all (
select * from users
where id in (select id from users where score < (select score from users u where u.id = 5) order by score ASC)
order by score desc limit 2
)
union all (
select * from users
where id in (select id from users where score > (select score from users u where u.id = 5) order by score ASC)
order by score ASC limit 2
)
order by score
Selecting arbitrarily ordered rows before and after a specific id
SET #j = 0;
SET #i = 0;
SELECT *
FROM (
SELECT id, col1, col2, ..., #j:=#j+1 AS pos
FROM `table`
WHERE col1=... ORDER BY col1 DESC, col2 ASC
) AS zz
WHERE (
SELECT position
FROM (
SELECT id AS id2, #i:=#i+1 AS position
FROM `table`
WHERE col1=... ORDER BY col1 DESC, col2 ASC
) AS zz
WHERE id2=$currId
)
IN (pos-5,pos-4,pos-3,pos-2,pos-1,pos,pos+1,pos+2,pos+3,pos+4,pos+5)
I have this table e.g.:
Id StatusDate Status
1 20-08-2014
1 15-08-2014
1 09-08-2014 P
2 17-08-2014
1 10-08-2014
2 12-08-2014
2 06-07-2014 P
1 30-07-2014
2 02-07-2014
2 01-07-2014 P
...... and so on
I want to select count by ID where status is blank until I hit the first 'P' in ascending order of date group by ID. So my results will be like this.
ID Count
1 3
2 2
Try it out. Not tested
SELECT t1.ID, count(*) FROM table t1
WHERE t1.StatusDate >= (SELECT MAX(t2.StatusDate) FROM table t2
WHERE t1.ID = t2.ID AND t2.Status = 'P')
GROUP BY t1.ID
Assuming your table name is StatusTable This will work:
SELECT
ID,
COUNT(*) AS `Count`
FROM StatusTable AS st
WHERE
st.Status = ''
AND st.StatusDate > (
SELECT st2.StatusDate
FROM `StatusTable` AS st2
WHERE st.ID = st2.ID
AND st2.Status = 'P'
ORDER BY st2.StatusDate DESC
LIMIT 1
)
GROUP BY st.ID
ORDER BY st.ID
One option is to use a JOIN and COUNT rows which have a lower statusdate value, like this:
SELECT t1.id, SUM(CASE WHEN t1.statusdate > t2.statusdate THEN 1 ELSE 0 END) AS mycount
FROM t t1 JOIN (
SELECT id, MIN(statusdate) statusdate
FROM t
WHERE status = 'P'
GROUP BY id
) t2
ON t1.id = t2.id
GROUP BY t1.id
Working Demo: http://sqlfiddle.com/#!2/d9d91/2