I have the following two tables -
Table1
TR1 TR2
1 10
2 15
3 20
Table2
TC1 TC2
10 100
15 150
20 200
select count(*) from table1, table2 where table1.tr2 = table2.tc1 and table1.tr1 > 1 and table1.tr2 in (select table2.tc1 from table2 where table2.tc1 > 10)
select count(*) from table1, table2 where table1.tr2 = table2.tc1 and table1.tr1 > 1 and table1.tr1 < 5 and table1.tr2 in (select table2.tc1 from table2 where table2.tc1 > 10)
2nd query will return a subset of the first query, I want to find the difference in count(*)s given by the two queries. How do I go about it?
You can always do
select (select count(*) ...) - (select count(*) ...);
But as your queries are so similar, you can merge the queries instead:
select
count(*) - sum(t1.tr1 < 5)
from table1 t1
join table2 t2 on t1.tr2 = t2.tc1
where t1.tr1 > 1
and t1.tr2 > 10;
I've changed your comma-separated join to a proper ANSI join. Your join syntax was made redundant in 1992. You shouldn't use it anymore.
I've replaced your IN clause with a simple t1.tr2 > 10, because you are already joining on t1.tr2 = t2.tc1.
you can do the a diff this way
select (
select count(*)
from table1, table2
where table1.tr2 = table2.tc1
and table1.tr1 > 1
and table1.tr2 in (select table2.tc1 from table2 where table2.tc1 > 10)
) - (
select count(*)
from table1, table2
where table1.tr2 = table2.tc1
and table1.tr1 > 1
and table1.tr1 < 5
and table1.tr2 in (select table2.tc1 from table2 where table2.tc1 > 10)
) as my_diff
from dual;
Related
Hypothetical data -
tbl1 -
id
date
value1
101
2021-01-01
200
101
2021-01-03
400
tbl2 -
id
date
value2
101
2021-01-01
600
101
2021-01-02
900
My expected result is -
id
date
value1
value2
101
2021-01-01
200
600
101
2021-01-02
NaN
900
101
2021-01-03
400
NaN
select * from (select * from tbl1 where id in
(another query)) t1
left join tbl2 as t2 on t1.id = t2.id and t1.date = t2.date
union all
select * from (select * from tbl1 where id in
(another query)) t1
right join tbl2 as t2 on t1.id = t2.id and t1.date = t2.date
where t1.id is null and t1.date is null
I am unable to figure out where am I going wrong.
I think you might be overcomplicating your union query:
SELECT t1.id, t1.date, t1.value1, t2.value2
FROM tbl1 t1
LEFT JOIN tbl2 t2 ON t1.id = t2.id AND t1.date = t2.date
UNION ALL
SELECT t2.id, t2.date, t1.value1, t2.value2
FROM tbl1 t1
RIGHT JOIN tbl2 t2 ON t1.id = t2.id AND t1.date = t2.date
WHERE t1.id IS NULL
ORDER BY id, date;
Demo
Collect all present (id, `date`) pairs then join source data to it:
SELECT id, `date`, tbl1.value1, tbl2.value2
FROM ( SELECT id, `date` FROM tbl1
UNION
SELECT id, `date` FROM tbl2 ) combined
LEFT JOIN tbl1 USING (id, `date`)
LEFT JOIN tbl2 USING (id, `date`);
fiddle
The solution assumes that (id, `date`) is unique over each separate source table. If not then some aggregation must be used (SUM or MAX, depends on the logic).
I am trying to count the rows from table1, and depending the rows count to update a certain column. Below is the query I have tried, but am getting an arror saying that temp is not a table.
UPDATE table1 AS t1
INNER JOIN table1 AS temp ON temp.id = t1.id
SET
t1.field1 = (CASE
WHEN (SELECT COUNT(*) FROM temp WHERE temp.field1 = 1) < 100 THEN 1
WHEN (SELECT COUNT(*) FROM temp WHERE temp.field1 = 2) < 100 THEN 2
WHEN (SELECT COUNT(*) FROM temp WHERE temp.field1 = 3) < 100 THEN 3
WHEN (SELECT COUNT(*) FROM temp WHERE temp.field1 = 4) < 100 THEN 4
WHEN (SELECT COUNT(*) FROM temp WHERE temp.field1 = 5) < 100 THEN 5
END)
WHERE t1.id IN(100, 200, 300); --Example data
A couple things:
I would suggest making a temp table of the data in your case
statement, then joining that for an update.
Joining back on the table you're updating does not work.
You have a syntax error in your where clause. You don't need that
equals sign before IN.
Try:
DROP TABLE IF EXISTS temp_table1;
CREATE TEMPORARY TABLE temp_table1 AS
SELECT field1,count(*) as field_count FROM table1 group by field1;
UPDATE table1 AS t1
LEFT JOIN temp_table1 aa
ON aa.field1= t1.field1
SET t1.field1 = (CASE
WHEN aa.field1 = 1 AND aa.field_count < 100 THEN 1
WHEN aa.field1 = 2 AND aa.field_count < 100 THEN 2
WHEN aa.field1 = 3 AND aa.field_count < 100 THEN 3
WHEN aa.field1 = 4 AND aa.field_count < 100 THEN 4
WHEN aa.field1 = 5 AND aa.field_count < 100 THEN 5 END)
WHERE t1.id IN (100, 200, 300);
Following query will be helpful to you,
UPDATE table1 as t1
SET
t1.field1 = (CASE
WHEN (select p.cnt from (SELECT COUNT(*) as cnt FROM table1 t2 WHERE t2.field1= 1) as p) < 100 THEN 1
WHEN (select p.cnt from (SELECT COUNT(*) as cnt FROM table1 t2 WHERE t2.field1= 2) as p) < 100 THEN 2
WHEN (select p.cnt from (SELECT COUNT(*) as cnt FROM table1 t2 WHERE t2.field1= 3) as p) < 100 THEN 3
WHEN (select p.cnt from (SELECT COUNT(*) as cnt FROM table1 t2 WHERE t2.field1= 4) as p) < 100 THEN 4
WHEN (select p.cnt from (SELECT COUNT(*) as cnt FROM table1 t2 WHERE t2.field1= 5) as p) < 100 THEN 5
END)
WHERE t1.id IN(100, 200, 300)
Please Suggest to get single 0 type row from multiple (0 type rows) and selected row should be just before type 1 row
Emp_tbl (id,type,company_id,created_at)
1,0,121,2015-02-19 18:05
2,0,121,2015-02-19 18:15
3,0,121,2015-02-19 18:17
4,1,121,2015-02-19 19:22
5,2,121,2015-02-19 19:25
6,0,121,2015-02-19 22:05
7,0,121,2015-02-19 22:15
8,0,121,2015-02-19 22:17
9,1,121,2015-02-19 22:22
10,2,121,2015-02-19 22:25
Expected Result
3,0,121,2015-02-19 18:17
4,1,121,2015-02-19 19:22
5,2,121,2015-02-19 19:25
8,0,121,2015-02-19 22:17
9,1,121,2015-02-19 22:22
10,2,121,2015-02-19 22:25
So what you want is the MAX(Id) of the type = 0 rows for each row that has type = 1, where the Id is less. You can join and group to get that:
select max(t0.Id) Id
from Emp_tbl t1
join Emp_tbl t0 on t0.type = 0 and t0.Id < t1.Id
where t1.type = 1
group by t1.Id
The rest is just putting it together:
select *
from Emp_tbl
where type <> 0
union all
select t.*
from Emp_tbl t
join (
select max(t0.Id) Id
from Emp_tbl t1
join Emp_tbl t0 on t0.type = 0 and t0.Id < t1.Id
where t1.type = 1
group by t1.Id
) t0 on t.Id = t0.Id
SQL Fiddle demo
I have this table where I only want to look at AB
ID CODE COUNT
102 AB 9
101 AB 8
100 AC 23 //not important!!!!
99 AB 7
98 AB 6
97 AB 5
96 AB 0
Conversed to this
ID NEWID CODE COUNT
102 102 AB 9
101 101 AB 8
99 100 AB 7
98 99 AB 6
97 98 AB 5
96 97 AB 0
Using this query:
SELECT t.ID, #NEWID := COALESCE(#NEWID - 1, t.ID) AS NEWID, t.CODE, t.COUNT
FROM
(SELECT ID, CODE, COUNT FROM some_table WHERE CODE = 'AB' ORDER BY ID DESC) t,
(SELECT #NEWID := NULL) _uv;
http://sqlfiddle.com/#!2/e0b8b/1/0
And now I want to count the difference of each consecutive NEWID.
So
Step 1: 9 - 8 = 1
Step 2: 8 - 7 = 1
Step 3: 7 - 6 = 1
Step 4: 6 - 5 = 1
Step 5: 5 - 0 = 5
I'm used to doing this with
LEFT OUTER JOIN some_table t2 ON t.ID = ( t2.ID + 1 )
And then taking the difference between t2.count and t.count,
but now when I'm using COALESCE, I cannot select this NEWID, so the code below does not work.
LEFT OUTER JOIN some_table t2 ON t.NEWID = ( t2.NEWID + 1 )
So how should I resolve this issue?
Oh, so that's why you needed sequential IDs. Well, you can use user variables for this, too, and you don't even need NEWID! Since you're doing stuff like this, you'd do well to read up on how user variables work.
SELECT
t.ID, t.CODE, t.COUNT,
#PREVCOUNT - t.COUNT DIFFERENCE,
#PREVCOUNT := t.COUNT -- Updates for the next iteration, so it
-- must come last!
FROM
(SELECT ID, CODE, COUNT FROM some_table WHERE CODE = 'AB' ORDER BY ID DESC) t,
(SELECT #PREVCOUNT := NULL) _uv;
SQL Fiddle
Try this:
SELECT
t1.ID as ID1,
t2.ID as ID2,
t1.CODE as CODE,
t1.COUNT as C1,
t2.COUNT as C2,
t2.COUNT - t1.COUNT as DIFF
FROM
some_table t1
INNER JOIN some_table t2 ON t1.ID < t2.ID AND t1.CODE = t2.CODE
WHERE
t1.CODE='AB'
AND NOT EXISTS
(SELECT * FROM some_table t3
INNER JOIN some_table t4 ON t3.ID < t4.ID and t3.CODE = t4.CODE
WHERE
t3.CODE='AB'
AND t1.ID = t3.ID
AND t4.ID < t2.ID
)
ORDER BY t1.ID
Another way will be to use LIMIT:
SELECT
t.ID1 AS ID,
t.CODE as CODE,
t.C2-t.C1 AS DIFF
FROM
(
SELECT
t1.ID as ID1,
t1.CODE as CODE,
t1.COUNT as C1,
(SELECT t.COUNT
FROM some_table t
WHERE t.ID > t1.ID AND t.CODE=t1.CODE
ORDER BY t.ID
LIMIT 1) as C2
FROM
some_table t1
WHERE
t1.CODE='AB'
ORDER BY t1.ID) t
ORDER BY t.ID1
http://sqlfiddle.com/#!2/e0b8b/24
I have below two query's SUM the values
Query1:*
SELECT SUM(price) FROM TABLE1 WHERE acc_id = '555'
Query2:
SELECT SUM(price) FROM TABLE2 WHERE account = '555' && active='1'
I try to combine this two query but give wrong sum result , for example if query1 sum is: -86500 and Query2 sum is: 76000 , RESULT must be -10500 but result shown with a number like -486000
I'm trying like this, but i'm not getting expected result.
SELECT SUM(t1.price + t2.price) AS TotalCredit
FROM TABLE1 AS t1, TABLE2 AS t2
WHERE t1.`acc_id` = '555' && t2.`Account`='555' && t2.`Active`='1'
Table image :
Due to join the number of records get duplicated and you get a higher value for sum
try this
SELECT sum(prc)
FROM (
SELECT SUM(price) prc FROM TABLE1 WHERE acc_id = '555'
union all
SELECT SUM(price) prc FROM TABLE2 WHERE account = '555' && active='1'
) a
Try this
SELECT SUM(C.TOTAL) AS TOTAL_CREDIT FROM (SELECT SUM(A.price) AS TOTAL FROM TABLE1 A WHERE A.acc_id = '555'
UNION ALL
SELECT SUM(B.price) AS TOTAL FROM TABLE2 B WHERE B.account = '555' && B.active='1') C;
try that
SELECT (SUM(t1.price) + SUM(t2.price)) AS TotalCredit
FROM TABLE1 AS t1, TABLE2 AS t2
WHERE t1.`acc_id` = '555' && t2.`Account`='555' && t2.`Active`='1'
try this
SELECT (t1.price + t2.price) AS TotalCredit
FROM TABLE1 AS t1, TABLE2 AS t2
WHERE t1.`acc_id` = '555' && t2.`Account`='555' && t2.`Active`='1'
EDIT:
here what you looking for i think
SELECT (SUM(t1.price)+SUM(t2.price) )/2 AS TotalCredit
FROM Table1 AS t1, Table2 AS t2
WHERE t1.`acc_id` = '555' && t2.`account`='555' && t2.`active`='1'
DEMO FIDDLE HERE
How about this:
SELECT SUM(a)
FROM
(SELECT SUM(price) AS a
FROM TABLE1
WHERE acc_id = '555'
UNION ALL
SELECT SUM(price) AS a
FROM TABLE2
WHERE account = '555' && active='1')
Join could be better. :) Would be even better if you could have showed us the table schema. Here is a solution based on some assumed sample data.
Sample data:
Table1:
ID PRICE
11 200
55 300
33 200
44 100
55 500
Table2:
ID PRICE ACTIVE
1 200 0
2 300 1
55 200 0
55 100 1
55 400 1
SQLFIDDLE DEMO
Query:
select sum(t.price) + x.tb2credit
from tb1 as t
inner join
(SELECT id, SUM(price) AS Tb2Credit
FROM tb2
WHERE id = 55
and `Active`=1) x
on t.id = x.id
Results:
SUM(T.PRICE) + X.TB2CREDIT
1300