I am using Mysql and I want count distinct value and then make the distinct values as the column name.
I have a table Students like this
ID Names Age
1 Tim 12
2 James 14
3 White 13
4 John 13
5 Annie 11
6 Judy 13
I want to find how many people in each age. My expected result is:
11 12 13 14
1 1 3 1
I tried the query: "Select count(age), age from Students group by age;"
It gives out:
count(age) age
1 11
1 12
3 13
1 14
How can I take a "transpose" to the table?
If you are using MySQL you will need to know age in advance:
SELECT
SUM(CASE WHEN (age='11') THEN 1 ELSE 0 END) AS 11,
SUM(CASE WHEN (age='12') THEN 1 ELSE 0 END) AS 12,
SUM(CASE WHEN (age='13') THEN 1 ELSE 0 END) AS 13,
SUM(CASE WHEN (age='14') THEN 1 ELSE 0 END) AS 14
FROM
Students
Related
I have 1 table called itemmovement : It has Item Id , Quantity In , Quantity Out , Invoice Id, Date. I need to make in one query to show how many pieces are sold and beside the sold column there will be the current on hand quantity .
itemmovement
Id itemid qtyin qtyout invid purchasereturnid date
1 1 10 2019-01-04
2 2 8 2019-01-06
3 2 2 1 2019-01-08
4 1 3 2 2019-01-12
5 2 1 2019-02-04
6 3 4 2019-03-04
7 1 1 3 2019-04-04
8 1 1 1 2019-04-14
9 3 1 2 2019-04-24
I need the query to show this result
Id itemid Sold Quantity OnHandQty
1 1 4 5
2 2 2 7
3 3 0 3
I'm Trying to use this query but not working
SELECT *
FROM
(SELECT itmv.itemid,
sum(itmv.qtyout)-sum(itmv.qtyin)
FROM itemmovement itmv
WHERE (itmv.systemdate BETWEEN '2019-01-01' AND '2019-06-01')
AND invid>0
GROUP BY itmv.itemid) AS result1,
(SELECT sum(itmv2.qtyin)-sum(itmv2.qtyout)
FROM itemmovement itmv2
WHERE itmv.itemid=itmv2.itemid
GROUP BY itmv2.itemid) AS result2
ORDER BY sum(itmv.qtyin)-sum(itmv.qtyout)
I'm getting :
Unknown column 'itmv.itemid' in 'where clause it for this syntax :
where itmv.itemid = itmv2.itemid
Here's your query.
select itemid
, sum(case when COALESCE(invid,0) > 0 then qtyout else 0 end) as Sold_Qantity
, sum(qtyin)-sum(qtyout) as OnHandQty
from itemmovement
group by itemid
I'm trying to count the number of occurences based severity level (1-5) on distinct dates. Note I have another table but severity levels are words (High, Medium and Low...not 1 to 5).
Example of DB:
DATE LEVEL COUNT
---- ----- -----
05/11/2018 3 14
05/11/2018 5 11
05/11/2018 5 11
05/12/2018 3 14
05/12/2018 2 14
05/13/2018 2 11
05/13/2018 1 12
Expected output
Date 1 2 3 4 5
--------- -- -- -- -- --
05/11/2018 0 0 14 0 22
05/12/2018 0 14 14 0 0
05/13/2018 12 11 0 0 0
Expected output 2
Level 05/11/2018 05/12/2018 05/13/2018
--------- ---------- ---------- ----------
1 0 0 12
2 0 14 11
3 14 14 0
4 0 0 0
5 22 0 0
I tried
SELECT CONCAT(DAY(`DATE`) ,MONTH(`DATE`) , YEAR(`DATE`)) AS DDMMYYYY ,
COUNT(DISTINCT LEVEL) as NumCount
FROM `myDatabase`
GROUP BY CONCAT(DAY(`DATE`),MONTH(`DATE`), YEAR(`DATE`) )
but I'm getting the number of different counts..
Any guidance would be appreciated! Thx!
You can't really do pivot tables in MySQL. However with a fixed number of columns (such as expected output #1) you can simulate them with CASE statements e.g.
select date_format(date, '%d%m%Y') as Date,
sum(case when level=1 then count else 0 end) as `1`,
sum(case when level=2 then count else 0 end) as `2`,
sum(case when level=3 then count else 0 end) as `3`,
sum(case when level=4 then count else 0 end) as `4`,
sum(case when level=5 then count else 0 end) as `5`
from table1
group by Date
Output:
Date 1 2 3 4 5
11052018 0 0 14 0 22
12052018 0 14 14 0 0
13052018 12 11 0 0 0
hi i am trying to solve this problem from 2 days please help. I have a table like below. i am trying to get crosstab display
expenditures
id name
1 exp1
2 exp2
3 exp3
4 exp4
5 exp5
stations
id name
1 station1
2 station2
3 station3
4 station4
expenses
expenditure_id station_id year month expense
1 1 2015 1 10
1 2 2015 1 20
1 3 2015 1 15
1 4 2015 1 10
1 1 2015 2 20
1 1 2015 3 30
1 1 2015 4 40
2 1 2015 1 20
2 1 2015 2 10
2 1 2015 3 20
I am trying get result like this
for year 2015
expenditure station1 station2 station3 station4
exp1 100 20 15 0
exp2 50 0 0 0
where value of station1 station2 will be the sum of month expense
This is the mysql query as your requirement, use Laravel query builder to run this query as raw query, if you donot know how to run raw query in laravel let me know, in the mean while run the query in phpmyadmin/mysql client and see whether its give you the desired output .
SELECT y.expenditure,
MAX(CASE y.station WHEN 'station1' THEN y.totalexpense END) 'station1',
MAX(CASE y.station WHEN 'station2' THEN y.totalexpense END) 'station2',
MAX(CASE y.station WHEN 'station3' THEN y.totalexpense END) 'station3',
MAX(CASE y.station WHEN 'station4' THEN y.totalexpense END) 'station4'
FROM (
SELECT exp.name AS expenditure,st.name AS station,x.totalexpense
FROM expenditures AS exp
LEFT JOIN
(SELECT expenditure_id,station_id,SUM(expense) as totalexpense
FROM expenses
WHERE year = '2015'
GROUP by expenditure_id,station_id
)
AS x ON exp.id = x.expenditure_id
LEFT JOIN stations AS st ON x.station_id = st.id
) AS y
GROUP BY y.expenditure
I assume you have only 4 stations, if stations are unknown numbers then you can use a prepared statement and create this dynamically:
I have a table (in mysql) like this:
TABLE1
Id Name Age
---------------
1 John 22
2 Mary 17
3 Peter 21
4 Agnes 34
5 Steve 14
6 Bart 26
7 Bob 32
8 Vince 18
...
What I am looking for is a SELECT statement, where I can get 4 records in a row. I mean, the result of the select statement would be:
Id1 Name1 Age1 Id2 Name2 Age2 Id3 Name3 Age3 Id4 Name4 Age4
-----------------------------------------------------------
1 John 22 2 Mary 17 3 Peter 21 4 Agnes 34
5 Steve 14 6 Bart 26 7 Bob 32 8 Vince 18
...
I guess it would be like a pivot...
Is this possible? If it is, then how can I achieve it?
I need to populate a report by showing 4 records on a row, so I would like to be able to do it from a datasource that returns this exact structure. So on first band/row there will be
rec1,rec2,rec3,rec4
then on second row:
rec5,rec6,rec7,rec8
and so on.
My first idea was to merge 4 queries that return every 5th record starting with 1,2,3,4 but I'm not exactly sure...
Can you help?
You can do this with arithmetic on the id and group by:
select (case when id % 4 = 1 then id end) as id1,
(case when id % 4 = 1 then name end) as name1,
(case when id % 4 = 1 then age end) as age1,
(case when id % 4 = 2 then id end) as id2,
(case when id % 4 = 2 then name end) as name2,
(case when id % 4 = 2 then age end) as age2,
(case when id % 4 = 3 then id end) as id3,
(case when id % 4 = 3 then name end) as name3,
(case when id % 4 = 3 then age end) as age3,
(case when id % 4 = 0 then id end) as id4,
(case when id % 4 = 0 then name end) as name4,
(case when id % 4 = 0 then age end) as age4
from t
group by floor((id - 1) / 4);
If the id doesn't increment without gaps, then you can generate one using:
from (select t.*, (#rn := #rn + 1) as seqnum
from t cross join
(select #rn := 0) params
order by id
) t
My table votes contains votes that have been made by users at different times:
id item_id position user_id created_at
1 2 0 1 11/21/2013 11:27
26 1 1 1 11/21/2013 11:27
27 3 2 1 11/21/2013 11:27
42 2 2 1 12/7/2013 2:20
41 3 1 1 12/7/2013 2:20
40 1 0 1 12/7/2013 2:20
67 2 2 1 12/13/2013 1:13
68 1 1 1 12/13/2013 1:13
69 3 0 1 12/13/2013 1:13
84 2 0 1 12/28/2013 2:29
83 3 2 1 12/28/2013 2:29
82 1 1 1 12/28/2013 2:29
113 3 0 1 1/17/2014 22:08
114 1 1 1 1/17/2014 22:08
115 2 2 1 1/17/2014 22:08
138 2 0 1 1/20/2014 16:49
139 1 1 1 1/20/2014 16:49
140 3 2 1 1/20/2014 16:49
141 1 1 11 1/20/2014 16:51
142 3 2 11 1/20/2014 16:51
143 2 0 11 1/20/2014 16:51
I need to tally the results on a monthly basis but here's the tricky part: the start/end of the month does not necessarily fall on the first day of the month. So if the votes are due on the 10th day of every month, I need a vote that was cast on the 10th to be in a different group from a vote that was cast on the 11th. Using the data above, I want to get three groups:
Group 1: 6 votes (11/21 and 12/7)
Group 2: 6 votes (12/13, 12/28)
Group 3: 9 votes (1/17, 1/20)
I've tried a lot of approaches but to no avail. This is my query right now:
select created_at, ADDDATE(DATE_FORMAT(created_at, '%Y-%m-01'),interval 10 day) as duedate,count("id") from votes where list_id = 2 group by duedate
I am getting group sizes of 3, 9, and 9, not 6, 6 and 9. Any help you can provide would be much appreciated. Thanks.
Your query is close. You just need to subtract 9 days (10 - 1) from the current day to get the month:
select created_at, date_sub(created_at, interval 9 day) as duedate,
count(id)
from votes
where list_id = 2
group by duedate;
date_format() converts a date to a string. There is no need to convert a date value to a character value for this query.
EDIT:
To group by month:
select date_format(date_sub(created_at, interval 9 day), '%Y-%m') as YYYYMM,
count(id)
from votes
where list_id = 2
group by YYYYMM;