Pivot SQL data - groups rows into columns - mysql

I have data stored in a mySQL database in the following format:
+------------+------------+-----------+
| id | field | value |
+============+============+===========+
| 1 | first | Bob |
+------------+------------+-----------+
| 1 | last | Smith |
+------------+------------+-----------+
| 2 | first | Jim |
+------------+------------+-----------+
| 2 | last | Jones |
+------------+------------+-----------+
and I would like it returned as follows:
+------------+------------+-----------+
| id | first | last |
+============+============+===========+
| 1 | Bob | Smith |
+------------+------------+-----------+
| 2 | Jim | Jones |
+------------+------------+-----------+
I know this seems like a silly way to store data, but it's just a simple example of what I really have. The table is formatted this way from a WordPress plugin, and I'd like to make it work without having to rewrite the plugin.
From what I've read, I can't use PIVOT with mySql. Is there something similar to PIVOT that I can use to achieve what I'm going for?

Try this pivot query:
SELECT id,
MAX(CASE WHEN field = 'first' THEN value ELSE NULL END) AS first,
MAX(CASE WHEN field = 'last' THEN value ELSE NULL END) AS last
FROM yourTable
GROUP BY id
Follow the link below for a running demo:
SQLFiddle

Try this;)
select
id,
max(if(field='first', value, null)) as first,
max(if(field='last', value, null)) as last
from yourtable
group by id
SQLFiddle DEMO HERE

Related

Insert concatenated values from multiple rows as new row in MySQL query

I currently have a table with columns for "field_type" (username, city, state), "user_id", and "value". The user_id column obviously has lots of repeats. I'd like to merge the city and state data into a single "location" field_type value. I need something that will:
for every integer in the user_id column:
-check if there exist corresponding (not null) table rows for field_type "city" and "state"
-if yes, insert a new row into the table with field_type "location" which concatenates the corresponding city and state values for that user_id
I haven't worked with MySQL much so I don't really know where to start. I've tried to simplify the problem a bit - it's actually a somewhat more complicated wordpress table and I'm trying to reformat the data to be compatible with a new plugin, but this covers the basics of what has to happen so I should hopefully be able to extrapolate an actual solution from the answers. Thanks for any pointers!
Edit: Current structure looks like this:
|-id (key)-|- field_type -|- user_id -|- value -|
| 1 | username | 1 | Joe |
| 2 | city | 1 | Albany |
| 3 | state | 1 | NY |
| 4 | username | 2 | Bob |
| 5 | city | 2 | Toledo |
| 6 | state | 2 | OH |
And I would like to get something like this:
|-id (key)-|- field_type -|- user_id -|- value ---------|
| 1 | username | 1 | Joe |
| 2 | city | 1 | Albany |
| 3 | state | 1 | NY |
| 4 | username | 2 | Bob |
| 5 | city | 2 | Toledo |
| 6 | state | 2 | OH |
| 7 | location | 1 | Albany, NY |
| 8 | location | 2 | Toledo, OH |
Duplicate user_id values are how it's supposed to work, so they don't need to be removed.
You could use an INSERT ... SELECT query to do this:
INSERT INTO yourtable
SELECT 'location' AS field_type, t1.user_id, CONCAT(t1.value, ' ', t2.value) AS value
FROM yourtable t1
JOIN yourtable t2 ON t2.user_id = t1.user_id AND t1.field_type = 'city' AND t2.field_type = 'state'
WHERE t1.value IS NOT NULL AND t2.value IS NOT NULL
Demo on dbfiddle
Since you are mentioned that there are duplicates with the same user_id.
I don't think inserting a new row will be a good idea.
So have written an update query to update the existing data.
You can later cleanup the duplciates.
UPDATE your_table SET locations = CONCAT_WS('-', state, city) where city is not null or state is not null

find unique items based on date column

I need to find unique items based on date column. I tried to group the data together, but am not getting the desired result.
In the below sample i need to find the new entry i.e."New Company" seen on date 27th July because it does not exists on 16th July. I have thousand such rows and various dates.
The table contains issues seen on an Operating system datewise. I need to find the new issues a particular company is hitting. Pls help!
mysql> select * from testdata;
+------------+----------------+-----------------------+
| date | os_ver | account_name | count |
+------------+----------------+-----------------------+
| 2018-07-16 | 22.345-595 | Company AA1 | 2 |
| 2018-07-16 | 22.346-596 | Company BB1 | 1 |
| 2018-07-16 | 22.346-596 | Company CC1 | 2 |
| 2018-07-27 | 22.346-595 | Company AA1 | 1 |
| 2018-07-27 | 22.346-596 | Company BB1 | 2 |
| 2018-07-27 | 22.346-596 | New Company | 1 |
| 2018-07-27 | 22.346-596 | Company CC1 | 1 |
+------------+----------------+----------------------
I tried the below, but it's not showing the unique item:
SELECT * FROM `testdata` group by timestamp order by timestamp DESC
Your question isn't entirely clear. However if you are trying to find the earliest date for the first occurence of each account name, then see the following query.
SELECT t.*
FROM test t
LEFT JOIN test t1
ON t.date > t1.date
AND t.account_name = t1.account_name
WHERE t1.date IS NULL;
Here's an SQL Fiddle demonstrating the query with your sample data.
Alternatively, if you want to find all account names that occur only once, then see the following query.
SELECT t.*
FROM test t
GROUP BY t.account_name
HAVING COUNT(*) = 1;
Here's an SQL Fiddle demonstrating the query with your sample data.
your question is not much clear but i guess you need below something
select date,os_ver,account_name,count(*) from testdata
group by date,os_ver,account_name

