In the below query I'm getting some odd results -- specifically, I'm getting the same counts for both categories (current year and all time) and I can't figure out why that would be. Here's my query:
SELECT eventlist.isid, eventlist.name, COUNT(currentyearcount.arid) AS currentyearcount, COUNT(allreports.arid) AS allreports
FROM eventlist
LEFT JOIN artist_reports currentyearcount ON eventlist.isid = currentyearcount.CompanyID AND currentyearcount.event_year = 2015
JOIN artist_reports allreports ON eventlist.isid = allreports.CompanyID
GROUP BY eventlist.isid
I'm getting results like this:
isid name currentyearcount allreports
1234 Name1 33 33
5678 Name2 105 105
9012 Name3 0 63
I'm not sure why Name3 would show 0 for currentyearcount when really they should all be showing 0 as there aren't any reports for the current year yet.
UPDATE: Here's the correct query thanks to Aleksandar's comments:
SELECT eventlist.isid, eventlist.name, SUM(CASE WHEN artist_reports.arid IS NOT NULL AND artist_reports.event_year = 2015 THEN 1 ELSE 0 END) AS currentyearcount, SUM(CASE WHEN artist_reports.arid IS NOT NULL THEN 1 ELSE 0 END) AS totalcount
FROM eventlist
LEFT JOIN artist_reports ON eventlist.isid = artist_reports.CompanyID
GROUP BY eventlist.isid
Related
I will preface this by saying I am still very much learning MySQL, and I am absolutely at that stage where I know just enough to be dangerous.
I have a database with data for scorekeeping for a sports league. We record wins/losses as either 1 or zero points. There is a night that has double play involved (meaning the players play twice in a single night, for 2 different formats). My data is structured like so (just a sample, I have hundreds of rows, over different formats):
ID
FID
WK
Type
HomeTeam
AwayTeam
HF1
HF2
AF1
AF2
1
44
1
PL
TM1
TM2
1
0
0
1
2
44
1
PL
TM3
TM4
0
0
1
1
3
44
2
PL
TM2
TM3
1
1
0
0
4
44
2
PL
TM4
TM1
0
1
1
0
5
44
3
PL
TM3
TM1
999
0
999
1
6
44
3
PL
Tm2
TM4
1
0
0
1
Where the 999 is used as a code number for us to know that the match hasn't yet been played, or the scoresheet hasn't been turned in to us for recordkeeping. (I use PHP to call these to a website for users to see what is going on, and am using an IF statement to convert that 999 to "TBD" on the website)
I can pull the Format 1 and Format 2 scores separately and get a listing just fine, but when I try to pull them together and get a total score, I am getting an incorrect count. I know the error lies with my WHERE Clause, but I've been banging my head trying to get it to work correctly, and I think I just need an extra set of eyes on this.
My current SQL Query is as follows:
SELECT Team,
SUM(TotalF1) AS TotalF1,
SUM(TotalF2) AS TotalF2,
SUM(TotalF1+TotalF2) AS Total
FROM ( ( SELECT HomeTeam AS Team,
HF1 AS TotalF1,
HF2 AS TotalF2
FROM tbl_teamscores
WHERE FID = 44
AND Type = 'PL'
AND HF1 != 999
AND HF2 != 999 )
UNION ALL
( SELECT AwayTeam,
AF1,
AF2
FROM tbl_teamscores
WHERE FID = 44
AND Type = 'PL'
AND AF1 != 999
AND AF2 != 999 )
) CC
GROUP BY Team
ORDER BY Total desc, Team ASC;
I am getting incorrect totals though, and I know the reason is because of those 999 designations, as the WHERE clause is skipping over ALL lines where either home or away score matches 999.
I tried separating it out to 4 separate Select Statements, and unioning them, but I just get an error when I do that. I also tried using Inner Join, but MySQL doesn't seem to like that either.
Edit to add DBFiddle with Real World Table Data and queries: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=1d4d090b08b8280e734218ba32db6d88
An example of the problem can be observed when looking at the data for Player 10. The overall total should be 13, but I am only getting 12.
Any suggestions would be very helpful.
Thanks in advance!
You can use conditional aggregation:
SELECT Team,
SUM(CASE WHEN Total8 <> 999 THEN Total8 END) AS Total8,
SUM(CASE WHEN TotalLO <> 999 THEN TotalLO END) AS TotalLO,
SUM(CASE WHEN Total8 <> 999 THEN Total8 END) + SUM(CASE WHEN TotalLO <> 999 THEN TotalLO END) AS Total
FROM (
SELECT HomeTeam AS Team, Home8PTS AS Total8, HomeLOPTS AS TotalLO FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL'
UNION ALL
SELECT AwayTeam, Away8PTS, AwayLOPTS FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL'
) CC
GROUP BY Team
ORDER BY Team ASC;
or:
SELECT Team,
SUM(NULLIF(Total8, 999)) AS Total8,
SUM(NULLIF(TotalLO, 999)) AS TotalLO,
SUM(NULLIF(Total8, 999)) + SUM(NULLIF(TotalLO, 999)) AS Total
FROM (
SELECT HomeTeam AS Team, Home8PTS AS Total8, HomeLOPTS AS TotalLO FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL'
UNION ALL
SELECT AwayTeam, Away8PTS, AwayLOPTS FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL'
) CC
GROUP BY Team
ORDER BY Team ASC;
If you get nulls in the results then you should also use COALESCE():
SELECT Team,
COALESCE(SUM(NULLIF(Total8, 999)), 0) AS Total8,
COALESCE(SUM(NULLIF(TotalLO, 999)), 0) AS TotalLO,
COALESCE(SUM(NULLIF(Total8, 999)), 0) + COALESCE(SUM(NULLIF(TotalLO, 999)), 0) AS Total
FROM (
SELECT HomeTeam AS Team, Home8PTS AS Total8, HomeLOPTS AS TotalLO FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL'
UNION ALL
SELECT AwayTeam, Away8PTS, AwayLOPTS FROM tbl_teamscores WHERE FID = 44 AND Type = 'PL'
) CC
GROUP BY Team
ORDER BY Team ASC;
See the demo.
I'm using MYSQL and I have a message table like below.
id
parent_id
sender_id
receiver_id
content
readed
sender_deleted
receiver_deleted
created
18
0
6
1
testab
0
0
0
2021-10-28 01:13:42
19
18
6
1
testcd
0
0
0
2021-10-28 01:14:55
I'm trying to combine two queries in one. Selecting and count where readed value is 0.
This query is selecting query.
SELECT * FROM message
WHERE (sender_id = 1 OR receiver_id = 1) AND (id = 18 OR parent_id = 18);
And this query is counting query.
SELECT COUNT(id) FROM message
WHERE (sender_id = 1 OR receiver_id = 1)
AND (id = 18 OR parent_id = 18) AND (readed = 0);
I'm trying to combine these two using LEFT JOIN.
SELECT a.id, a.parent_id, a.content, COUNT(b.id) AS unreaded_message
FROM message a
LEFT JOIN message c ON a.id = c.id AND (readed = 0)
GROUP BY A.ID, A.Date
ORDER BY a.id;
But I'm getting error like below.
ERROR 1054 (42S22): Unknown column 'b.id' in 'field list'
Is there way I can left join count query?
I notice these issues when testing the query:
The incorrect alias of b.id for the COUNT(). That's where the error is indicating.
The non-existing A.Date from table message. Based on your table sample, you don't have a column named as Date. Instead you have a column named created that stores date+time.
The query itself is incompatible with sql_mode=only_full_group_by. Since MySQL v5.7.5, this setting is on by default, with a very good reason of - "if the only_full_group_by mode is turned off the server is free to choose any value from each group, so unless they are the same, the values chosen are nondeterministic, which is probably not what you want (refer: "MySQL Handling of Group By" docs.
Now, if I'm not mistaken, content stores the text messages, correct? And since id=19 parent is id=18, it should be in the same row, with the total count of unread message is 2. I'm not sure if that's what you're really looking for but I'll post two queries; one is to address your current issue and another to suggest that it maybe what you're looking for.
For your current issue, you can achieve the desired result without self-join, and instead of using COUNT(), you can use SUM() with CASE expression like below:
SELECT id, parent_id, content,
SUM(CASE WHEN readed=0 THEN 1 ELSE 0 END) AS unreaded_message
FROM message
GROUP BY id, parent_id, content;
COUNT() will take every row in the query result depending on your conditions. The replacement of SUM() with CASE expression here is just telling the query to:
SUM(CASE WHEN readed=0 THEN 1 ELSE 0 END) AS unreaded_message
-- if the readed column is 0 (zero) then give it 1, else give it 0 then add them up.
The second suggestion I have is this, let's assume you have more rows in the table like this:
id
parent_id
sender_id
receiver_id
content
readed
sender_deleted
receiver_deleted
created
18
0
6
1
testab
1
0
0
2021-10-28 01:13:42
19
18
6
1
testcd
1
0
0
2021-10-28 01:14:55
20
18
6
1
testde
0
0
0
2021-10-28 01:15:05
21
0
6
1
testfg
0
0
0
2021-10-28 02:34:11
22
21
6
1
testhi
0
0
0
2021-10-28 02:44:01
With id of 18,19 both have readed=1, the query you have and the one I suggested above will return result like this:
id
parent_id
content
unreaded_message
18
0
testab
0
19
18
testcd
0
20
18
testde
1
21
0
testfg
1
22
21
testhi
1
But I have a feeling that you probably want something like this:
m_id
contents
unreaded_message
18
testde
1
21
testgftesthi
2
If that's a possibility, then you can just run this query:
SELECT CASE WHEN parent_id=0 THEN id ELSE parent_id END AS m_id,
GROUP_CONCAT(CASE WHEN readed=0
THEN content ELSE '' END
ORDER BY readed, id SEPARATOR '\r\n' ) AS contents,
SUM(CASE WHEN readed=0 THEN 1 ELSE 0 END) AS unreaded_message
FROM message
GROUP BY m_id;
Demo fiddle
You are using in the query B alias in the "COUNT" satement. You need to use A or C alias like these example:
SELECT a.id, a.parent_id, a.content, COUNT(c.id) AS unreaded_message
FROM message a
LEFT JOIN message c ON a.id = c.id AND (readed = 0)
GROUP BY A.ID, A.Date
ORDER BY a.id;
Table1: Agent Data: where agent details are stored
Agent Table
Agent_Id Name
1 Vijay
2 Rajesh
3 Satish
4 Anji
Table2: Case_transaction_details: Each step in Backend operation is stored.
Case_transaction_details
Case_Id Stage Login_Time Logout_time Agent_id Status
101 Maker 5/11/2019 10:20 10:30 2 Success
102 Maker 10:25 10:35 1 Success
103 Maker 10:40 10:50 2 Success
101 Checker 10:45 11:00 3 Success
101 Approver 11:15 11:30 2 Success
102 Checker 10:50 11:00 1 Reject
102 Maker 11:15 11:45 4 Reverify
103 Checker 11:30 11:40 2 Reject
The question is how to get Case Id which is rejected by checker but still not reverified?
SELECT Case_Id
FROM Case_transaction_detail
WHERE Status = 'Reject' and status != 'Reverify';
How to apply where clause twice on same column?
trying the above query is giving both
102
103
whereas answer should be only 103
You could use:
SELECT Case_Id
FROM Case_transaction_detail
GROUP BY Case_Id
HAVING SUM(Status = 'Reject') > 0
and SUM(status = 'Reverify') = 0 ;
I think you want aggregation:
SELECT Case_Id
FROM Case_transaction_detail
GROUP BY Case_Id
HAVING SUM(Status = 'Reject') > 0 AND
SUM(status = 'Reverify') = 0;
MySQL treats boolean conditions as numbers in a number context, with "1" for true and "0" for false. So, the first condition counts the number of rejects; the > 0 says there is at least one.
Similarly, the second condition counts the number of reverifies for each case. The = 0 says there are none.
You could do this with a simple LEFT JOIN.
Basically, you will select from the table all the rejected CaseIds, and you will left join the same table using the CaseIds selecting only their associated reverifieds.
The ones you want will be the ones where the left join relation (the associated reverifieds) is NULL.
SELECT CaseRejected.Case_Id
FROM Case_transaction_detail CaseRejected
LEFT JOIN Case_transaction_detail CaseReverified ON (CaseReverified.Case_Id = CaseRejected.Case_Id AND CaseReverified.Status = 'Reverify')
WHERE CaseRejected.Status = 'Reject'
AND CaseReverified.Case_Id IS NULL;
One way would be to test for homogeneity in the HAVING clause
SELECT Case_Id
FROM Case_transaction_detail
GROUP BY Case_Id
HAVING AVG(Status='Rejected')=1
Another method is basically a hack using GROUP_CONCAT
SELECT Case_Id
FROM Case_transaction_detail
GROUP BY Case_Id
HAVING GROUP_CONCAT(DISTINCT Status))='Rejected'
SELECT Case_Id
FROM case_transaction_details
GROUP BY Case_Id
HAVING SUM(Status = 'Reject') - SUM(status = 'Reverify') = 1
SELECT
case_id
FROM
case_transaction_details
WHERE
status = 'Reject'
AND status <> 'Reverify';
Country Value Type
AU 152 IN
AU 56 OUT
IN 85 IN
CA 74 OUT
CA 98 IN
IN 89 IN
US 124 IN
UK 856 OUT
IN 35 OUT
AU 26 IN
PS 24 OUT
CN 869 OUT
i need a query that groups the country and prints the sum of IN and OUT fields separately like
Thanks in advance
it will give you count of all indivisual country
SELECT country,
SUM(case when type = 'IN' then 1 END) AS IN,
SUM(case when type = 'OUT' then 1 END) AS OUT
FROM table_name
GROUP BY country
it will give you sum of all indivisual country's value
SELECT country,
SUM(case when type = 'IN' then value END) AS IN,
SUM(case when type = 'OUT' then value END) AS OUT
FROM table_name
GROUP BY country
I have this table in MYSQL:
Year Type Value ID
0 0 5 1
2010 1 6 1
2011 1 4 1
2012 1 5 1
2013 1 7 1
2014 1 8 1
2015 1 5 1
0 0 6 2
2009 1 7 2
2010 1 4 2
2011 1 2 2
2012 1 8 2
2013 1 8 2
2014 1 5 2
I want to select the minimum and maximum year for each person (IDs 1 and 2), but I also want to select the value associated with type 0 for each person as well. Ideally this is what the query result would look like:
ID MinYear MaxYear Type0Value
1 2010 2015 5
2 2009 2014 6
The query should look, I think, something like this...
select ID,
(min(year) where type = 1) as MinYear,
(max(year) where type = 1) as MaxYear,
(value where type = 0) as Type0Value
from table
group by ID
But this is obviously not correct SQL syntax. How do I do this?
strange table structure, but:
select
_type0.id,
_type0.value,
_type1._min,
_type1._max
from
tbl as _type0
inner join (
select
id,
min(year) as _min,
max(year) as _max
from
tbl
where
1 = type
group by
id
) as _type1 on
_type0.id = _type1.id
where
0 = _type0.type;
you should use inner join.
one half will handle the min and max, second half the type0value:
select a.minYear, a.maxYear, a.id, b.type0value from
(select min(year) as minYear, max(year) as maxYear, id from table where id = 1 group by id) as a
inner join table as b on a.id = b.id
where b.type = 0
Your pseudo-code is actually pretty close. You just need conditional aggregation:
select ID,
min(case when type = 1 then year end) as MinYear,
max(case when type = 1 then year end) as MaxYear,
max(case when type = 0 then value end) as Type0Value
from table
group by ID;
If there could be multiple rows with type = 0, you might want group_concat() instead.