SQL: Query formatting - mysql

I have a SQL query with three columns. The first is Year (categorical), the second is Site (categorical) and the last is temperature (float). The rows as unique combinations of Year X Site. For example:
Current query result
Year, Site, Temp
1, 1, x11
1, 2, x12
1, 3, x13
2, 1, x21
2, 2, x22
2, 3, x23
3, 1, x31
3, 2, x32
3, 3, x33
I would like to have each site as a different column, while keeping years as rows. For example:
Desired query result
Year, TSite1, TSite2, TSite3
1, x11, x12, x13
2, x21, x22, x23
3, x31, x23, x33
Any ideas on how to do a query that results in this format? I would not mind using a temporary table or a view to store the information.
Thanks in advance.

SELECT Year,MIN(CASE WHEN Site=1 THEN Temp ELSE 0 END) as Tsite1,
MIN(CASE WHEN Site=2 THEN Temp ELSE 0 END) as Tsite2,
MIN(CASE WHEN Site=3 THEN Temp ELSE 0 END) as Tsite3 FROM table GROUP BY Year

A pivot query is one approach (as mentioned in the comments) If you just want a comma-delimited list of sites, then you can do that with group_concat().
select year, group_concat(temp separator ', ' order by site) as temps
from t
group by year;
I realize this may not be exactly what you want -- you lose the type information for temp by converting it to a string for example. But then again, it may be what you need if you just want to see the temps or export them to another tool.

Related

MySQL query to show multiple values in one field from many-many tables