merger one row with null values to not null values of another row mysql

I want to merge two rows into one.The below format is in the database.
+----+---------+-----------------------+-------------------------+
| id | appid | photo | signature |
+====+=========+=======================+=========================+
| 1 | 10001 | 10001.photograph.jpg | NULL |
| 2 | 10001 | NULL | 10001.signature.jpg |
+----+---------+-----------------------+-------------------------+
I want a mysql query so that i can fetch data like below,
+--------+------------------------+-------------------------+
| appid | photo | signature |
+========+========================+=========================+
|10001 | 10001.photograph.jpg | 10001.signature.jpg |
+--------+------------------------+-------------------------+
Kindly suggest...
You can also use max function
select appid,
max(photo) photo,
max(signature) signature
from test
group by appid
Demo
This should do this:
select t1.appid,t1.photo,t2.signature from mytable t1 join mytable t2 on t1.appid=t2.appid where t1.id=1 and t2.id=2

Display one column data to two column

Table A
| SLNO | TYPENAME | TYPEMODE |
------------------------------
| 1 | Act.Alw | A |
| 2 | Canteen | D |
I want to display two column according to its typmode
using UNION ALL I get
| Addition | Deduction |
------------------------
| Act.Alw | |
| | Canteen |
I want display like this. Addtion and Deduction are alias
| ADDITION | DEDUCTION |
------------------------
| Act.Alw | Canteen |
It looks like you need to use a join instead of a union. But it would be helpful if you could explain a little bit more about what you are trying to accomplish and maybe post he sql query you are currently trying to run.
You can use CASE statement for that. To group them you need to use GROUP_CONCAT function like this:
SELECT GROUP_CONCAT(CASE WHEN typemode = 'A'
THEN typename ELSE NULL END) AS Addition
,GROUP_CONCAT(CASE WHEN typemode = 'D'
THEN typename ELSE NULL END) AS Deduction
FROM Table1
Output:
| ADDITION | DEDUCTION |
------------------------
| Act.Alw | Canteen |
See this SQLFiddle

MySQL: Sort by group and field

I have a table with the following (simplified) structure:
INT id,
INT type,
INT sort
What I need is a SELECT that sorts my data in a way, so that:
all rows of the same type are in sequency, sorted ascendingly by sort internally, and
all "blocks" of one type are sorted by their minimum sort.
Example:
If the table looks like this:
| id | type | sort |
| 1 | 1 | 3 |
| 2 | 3 | 5 |
| 3 | 3 | 1 |
| 4 | 2 | 4 |
| 5 | 1 | 2 |
| 6 | 2 | 6 |
The query should sort the result like this:
| id | type | sort |
| 3 | 3 | 1 |
| 2 | 3 | 5 |
| 5 | 1 | 2 |
| 1 | 1 | 3 |
| 4 | 2 | 4 |
| 6 | 2 | 6 |
I hope this makes it clear enough.
Looks to me, as this should be a very common requirement, but I didn't find any examples close enough to be able to transfer it to my use case on my own. I suppose I can't avoid at least one subquery, but I didn't figure it out on my own.
Any help is appreciated, thanks in advance.
By the way: I'm going to use this query with CakePHP 2.1, so if you know of a comfortable way to do it with Cake, please let me know.
This is simpler than it initially sounds. I believe the following should do the trick:
SELECT a.id, a.type, a.sort
FROM Some_Table as a
JOIN (SELECT type, MIN(sort) as min
FROM Some_Table
GROUP BY type) as b
ON b.type = a.type
ORDER BY b.min, a.type, a.sort
For best (fastest) results, you're probably going to want an index on (type, sort).
You want an additional sort by a.type (instead of (b.min, a.sort)), in case there are two groups with the same sort value (would result in mixed rows). If there are no duplicate values, you can remove it.
sort and type are reserved words on some databases and can cause you problems.
Have you tried?
ORDER BY TYPE DESC, SORT ASC