Order by * where * - mysql

Sorry that my english isn't the best.
Is it possible to do a "where" in "order by".
Example :
ORDER BY
SUM(points),
SUM(points) WHERE type = 1,
SUM(goal),
SUM(goal) WHERE type = 1
So as first we sort by points.
If anyone has the same number of SUM(points), then we sort by SUM(points) where type = 1.
If anyone has the same number of SUM(points) and the same number of SUM(points) where type = 1, then we sort after SUM(goal).
If anyone has the same in all 3, then it have to sort by SUM(goal) where type = 1.

SUM(CASE WHEN type=1 THEN points ELSE 0 END)
etc.
you should of course add DESC on all order conditions, if you want the "best" first ;)
And the sqlFiddle

ORDER BY
SUM(points),
SUM(CASE WHEN type = 1 THEN points ELSE 0 END),
SUM(goal),
SUM(CASE WHEN type = 1 THEN goal ELSE 0 END)

Related

Counting the number of mention depending on sentiment SQL

Apologies if this is a duplicate of anything, I wasn't finding answers which particularly did what I wanted.
I'm trying to write a SQL query which will return the count of rows which contain a positive, negative or neutral sentiment on one of the candidates in the dataset.
Here is a screenshot for reference
Sentiment is one column but the values in it define the tweet to be positive, negative, or neutral. my goal is to have the query return something like this
if anyone could give me an example on how to do this, I'd appreciate!
try using specific COUNT() functions in your query like this.
SELECT name as `Candidate Name`,
COUNT(CASE WHEN sentiment='Negative' THEN 1 END) AS `Negative`,
COUNT(CASE WHEN sentiment='Positive' THEN 1 END) AS `Positive`,
COUNT(CASE WHEN sentiment='Neutral' THEN 1 END) AS `Neutral`,
COUNT(*) AS `Total`
FROM [table]
GROUP BY candidate
I like using IF()'s or CASE WHEN's to solve this type of thing. Pivots are sometimes time consuming to think through.
SELECT
Name as CandidateName,
SUM(IF(Sentiment = 'N', 1, 0)) as Negative,
SUM(IF(Sentiment = 'Y', 1, 0)) as Positive,
SUM(IF(Sentiment = 'N', 1, 0)) as Neutral
COUNT(*) as Total
FROM [TABLE]
GROUP BY
Name
To use t-SQL, or to just use CASE WHEN's, that same code could look like:
SELECT
Name as CandidateName,
SUM(CASE WHEN Sentiment = 'N' THEN 1 ELSE 0 END) as Negative,
SUM(CASE WHEN Sentiment = 'Y' THEN 1 ELSE 0 END) as Positive,
SUM(CASE WHEN Sentiment = 'N' THEN 1 ELSE 0 END) as Neutral
COUNT(*) as Total
FROM [TABLE]
GROUP BY
Name

How to count values with different where clauses on the same column?

I hate that I have to ask but I just cant handle it.
I have this table votes:
type=1 is an upvote, type=0 would be a downvote
I want this output:
[
{'video': 'best-of-mehrwert', 'upvote': 2, 'downvote': 0},
{...}
]
I am using medoo:
<?php
$votes = $database->query(
// 'SELECT COUNT(video) as votes, video FROM votes GROUP BY video, type'
'
SELECT video,COUNT(*) as counts
FROM votes
GROUP BY video,type;
'
)->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($votes);
which gives me
[{"video":"anlaesse","counts":"1"},{"video":"best-of-mehrwert","counts":"2"}]
How do I "add a column" like "upvotes" i.e. entries where type = 1 and the same with type = 0?
two variants:
select
video,
sum(case when type=1 then 1 else 0 end) as upvote,
sum(case when type=0 then 1 else 0 end) as downvote
from votes
group by video
and
select
video,
sum(type) as upvote,
sum(1-type) as downvote
from votes
group by video
http://www.sqlfiddle.com/#!9/c73f2a/5
I think it might be easiest to SUM up a 1 for each row where your criteria matches:
SELECT
video,
SUM(CASE type WHEN 1 THEN 1 ELSE 0 END) as upvotes,
SUM(CASE type WHEN 0 THEN 1 ELSE 0 END) as downvotes
FROM
votes
GROUP BY
video;
Note, you should omit type from the GROUP BY in order to get a single row back for each video.
You could use case expression to count only the type of votes you're interested in:
SELECT video,
COUNT(CASE type WHEN 1 THEN 1 END) as upvotes
COUNT(CASE type WHEN 0 THEN 1 END) as downvotes
FROM votes
GROUP BY video, type;

