Combine two MySQL queries to one - mysql

Is it possible to combine these two queries into one query?
SELECT sum(amount) as credit FROM statement WHERE userId= '33003' AND debitOrCredit = '1' AND actionDate <= '2012-10-17';
SELECT sum(amount) as debit FROM statement WHERE userId= '33003' AND debitOrCredit = '0' AND actionDate <= '2012-10-17';
so I get the result:
| credit | debit |
| 90 | 60 |

You could use CASE within your SUM:
SELECT sum(CASE WHEN debitOrCredit = '1' THEN amount ELSE 0 END) as credit,
sum(CASE WHEN debitOrCredit = '0' THEN amount ELSE 0 END) as debit
FROM statement WHERE userId= '33003' AND actionDate <= '2012-10-17';

use CASE in your SELECT clause
SELECT sum(CASE WHEN debitOrCredit = '1' THEN amount ELSE 0 END) as credit,
sum(CASE WHEN debitOrCredit = '0' THEN amount ELSE 0 END) as debit
FROM statement
WHERE userId= '33003' AND
actionDate <= '2012-10-17';

Use like this.
SELECT sum(a.amount) as credit,sum(b.amount) as debit FROM statement a left join statement b
on a.userId=b.userId
WHERE a.userId= '33003' AND a.debitOrCredit = '1' AND b.debitOrCredit = '0' AND a.actionDate <= '2012-10-17' AND b.actionDate <= '2012-10-17' ;
-- Mark answered if this answer answers your question...

Thank you for your help.
This is how I used it in Zend framework:
$sql = $this->_dba->select()
->from('statement', array(
"credit" => "sum(CASE WHEN debitOrCredit = '1' THEN amount ELSE 0 END)",
"debit" => "sum(CASE WHEN debitOrCredit = '0' THEN amount ELSE 0 END)"))
->where('userId = ?', $userId)
->where('actionDate <= ?', $date);
try
{
$result = $this->db->fetchRow($sql);
//process result here
}
catch (Exception $e)
{
throw new Exception("Error on ...... ");
}

Try this
SELECT sum(case when debitOrCredit = '1' then amount else 0 end) as credit, sum(case when debitOrCredit = '2' then amount else 0 end) as debit FROM statement WHERE userId= '33003' AND actionDate <= '2012-10-17'

Related

Count each day with SQL query

I want to display a table with SQL query like this:
I have run my query:
select
tb_r_orderdata.finishtime as date ,
count(*)sum all,
sum(when status = 'SUCCESS' and issync = '1' then 1 else 0 end) sumpaid,
sum(when status = 'SUCCESS' and issync in ('3', '4') then 1 else 0 end) sumfail,
sum(when status = 'CLOSED' then 1 else 0 end) sumclose,
sum(when status = 'Null' then 1 else 0 end) sumunflag
from
tb_r_orderdata;
But when I execute it, the result is different than what I expected. The result is like this:
Thank you for any help
You are missing the GROUP BY and the CASE:
select tb_r_orderdata.finishtime as date ,
COUNT(*) as sumall,
SUM(CASE WHEN status='SUCCESS' AND issync='1' then 1 ELSE 0 END) as sumpaid,
SUM(CASE WHEN status='SUCCESS' AND issync in ('3','4') then 1 ELSE 0 END) as sumfail,
SUM(CASE WHEN status='CLOSED' then 1 ELSE 0 END) as sumclose,
SUM(CASE WHEN status is null then 1 ELSE 0 END) as sumunflag
from tb_r_orderdata
group by tb_r_orderdata.finishtime ;
MySQL treats booleans as integers in a numeric context, with "1" for true and "0" for false. You can simplify your query to:
select o.finishtime as date ,
COUNT(*) as sumall,
SUM(status = 'SUCCESS' AND issync = '1') as sumpaid,
SUM(status = 'SUCCESS' AND issync in ('3', '4')) as sumfail,
SUM(status = 'CLOSED') as sumclose,
SUM(status is null) as sumunflag
from tb_r_orderdata o
where tb_r_orderdata.finishtime is not NULL
group by o.finishtime ;
This also removes NULL finish times.
Explanation in comment for Gordon Linoff
i have try your answer but there is record NULL in the top of table, i dont know why, can you explain it
with little bit change from Gordon Linoff answer
select tb_r_orderdata.finishtime as date ,
SUM(CASE WHEN status='SUCCESS' AND issync='1' then 1 ELSE 0 END) as sumpaid,
SUM(CASE WHEN status='SUCCESS' AND issync in ('3','4') then 1 ELSE 0 END) as sumfail,
SUM(CASE WHEN status='CLOSED' then 1 ELSE 0 END) as sumclose,
SUM(CASE WHEN status='NULL' then 1 ELSE 0 END) as sumunflag
from tb_r_orderdata
group by tb_r_orderdata.finishtime

