MYSQL - How to let 3 row data become 1 row data - mysql

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

Related

Join data table with latest value, if not found show null mysql?

I have 3 tables, which every table has it's own foreign key and primary key.
Table scheme looks like this :
tbl_cake
/---------------------------------------------------------------------------\
| CakeId (Primary key) | CakeName | UserId (Foreign Key from tbl_user) |
|----------------------------------------------------------------------------|
| 1 | BlackForest | 12345 |
|----------------------------------------------------------------------------|
| 2 | Fruit Pie | 98475 |
|----------------------------------------------------------------------------|
| 3 | Birthday Cake | 12345 |
|----------------------------------------------------------------------------|
| 4 | Raspberry Pie | 28475 |
\----------------------------------------------------------------------------/
tbl_user
/--------------------------------------\
| UserId (Primary key) | UserName |
|--------------------------------------|
| 12345 | Angelia |
|--------------------------------------|
| 98475 | Rudi |
|--------------------------------------|
| 56782 | Andika |
\--------------------------------------/
tbl_transaction
/--------------------------------------------------------------------------------------------------\
| TransactionId(Primary) | CakeId(Foreign) | UserId| Qty | Date | OrderType |
|--------------------------------------------------------------------------------------------------|
| 1 | 1 | 12345 | 1000 | 2020-04-01 10:05:01 | Drive Thru |
|--------------------------------------------------------------------------------------------------|
| 2 | 2 | 98475 | 200 | 2020-04-03 09:15:01 | On The Spot |
|--------------------------------------------------------------------------------------------------|
| 3 | 2 | 98475 | 500 | 2020-04-03 11:05:01 | On The Spot |
|--------------------------------------------------------------------------------------------------|
| 4 | 1 | 12345 | 150 | 2020-04-05 08:05:01 | On The Spot |
\--------------------------------------------------------------------------------------------------/
So the goals are :
Show UserId,TransactionId,Qty,Date and OrderType which :
Show all UserId, either it has any order or not.
If multiple order occurs, then show the latest data
If UserId don't have any order, fill the missing values with null
Finally, show the data with OrderType 'On The Spot'.
The expected result will be :
FINAL RESULT
/----------------------------------------------------------------------------------\
| UserId | TransactionId | Qty | Date | OrderType |
|----------------------------------------------------------------------------------|
| 12345 | 4 | 150 | 2020-04-05 08:05:01 | On The Spot|
|----------------------------------------------------------------------------------|
| 98475 | 3 | 500 | 2020-04-03 11:05:01 | On The Spot|
|----------------------------------------------------------------------------------|
| 56782 | null | null | null | null |
\----------------------------------------------------------------------------------/
I think using join(s) will accomplish this, but i'm not sure how, especially when determine if UserId has any order or not, and pick the latest order to be shown.
Many thanks!
In MySQL 8+, we would use ROW_NUMBER here:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY Date DESC) rn
FROM tbl_transaction
WHERE OrderType = 'On The Spot'
)
SELECT
u.UserId,
t.TransactionId,
t.Qty,
t.Date,
t.OrderType
FROM tbl_user u
LEFT JOIN cte t
ON u.UserId = t.UserId AND rn = 1;
Demo
I managed to solve it (using left join and max function) :
select tbl_user.UserId,tbl_transaction.TransactionId,tbl_transaction.Qty,tbl_transaction.Date,
tbl_transaction.OrderType
from tbl_cake
left join tbl_user on tbl_user.UserId=tbl_cake.UserId
left join tbl_transaction on tbl_user.UserId=tbl_transaction.UserId
and
tbl_transaction.Date=(select max(Date) from tbl_transaction where UserId=tbl_User.UserId
and tbl_transaction.OrderType="On The Spot")
group by UserId

Select multiple rows into one row from one table

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;

How can I treat with NULL as minimum value?