How to sum varchar column in SQL?

I am a beginner in SQL. I need to sum up the gender column.I mean how many males and how many females are there in a Table.This is what i tried.
SELECT
SUM(CASE WHEN Gender='Female' THEN Gender ELSE 'Null' END)Gender,
SUM(CASE WHEN Gender='Male' THEN Gender ELSE 'Null' END)Gender
FROM EmployeeDetails;
I am getting this error:
Msg 8117, Level 16, State 1, Line 2
Operand data type nvarchar is invalid for sum operator.
So i tried the following query:
Select length(Gender) - length(replace(Gender, ' ', '')) + 1 NumbofWords
from EmployeeDetails
Its showing as length is not a recognized builtin function.
Any help will be appreciated.
Thanks in advance.
SUM + CASE will work, but you need to sum numbers like:
SELECT
SUM(CASE WHEN Gender='Female' THEN 1 ELSE 0 END) AS [FemaleNumber],
SUM(CASE WHEN Gender='Male' THEN 1 ELSE 0 END) AS [MaleNumber]
FROM EmployeeDetails;
SQL Server 2012+
SELECT
SUM(IIF(Gender='Female', 1, 0)) AS [FemaleNumber],
SUM(IIF(Gender='Male', 1, 0)) AS [MaleNumber]
FROM EmployeeDetails;
This is a little bit of an XY solution, given that it produces rows and not columns. But this is more "database-y", and essentially what you have is a PIVOTed version of the following anyway.
You can't add words, but you can count them. So just GROUP BY your Gender column and COUNT:
select Gender, count(*)
from EmployeeDetails
group by Gender

MySQL - Conditional COUNT with GROUP BY