mySQL Sum in the sum column

SELECT tbl_trans.trans_username,
Sum(Case When tbl_trans.trans_type <> 'REWARD' AND tbl_trans.trans_winlose <> 'QB' then
trans_winloseamount Else 0 End) BETHOST,
Sum(Case When tbl_trans.trans_winlose = 'QB' then
trans_winloseamount Else 0 End) QB,
Sum(Case When tbl_trans.trans_type = 'REWARD' then
trans_winloseamount Else 0 End) reward ,
Sum(sum(BETHOST)+sum(QB)+sum(reward)) totalsum
FROM tbl_trans
GROUP BY trans_username
i need to totalsum of BETHOST,QB and reward
how to sum of this Sum(sum(BETHOST)+sum(QB)+sum(reward)) totalsum
pls try this
sum(SELECT(BETHOST))+sum(SELECT(QB))+sum(SELECT(reward)) AS totalsum

Outer right join doesn't work in NHibernate

So I'm having two tables:
Table 1:
Item
id : int
title : varchar
comments : varchar
Table 2:
Rating
id : int
isUpvote : bit
date : datetime
item_id : int
One Item can have several ratings. IsUpvote states whether a Rating is a like or dislike.
I'm using NHibernate to ORM to my MySQL-database.
Want I want to make a kind of trending list of items to show which items have had to most likes in the past time (so from dateTime X to now).
The MySQL code looks like this:
select p.id, sum(case when r.isUpvote = b'1' then 1 else 0 END) - sum(case when r.isUpvote=b'0' then 1 else 0 END) as score
from rating as r
right join item as p
on p.id = r.item_id
group by p.id
order by score desc
limit 7;
This results in:
Id - Score
1 - 2
2 - 1
3 - 0
4 - 0
5 - 0
6 - 0
7 - 0
So I want to do this in NHibernate. I tried but HQL and QueryOver but I just can't figure it out. What I tried is:
GetTrendingItems(int nrOfTrendingItems, DateTime fromDate) {
var trendingItems = Session
.CreateQuery(#"select p, sum(case when r.IsUpvote = 1 then 1 else 0 END) - sum(case when r.IsUpvote=0 then 1 else 0 END) as score
from Item as p, Rating as r
where p.Id = r.Point.Id
group by p.Id
order by sum(case when r.IsUpvote = 1 then 1 else 0 END) - sum(case when r.IsUpvote=0 then 1 else 0 END) desc")
.SetMaxResults(nrOfClimbers)
.List();
}
and I tried:
GetTrendingItems(int nrOfTrendingItems, DateTime fromDate) {
DBRating dbRatingAlias = null;
var iets = Session.QueryOver<DBRating>(() => dbRatingAlias)
.Where(r => r.Date > fromDate)
.OrderBy(Projections.Conditional(
Restrictions.Where(() => dbRatingAlias.IsUpvote),
Projections.Constant(1),
Projections.Constant(-1))).Desc
.Right.JoinQueryOver<DBPoints>(r => r.Point)
.Take(nrOfClimbers)
.List();
}
I'm kinda losing hope here. Can someone help me?
Update:
The HQL generates this SQL:
select
dbpoints0_.id as col_0_0_,
sum(case
when dbrating1_.isUpvote=1 then 1
else 0
end)-sum(case
when dbrating1_.isUpvote=0 then 1
else 0
end) as col_1_0_,
dbpoints0_.id as id3_,
dbpoints0_.active as active3_,
dbpoints0_.title as title3_,
dbpoints0_.comments as comments3_,
dbpoints0_.score as score3_
from
points dbpoints0_,
Rating dbrating1_
where
dbpoints0_.id=dbrating1_.points_id
group by
dbpoints0_.id
order by
sum(case
when dbrating1_.isUpvote=1 then 1
else 0
end)-sum(case
when dbrating1_.isUpvote=0 then 1
else 0
end) desc limit ?p0;
?p0 = 10 [Type: Int32 (0)]
and the Fluent generates this SQL:
SELECT
this_.id as id6_0_,
this_.owners_id as owners2_6_0_,
this_.points_id as points3_6_0_,
this_.isUpvote as isUpvote6_0_,
this_.date as date6_0_
FROM
Rating this_
WHERE
this_.date > ?p0
ORDER BY
(case
when this_.isUpvote = ?p1 then ?p2
else ?p3
end) desc limit ?p4;
?p0 = 25-5-2015 22:39:49 [Type: DateTime (0)],
?p1 = True [Type: Boolean (0)],
?p2 = 1 [Type: Int32 (0)],
?p3 = -1 [Type: Int32 (0)],
?p4 = 10 [Type: Int32 (0)]
I made a stored procedure in de MySQL database
DELIMITER //
create procedure getTrending
(IN $getClimbers bool,
IN $fromDate DateTime,
IN $nrOfTrending int)
Begin
if ($getClimbers) then
select p.id, p.active, p.title, p.comments,
sum(case when r.isUpvote = b'1' and r.date > $fromDate then 1 else 0 END) - sum(case when r.isUpvote=b'0' and r.date > $fromDate then 1 else 0 END) as score
from rating as r
right join points as p
on p.id = r.points_id
group by p.id
order by sum(case when r.isUpvote = b'1' and r.date > $fromDate then 1 else 0 END) - sum(case when r.isUpvote=b'0' and r.date > $fromDate then 1 else 0 END) desc
limit $nrOfTrending;
else
select p.id, p.active, p.title, p.comments,
sum(case when r.isUpvote = b'1' and r.date > $fromDate then 1 else 0 END) - sum(case when r.isUpvote=b'0' and r.date > $fromDate then 1 else 0 END) as score
from rating as r
right join points as p
on p.id = r.points_id
group by p.id
order by sum(case when r.isUpvote = b'1' and r.date > $fromDate then 1 else 0 END) - sum(case when r.isUpvote=b'0' and r.date > $fromDate then 1 else 0 END) asc
limit $nrOfTrending;
end if;
end //
DELIMITER ;
and then called it from my C#-code with:
public virtual List<DBPoints> GetClimbers(int nrOfClimbers, DateTime fromDate)
{
OpenSession();
var query = Session.GetNamedQuery("getTrending");
query.SetBoolean("getClimbers", true);
query.SetDateTime("fromDate", fromDate);
query.SetInt32("nrOfTrending", nrOfClimbers);
var pointList = query.List<DBPoints>();
CloseSession();
return pointList.ToList();
}
For Nhibernate there needs to be made a mapping like this:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="TechDash.Business"
namespace="TechDash.Business.Models.Database">
<sql-query name="getTrending">
<return class="DBPoints" />
call getTrending(:getClimbers, :fromDate, :nrOfTrending)
Since the names of my columns that are returned are the same as those that are returned when I'm retrieving a Points-object, I don't have to make a new C#-object nor the mapping belonging to that C#-object.

SQL query - How to exclude WHERE for specific field

See the SQL query below, it work fine. It calculate the number of Yes, NOT, Other and the number of matching mobile number [Sales field] (D.MobileNo = S.mobile)
SELECT D.Username,
SUM(CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN D.type = 'Not' THEN 1 ELSE 0 END) as Not,
SUM(CASE WHEN D.type = '' THEN 1 ELSE 0 END) as Other,
SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales,
COUNT(*) as TOTAL
FROM dairy as D
LEFT JOIN (SELECT DISTINCT mobile FROM sales) as S on D.MobileNo = S.mobile
WHERE source = 'Network'
AND UNIX_TIMESTAMP(CheckDate) >= 1309474800
AND UNIX_TIMESTAMP(CheckDate) <= 1311894000
GROUP BY D.Username
ORDER BY TOTAL DESC
I want to exclude WHERE for the Sales field - it should not be part from CheckDate. Meaning it should check any record in the dairy table without CheckDate for the Sales field.
How can that be done?
If you really want those results in only one query, this might do the trick.
SELECT D.Username,
SUM(CASE WHEN D.type = 'Yes' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN D.type = 'Not' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) as Not,
SUM(CASE WHEN D.type = '' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) as Other,
SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales,
COUNT(*) as TOTAL,
SUM(CASE WHEN UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) AS TOTALINCHECKDATE
FROM dairy as D
LEFT JOIN (SELECT DISTINCT mobile FROM sales) as S on D.MobileNo = S.mobile
WHERE source = 'Network'
GROUP BY D.Username
ORDER BY TOTAL DESC
Note that "TOTAL" will count all rows (including those who where not within your CheckDate range), TOTALINCHECKDATE return the same value as in your previous query.
Obviously, this can still be optimized.
Assuming username exists also in SALES table
SELECT Username,SUM(Yes) As Yes, SUM(`Not`) As `Not`
, SUM(Other) As Other, SUM(sales) Sales, SUM(total)
FROM (
-- get diary data
SELECT username,mobileNo As mobile,
CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END as Yes,
CASE WHEN D.type = 'Not' THEN 1 ELSE 0 END as `Not`,
CASE WHEN D.type = '' THEN 1 ELSE 0 END as Other,
0 As sales, 1 as total
FROM dairy as D
WHERE source = 'Network'
AND UNIX_TIMESTAMP(CheckDate) >= 1309474800
AND UNIX_TIMESTAMP(CheckDate) <= 1311894000
UNION ALL
-- get all sales
SELECT DISTINCT username,mobile, 0 as Yes, 0 as `Not`, 0 As Other, 1 As sales, 0 As total
FROM sales
WHERE UNIX_TIMESTAMP(CheckDate) >= 1309474800
AND UNIX_TIMESTAMP(CheckDate) <= 1311894000
) AS a
GROUP BY Username
Also try your original query with date addition
SELECT D.Username,
SUM(CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN D.type = 'Not' THEN 1 ELSE 0 END) as Not,
SUM(CASE WHEN D.type = '' THEN 1 ELSE 0 END) as Other,
SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales,
COUNT(*) as TOTAL
FROM dairy as D
LEFT JOIN (SELECT DISTINCT mobile FROM sales WHERE UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 ) as S on D.MobileNo = S.mobile
WHERE source = 'Network'
AND UNIX_TIMESTAMP(CheckDate) >= 1309474800
AND UNIX_TIMESTAMP(CheckDate) <= 1311894000
GROUP BY D.Username
ORDER BY TOTAL DESC

Getting total value from each field?

How do I get the Total value of Yes, No, Other fields of each username?
I like to add Total field.
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE NULL END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE NULL END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE NULL END) as Other
//How to get total of Yes/No/Other
FROM table
WHERE source = 'CompanyName' ";
Also the highest Total goes at the top order.
use 0 instead of NULL, add the missing group by and use COUNT(*) to get the total of each group and order the result:
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE 0 END) as Other,
COUNT(*) as TOTAL
FROM table
WHERE source = 'CompanyName'
group by Username
order by TOTAL desc;
This assumes that type can only be 'Yes', 'No' or ''.
Use a sub query to sum up your results and add a sort:
select yes, no, other, yes + no + other as Total
from (
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE 0 END) as Other
FROM table
WHERE source = 'CompanyName'
)
order by (yes + no + other) desc
Don't use SUM(null), the SUM of (1,1,1,null) = null, not 3.
SELECT s.*, s.yes+s.no+s.other as all FROM (
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE 0 END) as Other
FROM table
WHERE source = 'CompanyName'
GROUP BY Username
) s
ORDER BY all DESC