I have tables:
TRUCKING_JOB: trucking_id, driver
Data:
1, Jonah
2, Jim
3, Ron
MACHINES: machine_id, machine_name
Data:
1, Machine1
2, Machine2
3, Machine3
TRUCKING_MACHINE: trucking_id, machine_id
Data:
1, 1
1, 2
1, 3
2, 1
2, 2
3, 1
3, 3
My question is, how can I get this query result using a single query string
trucking_id, driver, machine_names
For example:
1, Jonah, (Machine1, Machine2, Machine3)
The third column combine all machines.
Thanks for any help and advice..
What you are looking for is a 'GROUP BY' which has some special functions to do exactly what you need such as 'GROUP_CONCAT'.
SELECT
TRUCKING_JOB.trucking_id,
TRUCKING_JOB.driver,
GROUP_CONCAT(MACHINES.machine_name SEPARATOR ','
FROM TRUCKING_MACHINE
JOIN TRUCKING_JOB ON TRUCKING_MACHINE.trucking_id = TRUCKING_JOB.trucking_id
JOIN MACHINES ON TRUCKING_MACHINE.machine_id = MACHINES.machine_id
GROUP BY TRUCKING_JOB.trucking_id
You can add any WHERE clause statements before the GROUP BY.
Thank you.. Here is my final query string based on #Eugene recommended query.
SELECT
TRUCKING_JOB.trucking_id AS TRUCKING_ID,
TRUCKING_JOB.driver AS DRIVER,
GROUP_CONCAT(MACHINES.machine_name SEPARATOR ', ') AS MACHINES
FROM TRUCKING_MACHINE
JOIN TRUCKING_JOB ON TRUCKING_MACHINE.trucking_id = TRUCKING_JOB.trucking_id
JOIN MACHINES ON TRUCKING_MACHINE.machine_id = MACHINES.machine_id
GROUP BY TRUCKING_JOB.trucking_id

SSRS - avg function by subtotals

I have details, subtotals and totals.
When I put avg function in totals line I have avg of every row.
I need avg of subtotals
How to do it?
week1
day1..... 2
day3..... 3
day4..... 4
day6..... 2
total.... 11 sum()
week2
day1..... 3
day2..... 2
total..... 5 sum()
Total
........... 16 sum() OK
............ 2,66666 avg() here should be (11+5)/2 =8
Result after implementing solution
I created a dataset to replicate your sample data as follows:
DECLARE #t TABLE (week int, day int, amount int)
INSERT INTO #t VALUES
(1, 1, 2),
(1, 3, 3),
(1, 4, 4),
(1, 6, 2),
(2, 1, 3),
(2, 2, 2)
SELECT * FROM #t
I then built a simple tablix as you had done (more or less)
I included the incorrect results you had for illustration and then added a new expression to calculate this correctly.
The result looks like this
You can ignore the other datasets, this is just a report I use for testing. Only dataset3 is used here.
The expression used was this
=Sum(Fields!amount.Value) / CountDistinct(Fields!week.Value)
You'll just need to edit this to match your field names. It basically just sums all the detail amounts then divides by the number of distinct weeks in the dataset.

Sorting in MySQL in a specific manner in one column

So I have a data where one of the column (section) contains the following:
A1LB
A1LC
A1RC
A2LB
A2LC
A2RC
B1LB
B1LC
but I want the data to look like this:
A1LC
A1LB
A1RC
A2LC
A2LB
A2RC
B1LC
B1LB
I have tried "ORDER BY CASE WHEN section like %LC" THEN 1 else 2 END"
but it comes out with all of the LCs on top
A1LC
A2LC
B1LC
B2LC
A1LB
A1RC
A2LB
A2RC
B1LB
B1RC
how can I do so without having all of the LC's on top but in the order I want it to be?
Looks like:
ORDER BY substring(section, 1, 3), substring(section, 4, 1) desc
I think you need to make a table mapping {LC -> 1, LB -> 2, RC -> 3}. You can try something like this:
CREATE TABLE map (ky VARCHAR(2), ord TINYINT, PRIMARY KEY(ky,ord))
INSERT INTO map VALUES ('LC', 1), ('LB', 2), ('RC', 3)
SELECT col
FROM table
JOIN map ON RIGHT(col, 2) = map.ky
ORDER BY LEFT(col, 2) ASC, map.ord DESC
You can do the sorting like this
Sort by the first 2 characters
Then list records having the last 2 characters of LC
Then sort by the last 2 characters in general
ORDER BY substring(section, 1, 2),
substring(section, 3, 2) 'LC',
substring(section, 3, 2)

How do I create a query that caters for two different groups of data and produces a result that is dependent on the first set in MySQL?

I'm trying to count all instances where a group of data has one or more fail.
I'm also Finding it very difficult to build this question so I'm hoping that showing an example will do the trick in explaining what I'm trying to achieve.
Sample data:
INSERT INTO test.answers (id, result_id, fail_all, fail_group) VALUES
(1,1,0,1), (2,1,0,1), (3,1,0,1), (4,1,0,0),
(5,2,1,0), (6,2,0,0), (7,2,1,0), (8,2,1,0), (9,2,1,0),
(10,3,0,1), (11,3,1,1), (12,3,0,1), (13,3,0,1), (14,3,0,1),
(15,4,0,0), (16,4,0,0), (17,4,0,1), (18,4,0,1), (19,4,0,0), (20,4,0,1),
(21,5,1,0), (22,5,0,1), (23,5,1,1), (24,5,0,1), (25,5,1,0), (26,5,0,1);
INSERT INTO test.results (id,team_id) VALUES
(1,1), (2,1), (3,1), (4,2), (5,2);
I then run the following query:
SELECT
COUNT(IF(a.fail_all = 1,1,NULL)) AS count_fail_all,
COUNT(IF(a.fail_group = 1,1,NULL)) AS count_fail_group,
a.result_id
FROM test.answers AS a
GROUP BY a.result_id
Result:
count_fail_all, count_fail_group, result_id
0, 3, 1
4, 0, 2
1, 5, 3
0, 3, 4
3, 4, 5
I need to create a query that groups by team_id and counts how many fails there are per result. If a result has more than one fail, then that overall result is a fail. thereby if the count of results in the above query is 3 (example: first result) then it should only be counted as one. The fail_group can be ignored for now as I believe that the same solution for fail_all will work for fail_group.
The result I hope for is:
team_id, amount_of_fails, amount_of_fails_per_group
1, 2, 2
2, 1, 2
I hope someone might be able to help me create the query that I need? I'm not even sure how to start.
Let me know if there is anything that I can do to adjust the query as I know it's not very well asked?
Thanks!
If you want that output. Maybe something like this:
SELECT
r.team_id,
SUM(IF(a.fail_all = 1,1,0)) AS amount_fail_all,
SUM(IF(a.fail_group = 1,1,0)) AS amount_fail_group
FROM answers AS a
JOIN results AS r on r.id=a.result_id
GROUP BY r.team_id
This will get you this output:
team_id amount_fail_all amount_fail_group
1 2 2
2 1 2

Adding attributes to an row count

I have the following table:
OrderHasItem
OrderTable_idOrder
Item_idItem
quantity
SELECT Item_idItem, COUNT(Item_idItem)+quantity
FROM OrderHasItem
GROUP BY Item_idItem
I want to count how many of each item, but also take into account the quantity of each entry.
The problem is when I tried it with this data I got really strange results:
Data:
OrderTable_idOrder, Item_idItem, quantity
1, 1, 1
2, 1, 2
34, 4, 2
43, 4, 1
77, 2, 1
Result:
Item_idItem, COUNT(Item_idItem)+quantity
1, 3
2, 2
4, 4
I don't really understand how it got what it gave me so I'm not quite sure how to proceed. Thank you for the help.
Here is the target Data:
Item_idItem, quantity
1, 3
4, 3
2, 1
SELECT Item_idItem, COUNT(Item_idItem), COUNT(Item_idItem)+SUM(quantity)
FROM OrderHasItem
GROUP BY Item_idItem
I think it should work, if sum of quantity and number of items is required.
Or
SELECT Item_idItem, SUM(quantity)
FROM OrderHasItem
GROUP BY Item_idItem
if only sum of quantity is required.
Because quantity is not part of the GROUP BY clause it can not be selected reliably. So MySQL is returning more or less arbitrary data.
Zohaib has a query that you should use. I wanted to provide the explanation.