I'm trying to refine a query that I am currently using:
SELECT `puid`,
COUNT(DISTINCT `droid_v`) AS DROID,
COUNT(DISTINCT `sig_v`) AS sig,
SUM(NoExt) AS hits
FROM temp
GROUP BY `puid`
And I need to get it to only count droid_v where droid_V is greater than 0. Is it possible to condition the count in this way? At the moment, it is counting zero values as countable, and I can't really change the zeros to null values.
I do not need to know the count value for droid_V = 0, I only need to count it if it has a number greater than 0. That number will always be either 0, 1, 2, 3, or 4.
I have tried:
SELECT `puid`,
COUNT(DISTINCT CASE WHEN `droid_v` > 0 THEN 1 END) AS DROID,
COUNT(DISTINCT `sig_v`) AS sig,
SUM(`NoExt`) AS hits
FROM temp
GROUP BY `puid`
But this gives a binary result (either 0 or 1) not the count I am expecting.
example output =
puid DROID sig hits
No PUID 1 1 252
x-fmt/92 1 5 1008
anticipated output:
puid DROID sig hits
No PUID 1 1 252
x-fmt/92 3 5 1008
Sample data:
id;puid;droid_v;sig_v;speed;Ext;NoExt;tally
1;"No PUID";"3";"v13";"SLOW";"0";"63";"63"
2;"x-fmt/92";"3";"v13";"SLOW";"63";"0";"63"
3;"x-fmt/92";"3";"v37";"SLOW";"63";"63";"126"
4;"x-fmt/92";"3";"v45";"SLOW";"63";"63";"126"
5;"x-fmt/92";"3";"v49";"SLOW";"63";"63";"126"
6;"x-fmt/92";"3";"v50";"SLOW";"63";"63";"126"
7;"x-fmt/92";"5";"v13";"SLOW";"63";"0";"63"
8;"No PUID";"5";"v13";"SLOW";"0";"63";"63"
9;"x-fmt/92";"5";"v37";"SLOW";"63";"63";"126"
10;"x-fmt/92";"5";"v45";"SLOW";"63";"63";"126"
11;"x-fmt/92";"5";"v49";"SLOW";"63";"63";"126"
12;"x-fmt/92";"5";"v50";"SLOW";"63";"63";"126"
13;"No PUID";"6";"v13";"FAST";"0";"63";"63"
14;"x-fmt/92";"6";"v13";"SLOW";"63";"0";"63"
15;"No PUID";"6";"v13";"SLOW";"0";"63";"63"
16;"x-fmt/92";"6";"v13";"FAST";"63";"0";"63"
17;"x-fmt/92";"6";"v37";"SLOW";"63";"63";"126"
18;"x-fmt/92";"6";"v37";"FAST";"63";"63";"126"
19;"x-fmt/92";"6";"v45";"FAST";"63";"63";"126"
20;"x-fmt/92";"6";"v45";"SLOW";"63";"63";"126"
21;"x-fmt/92";"6";"v49";"FAST";"63";"63";"126"
22;"x-fmt/92";"6";"v49";"SLOW";"63";"63";"126"
23;"x-fmt/92";"6";"v50";"FAST";"63";"63";"126"
24;"x-fmt/92";"6";"v50";"SLOW";"63";"63";"126"
If droid_v can only be 0, 1, 2, 3, or 4, then COUNT(DISTINCT) will never return more than 5, since there are only five possible values. Is that what you want? If so, then try this:
SELECT puid, COUNT(DISTINCT CASE WHEN droid_v > 0 THEN droid_v ELSE 0 END) - 1 AS droid /* -1 for the case where droid_v is 0 */
, COUNT(DISTINCT sig_v) AS sig
, SUM(NoExt) AS hits
Update: Oops, sorry, the above is not quite right as there might not be a zero.
It should be:
SELECT puid, COUNT(DISTINCT CASE WHEN droid_v > 0 THEN droid_v END) AS droid
If, on the other hand, you want a count of all the rows where droid_v > 0, then I think you want this:
SELECT puid, SUM(CASE WHEN droid_v > 0 THEN 1 ELSE 0 END) AS droid
, COUNT(DISTINCT sig_v) AS sig
, SUM(NoExt) AS hits
Hope this helps.
Just use a sum
so if you want to group something check this out
select city, sum( case when gender = 'male' then 1 else 0 end ) as male,
sum( case when gender = 'female' then 1 else 0 end ) as female
from person
group by city
simple as this :D
SELECT
`puid`,
COUNT(DISTINCT CASE WHEN `droid_v` > 0 THEN `droid_v` END) AS DROID,
COUNT(DISTINCT `sig_v`) AS sig,
SUM(NoExt) AS hits
This is the simplest solution I can think of:
SELECT puid,
SUM(droid_v > 0) AS DROID,
COUNT(DISTINCT sig_v) AS sig,
SUM(`NoExt`) AS hits
FROM t
GROUP BY puid
However, it is not clear if you want to count the distinct or not. If you want to count the distinct values then:
SELECT puid,
COUNT(if(droid_v > 0, droid_v, null)) AS DROID,
COUNT(DISTINCT sig_v) AS sig,
SUM(`NoExt`) AS hits
FROM t
GROUP BY puid
add this to the query
WHERE droid_v > 0

mysql grouping a status field

I have a table
id, location, status
1, london, 1
2, london, 0
3, boston, 1
4, boston, 1
I'd like my query to generate something like this: -
location, status_1, status_0
london, 1, 1
boston, 2, 0
so far I have: -
select count(id) as freq, location from my_table
group by location order by freq desc;
I'm completely lost as to where to go from here.
That sort of transformation is better done in whatever client is issuing the query, but if you have to do it in the database, then
select location,
sum(status = 1) AS status_1,
sum(status = 0) AS status_0
from my_table
group by location
it's a bit hackish, but the 'status = 1' when status really is 1 will evaluate to a boolean true, which MySQL will politely cast to an integer '1', which then gets summed up. Same goes for when status is 0 and status = 0 evaluates to true.
So you want to count the records for each status per city?
In the query below, I group by location (like your did), and then add a sum for each state. Inside the sum is a case, that either returns 1 if the record matches the desired state, or 0 otherwise. That way, you effectively count the number of records for each state per location.
select
a.location,
sum(case when a.status = 1 then 1 else 0 end) as status_1,
sum(case when a.status = 0 then 1 else 0 end) as status_0
from
YourTable a
group by
a.location
select location,
sum(case when status = 1 then 1 else 0 end) as status_1,
sum(case when status = 0 then 1 else 0 end) as status_0,
from my_table
group by location;