I have a table with related data across multiple rows that I need to query as one row.
string_value | def_id | location | model | asset_num | exp_date |
-------------+--------+----------+-------+-----------+------------+
null | 16 | A | CR35 | 1 | 2015-02-01 |
SWIT: C | 25 | A | CR35 | 1 | null |
null | 16 | B | CR85 | 2 | 2015-07-28 |
SWIT: D | 25 | B | CR85 | 2 | null |
What I am looking to end up with is a query that gives me results:
string_value | location | model | asset_num | exp_date |
-------------+----------+-------+-----------+------------+
SWIT: C | A | CR35 | 1 | 2015-02-01 |
SWIT: D | B | CR85 | 2 | 2015-07-28 |
Using aggregate function MAX() with GROUP BY return your expected result:
SELECT MAX(string_value) AS string_value ,
location,
MAX(model) AS model,
MAX(asset_num) AS asset_num,
MAX(exp_date) AS exp_date
FROM TableName
GROUP BY location
You can Try below - using aggregation and group by
select location, model, asset_num,max(string_value),max(exp_date)
from tablename
group by location, model, asset_num
I am guessing that the triple location, model, asset_num defines the row in the result set. If so, use aggregation:
select location, model, asset_num,
max(string_value) as string_value,
max(exp_date) as exp_date
from t
group by location, model, asset_num;
Related
I got a working answer
added the final query to the end of the question.
Thank you
Original Question:
Maybe thats not a good idea or not even possible, but I want to create something like multiple lists with one sql query.
This is my data example:
+------+--------+
| id | type |
+------+--------+
| 1 | type_1 |
| 2 | type_2 |
| 3 | type_1 |
| 4 | type_1 |
| 5 | type_3 |
| 6 | type_4 |
| 7 | type_2 |
| 8 | type_4 |
| 9 | type_4 |
+------+--------+
now i want to generate something kind of lists like this:
+--------+--------+--------+--------+
| type_1 | type_2 | type_3 | type_4 |
+--------+--------+--------+--------+
| 1 | 2 | 5 | 6 |
| 3 | 7 | | 8 |
| 4 | | | 9 |
+--------+--------+--------+--------+
Note there are empty columns, when nothing more is found but more lines are generated.
I have no clue if this is even possible, but if it is, I need some help to do this :)
It would be totally ok to get the grouped IDs like this, if thats a more possible/straightforward way:
+--------+-------+
| types | ids |
+--------+-------+
| type_1 | 1,3,4 |
| type_2 | 2,7 |
| type_3 | 5 |
| type_4 | 6,8,9 |
+--------+-------+
Thanks for any advice.
Answer
I modified the query posted by #Zakaria a bit:
select type, group_concat(distinct id)
from my_table
where type in (
'type_1',
'type_2',
'type_3'
)
group by type;
I added a distinct id, because the IDs are pages, where an item of a type could exist multiple times.
This generates the following output
+--------+------------------+
| type | group_concat(id) |
+--------+------------------+
| type_1 | 1,3,4 |
| type_2 | 2,7 |
| type_3 | 5 |
| typ3_4 | 6,8,9 |
+--------+------------------+
Works exactly like I needed.
Second output can be generated very easily with group_concat:
select type, group_concat(id)
from table_name
group by type
Fiddle
We can generate the first output using a pivot query with the help of ROW_NUMBER:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY type ORDER BY id) rn
FROM yourTable
)
SELECT
MAX(CASE WHEN type = 'type_1' THEN id END) AS type_1,
MAX(CASE WHEN type = 'type_2' THEN id END) AS type_2,
MAX(CASE WHEN type = 'type_3' THEN id END) AS type_3,
MAX(CASE WHEN type = 'type_4' THEN id END) AS type_4
FROM cte
GROUP BY rn
ORDER BY rn;
I have a query on a table of phone calls that uses GROUP BY to show only unique caller ids. The problem is that if a caller has caller id blocking their caller id shows up as "Unknown" and the client doesn't want all Unknowns to be summed up together. So basically, instead of just GROUP BY caller_id I need to somehow do something like GROUP BY caller_id IF caller_id != 'Unknown'
Is this even possible? I'd like to avoid doing all the group processing in PHP if at all possible.
You can do something like:
SELECT caller_id FROM phone_calls WHERE caller_id != 'Unknown' GROUP BY caller_id;
or consider DISTINCT - in most cases it is faster - if you have index created on caller_id the performance is usually the same, but if not DISTINCT is better. If you need :
... show only unique caller ids ..
but maybe for your case (doing aggregation or something similar) you are not able to use it but just in case:
SELECT DISTINCT caller_id FROM phone_calls WHERE caller_id != 'Unknown';
-- EDIT AFTER discussion in comments
SELECT * FROM callers;
+----+-----------+-----------+
| id | caller_id | call_time |
+----+-----------+-----------+
| 1 | abc | 24 |
| 2 | abc | 16 |
| 3 | xyz | 10 |
| 4 | xyz | 10 |
| 5 | Unknown | 11 |
| 6 | Unknown | 12 |
| 7 | Unknown | 13 |
| 8 | xyz | 1 |
| 9 | abc | 10 |
+----+-----------+-----------+
SELECT caller_id, SUM(call_time) FROM callers
WHERE caller_id != 'Unknown'
GROUP BY caller_id;
+-----------+----------------+
| caller_id | SUM(call_time) |
+-----------+----------------+
| abc | 50 |
| xyz | 21 |
+-----------+----------------+
SELECT caller_id, SUM(call_time) FROM callers
GROUP BY caller_id;
+-----------+----------------+
| caller_id | SUM(call_time) |
+-----------+----------------+
| abc | 50 |
| Unknown | 36 |
| xyz | 21 |
+-----------+----------------+
SELECT caller_id, SUM(call_time) as total_time FROM callers
WHERE caller_id != 'Unknown'
GROUP BY caller_id
UNION
SELECT caller_id, call_time FROM callers
WHERE caller_id = 'Unknown';
+-----------+------------+
| caller_id | total_time |
+-----------+------------+
| abc | 50 |
| xyz | 21 |
| Unknown | 11 |
| Unknown | 12 |
| Unknown | 13 |
+-----------+------------+
SELECT caller_id, SUM(call_time) as total_time FROM callers
GROUP BY caller_id,
(case when caller_id = 'Unknown'
AND id is not null
then id end
);
+-----------+------------+
| caller_id | total_time |
+-----------+------------+
| abc | 50 |
| Unknown | 11 |
| Unknown | 12 |
| Unknown | 13 |
| xyz | 21 |
+-----------+------------+
I have a MySql table with the following data:
| ID | House | Date |
| 1 | A | 2015-03-13 15:56:59 |
| 2 | A | 2015-03-11 12:19:45 |
| 3 | A | 2015-03-06 00:00:00 |
| 4 | B | 2015-03-13 16:07:21 |
| 5 | B | 2015-03-11 13:02:22 |
I'm trying to get the following results:
| ID | House | Date |
| 1 | A | 2015-03-13 15:56:59 |
| 4 | B | 2015-03-13 16:07:21 |
I've tried using subqueries and other types of things. Any ideas of what I could use?
Query:
select h1.id, h1.house, h1.date
from house h1 left join house h2
on h1.house = h2.house and h1.date < h2.date
where h2.date is null
This query makes no assumptions about the ordering of the data.
Demo: http://sqlfiddle.com/#!9/2da11/1
Assuming the table name is tableName
Select tbl.id, temp.house,
temp.datecol
from tableName tbl,
(
select max(tbl2.datecol),
tbl2.house
from tableName tbl2
group by tbl2.house
) temp
where tbl.house=temp.house
order by temp.datecol asc;
This can be done in a simpler way.
SELECT id, house, date FROM house WHERE date > '2015-03-13'
Now I union 3 table and select become below show.
|remark|totalA|totalB|tatalC|
-----------------------------
| a | 123 | NULL | NULL |
| a | NULL | 123 | NULL |
| a | NULL | NULL | 123 |
How to let it become 1 row as below show?
|remark|totalA|totalB|tatalC|
-----------------------------
| a | 123 | 123 | 123 |
I trying group and distinct it but it show below
|remark|totalA|totalB|tatalC|
-----------------------------
| a | 123 | NULL | NULL |
select
remark,
sum(totalA) as totalA,
sum(totalB) as totalB,
sum(totalC) as totalC
from the_table
group by remark
Usesum along with group by as
select remark, sum(totalA), sum(totalB), sum(totalC)
from table_name
group by remark
Use an aggregate function, like MIN(), which will exclude nulls by default:
SELECT remark, MIN(totalA), MIN(totalB), MIN(totalC)
FROM Remarks
GROUP BY remark
I have events flowing into a MySQL database and I need to group and sum the events to transactions and store away into another table. The data looks like:
+----+---------+------+-------+
| id | transid | code | value |
+----+---------+------+-------+
| 1 | 1 | b | 12 |
| 2 | 1 | i | 23 |
| 3 | 2 | b | 34 |
| 4 | 1 | e | 45 |
| 5 | 3 | b | 56 |
| 6 | 2 | i | 67 |
| 7 | 2 | e | 78 |
| 8 | 3 | i | 89 |
| 9 | 3 | i | 90 |
+----+---------+------+-------+
The events arrive in batches and I would like to create the transaction by summing up the values for each transid, like:
select transid, sum(value) from eventtable group by transid;
but only after all the events for that transid have arrived. That is determined by the event with the code e (b for the beginning, e for the end and i for varying amount of intermediates). Being a novice in SQL, how could I implement the requirement for the existance of the end code before the summing?
Perhaps with having:
select transid, sum(value)
from eventtable
group by transid
having max(case code when 'e' then 1 end)=1;
select transid, sum(value) from eventtable
group by transid
HAVING COUNT(*) = 3
you should count the records in the group. So when there is (b)egin, (i)?? don't know what it is and (e)nd this group is not filtered out.