getting data in single query - mysql

Say I have the following:
id bill vote
1 x 1
2 y 1
3 y 0
4 z 1
5 x 1
What I want the query to return is:
bill vote(1) vote(0)
x 2 0
y 1 1
z 1 0
vote(1) is count of data (1), same applies to vote(0)

select bill, sum(vote) as vote_1, sum(1-vote) as vote_0
from tablename
group by bill
The first sum is used to sum all 1's. The second one to sum all 0's (1-1 = 0, 1 - 0 = 1!)

Related

How to use count in sql based on a IF condition

From this table
groupId
flag
flagValue
1
0
500
2
0
100
1
1
10
2
1
50
3
0
100
1
1
200
3
1
1000
2
1
50
I need this result
groupId
flag1
flag0
valFlag1
valFlag0
totalFlags
1
2
1
210
500
3
2
2
1
100
100
3
3
1
1
1000
100
2
where
flag1 is number of times flag is 1 for a particular group
flag0 is number of times flag is 0 for a particular group
valFlag1 is sum of flagVal when flag is 1
valFlag0 is sum of flagVal when flag is 0
totalFlags is sum of total flags associated with a group
I am stuck as to how to actually count values based on an IF condition.
Anyhelp is appreciated. Thanks.
I have used a table named group_table with your values
Try using this:
SELECT
g.`groupId`,
SUM(g.`flag`=1 ) AS flag1,
SUM(g.`flag`=0) AS flag0,
SUM(CASE WHEN g.`flag`=1 THEN g.`flagValue` ELSE 0 END) AS valFalg1,
SUM(CASE WHEN g.`flag`=0 THEN g.`flagValue` ELSE 0 END) AS valFalg0,
COUNT(*) AS totalFlags
FROM
`group_table` g
GROUP BY g.`groupId`
If you have to use the IF,
SELECT
g.`groupId`,
IF(g.`flag`=1,1,0 ) AS flag1,
IF(g.`flag`=0,1,0) AS flag0,
SUM(IF(g.`flag`=1,g.`flagValue`,0 )) AS valFalg1,
SUM(IF(g.`flag`=0,g.`flagValue`,0 )) AS valFalg0,
COUNT(*) AS totalFlags
FROM
`group_table` g
GROUP BY g.`groupId`, flag1, flag0
They'll produce the same result

Query for one column from database, but display two column for difference condition in table view

Here are my database "Stock", and "Quan":
item model Quantity
-----------------------------
A 2 3
A 3 4
B 3 1
C 3 1
D 2 1
E 2 1
F 3 2
G 2 2
Current code
Select stock.item, stock.model, stock.Quantity as model_2
FROM stock
WHERE stock.item ='2'
CURRENT display:
item model_2
--------------------
A 3
D 1
E 1
G 2
Do any way to display one more column with condition:
WHERE stock.item ='3'
So that I can display as below table?
item model_2 model_3
----------------------------
A 2 4
B 0 1
C 0 1
D 1 0
E 1 0
F 0 2
G 2 0
Thanks!!!!!!!!!!!!
Use the modulus operator along with a CASE expression:
SELECT
item,
CASE WHEN model % 2 = 0 THEN model ELSE 0 END AS even,
CASE WHEN model % 2 = 1 THEN model ELSE 0 END AS odd
FROM abc;

Generate a counter with a condition is met

I want to generate a counter with a condition. By id i want to generate a counter that start from 1 and whenever column changer change from x to y or y to x add 1 to the counter created.
id changer
1 x
1 x
1 y
1 x
1 y
2 y
2 x
2 y
3 x
3 y
3 x
3 y
3 y
Expected result is :
id changer counter
1 x 1
1 x 1
1 y 2
1 x 3
1 y 4
2 y 1
2 x 2
2 y 3
3 x 1
3 y 2
3 x 3
3 y 4
3 y 4
Interestingly, if you only need the maximum value, this makes things much simpler as you only need to create a counter for the rows where a change occured, and then get the max value:
WITH tCountAtChange as
(SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY date_time) + 1 as aCounter
FROM
(SELECT UniqueNbr, date_time, id
,CASE WHEN LAG(changer) OVER (PARTITION BY id ORDER BY date_time) <> changer THEN 'YES' ELSE 'NO' END as ChangeFlag
FROM MyTable) a
WHERE ChangeFlag = 'YES')
SELECT MyTable.id, COALESCE(MAX(aCounter), 1) as MaxCounter
FROM MyTable
LEFT JOIN tCountAtChange
ON MyTable.UniqueNbr = tCountAtChange.UniqueNbr
GROUP BY MyTable.id
Result :
id MaxCounter
1 4
2 3
3 4
You will need a date_time field or some sort field for the ORDER BY clauses, and a UniqueNbr (Unique ID) that you can use for the join, or you could always create one in an other cte with a ROW_NUMBER function.