I have a table like this:
// notifications
+----+-----------+-------+---------+---------+------+
| id | score | type | post_id | user_id | seen |
+----+-----------+-------+---------+---------+------+
| 1 | 15 | 1 | 2342 | 342 | 1 |
| 2 | 5 | 1 | 2342 | 342 | 1 |
| 3 | NULL | 2 | 5342 | 342 | 1 |
| 4 | -10 | 1 | 2342 | 342 | NULL |
| 5 | 5 | 1 | 2342 | 342 | NULL |
| 6 | NULL | 2 | 8342 | 342 | NULL |
| 7 | -2 | 1 | 2342 | 342 | NULL |
+----+-----------+-------+---------+---------+------+
-- type: 1 means "it is a vote", 2 means "it is a comment (without score)"
Here is my query:
SELECT SUM(score), type, post_id, seen
FROM notifications
WHERE user_id = 342
GROUP BY type, post_id
ORDER BY (seen IS NULL) desc
As you see, there is SUM() function, Also both type and post_id columns are in the GROUP BY statement. Well now I'm talking about seen column. I don't want to put it into GROUP BY statement. So I have to use either MAX() or MIN() for it. Right?
Actually I need to select NULL as seen column (in query above) if there is even one row which has seen = NULL. My current query selects 1 as seen's value, even when I use MIN(seen). So why 1 is minimum when there is NULL?
Also I want to order rows so that all SEEN = NULL be in the top of list. How can I do that?
Expected result:
// notifications
+-----------+-------+---------+------+
| score | type | post_id | seen |
+-----------+-------+---------+------+
| 13 | 1 | 2342 | NULL |
| NULL | 2 | 8342 | NULL |
| NULL | 2 | 5342 | 1 |
+-----------+-------+---------+------+
You could do this
case when sum(seen is null) > 0
then null
else min(seen)
end
You could use the following query:
SELECT SUM(score), type, post_id, min(IFNULL(seen, 0)) as seen
FROM notifications
WHERE user_id = 342
GROUP BY type, post_id
ORDER BY seen desc

Where clause with having count breaks query

This query isn't returning what I though it should:
Select user_id
from subs
where status = 'Failed'
and next_run_dt = '2016-08-04'
and active = '1'
group by user_id having count(status) = 2
Table structure and sample data:
id__|__status__|__next_run_dt__|__user_id__|__active__|
| | | | |
1 | Failed | 2016-08-04 | 3 | 1 |
___|__________|_______________|___________|__________|
| | | | |
2 | Failed | 2016-08-04 | 4 | 1 |
___|__________|_______________|___________|__________|
| | | | |
3 | Failed | 2016-08-04 | 3 | 1 |
___|__________|_______________|___________|__________|
The query should return the user_id of 3 because that user has two entries with at status of Failed. The query returns the user_id if I remove and next_run_dt = '2016-08-04' (date column).
What am I missing?
EDIT: There also exists the possibility that a user_id can also have a next_run_dt of null as well
Are you sure it's a date column? If it's datetime, you'll have problems.
Your query works for me on SQLFiddle.
http://sqlfiddle.com/#!9/f0bab6/1

MySQL: Order by field, placing empty cells at end

I have a MySQL table which contains a number of products. What I want to do is sort the table by one particular column (most of the values begin with numbers for example: 1st, 2nd), etc. However, since some records do not have a value for this column, when I try to sort, the table automatically puts empty rows FIRST.
I am looking for a way to sort the row ASCENDING, but only insert blank records at the end of the sorted records, if that makes sense?
Any help would be most gratefully received!
select * from table
order by if(field = '' or field is null,1,0),field
This is one of the most effective method
ASC Order
SELECT * FROM user ORDER BY name IS NULL, name ASC
Expected Result:
+----+--------+------------+
| id | name | date_login |
+----+--------+------------+
| 3 | david | 2016-12-24 |
| 2 | john | NULL |
| 4 | zayne | 2017-03-02 |
| 1 | NULL | 2017-03-12 |
DESC Order
SELECT * FROM user ORDER BY name IS NULL, name DESC
Expected Result:
+----+--------+------------+
| id | name | date_login |
+----+--------+------------+
| 4 | zayne | 2017-03-02 |
| 2 | john | NULL |
| 3 | david | 2016-12-24 |
| 1 | NULL | 2017-03-12 |