MySQL -- Select the minimum value of a column after selecting the minimum value of another column, and be in a specific range

I got following table(tablea):
x y z
--------------------
3 0 2
0 0 3
0 3 2
0 0 1
0 0 4
i want to select all values in a specific row. The row has to fulfill specific requirements in that order (sorted by priority)
z has to be in a specific range (between 2 and 4)
x as low as possible
y as low as possible
z as low as possible
I got following code which fulfills requirement 1, 2 and 4:
Select x, MIN(z) AS z
FROM tablea
WHERE x = (SELECT MIN(x) FROM tablea where z between 2 AND 4)
and z between 2 AND 4;
I would also need requirement 3, what do i need to add in my code for that (or alternatively, completely different code)?
The result in my example should be x=0 y=0 z=3.
Edit: Second example
x y z
--------------------
3 0 2
1 0 3
0 3 2
0 0 1
0 2 4
Here x=0 y=2 z=4 should be selected.
Use order by and limit:
select t.*
from t
where z between 2 and 4
order by x, y, z
limit 1;
This chooses the lowest value of x, y, z in order (lowest x, then lowest y if there are ties, then lowest z if there are ties). If you have some other definition, you can include that. For instance, for the lowest sum:
select t.*
from t
where z between 2 and 4
order by x + y + z
limit 1;
You can use derived tables to get the min values of x and y. Then join the results to the original table and select the min value of z.
SQL Fiddle
select t.x, t.y, min(t.z) as z
from tablename t
join (select min(x) as minx from tablename where z between 2 and 4) mx
on t.x = mx.minx
join (select min(y) as miny from tablename where z between 2 and 4) my
on t.y = my.miny
where t.z between 2 and 4
group by t.x,t.y

SUM a column when another column has equal values

Let's suppose I have this MySQL table:
id place_id area_mq n
-- -------- ------- --
1 1 50 1
2 2 90 1
3 2 20 1
4 3 10 1
5 3 10 2
6 3 10 3
7 4 20 1
8 4 20 2
9 5 15 1
10 5 25 1
id is the primary key, place_id stands for an area id, area_mq is the surface area of the place in mq.
What I have to do is find a compact query to calculate the sum of area_mq with these rules:
if n is equal for the same place_id, then count every area_mq (f.ex for place_id=2, I count 90 and 20 in the sum)
if n is different for the same place_id, then count area_mq only once (possible to do because for these kind of "places" the value will be the same; f.ex. place_id=4, there are two 20's, i sum only 20 and not 40).
In this example, my correct total would be: 50 + (90 + 20) + 10 + 20 + (15 + 25).
Can I accomplish this with a query (no code or procedures)? If requirements for n were reversed, it would be simple with a GROUP BY and a subquery... but with these conditions, I'm stuck.
select place_id, sum(area_sq)/count(distinct n)
from your_table
group by place_id;
Tested here
From what I see in your pattern all with n = 1 is added?
SELECT SUM((n = 1) * area_mq) AS total
FROM table_name
I do a validation that either returns 1 or 0, and then I multiply it with the column value.
I think you could use something like this. Take the sum and the count of n, and also the min and max (maybe overkill); use that to figure out if all values of n are the same. Along these lines:
SELECT
CASE WHEN sm/cnt = mn AND sm/cnt = mx THEN sum_area
ELSE area/cnt END
AS sum_area
FROM (
SELECT COUNT(n) cnt, SUM(n) sm, MIN(n) mn, MAX(n) mx, SUM(area_mq) sum_area
GROUP BY place_id
) a
So, say n has values of 2 and 2 => sm/cnt = mn (4/2 = 2) and mx. If it has values of 2 and 1 => sm/cnt != mn (3/2 != 1).