MySQL data in column wise which is stored in row based - mysql

I am having a table with data stored in row basis as shown below.
UID | DetailsID | Data|
----------------------|
1 | 1 | A |
1 | 2 | 200|
1 | 3 | 2010-10-11 08:32 |
2 | 1 | B |
2 | 2 | 600|
2 | 3 | 2011-05-20 14:56 |
From this I need the output as follows
UID|1|2|3
------------
1|A|200|2010-10-11 08:32
2|B|600|2011-05-20 14:56
Here main thing is, the number of entries of DetailsID values is not known.
I wanted this one in MySQL.
Please help me out of this.

Not quite what you want, but other than loads of left joins i can only suggest:
SELECT UID,GROUP_CONCAT(DetailsID SEPARATOR ",") "DetailsIDs",GROUP_CONCAT(Data SEPARATOR ",") "Data" FROM data_table GROUP BY UID;

Do that transformation in your coding language, not in SQL.

you didnt say where you need the output. If you need the output in PHP pages it is simple only by creating the loop for the entries in columns wise.

Related

Is there a way in SQL to create a new column that looks at the values in a column that shares multiple rows to determine the value in the new column?

My data looks similar to what I've attached.
I'm wanting to create a new column that looks at the appt# and any row associated with that appt to see if that appt had the procedure D0330 and marks it yes or no.
So for example B Bradley's appt 8210 did include the procedure D0330. So the new column would be marked yes for both lines 1 & 2 despite line 2 not having that specific procedure in it's row.
What would be the best way to go about doing this?
Data
You can't define a column of a table that auto-generates a value based on multiple rows, or a subquery, or anything like that. Generated columns can only be based on simple functions that reference columns within the same row.
But you can reference a window of rows in a query, and produce a column of that query result, even though the column is not persisted in the table.
SELECT *, MAX(CASE `procedure` WHEN 'D0330' THEN 'Yes' ELSE 'No' END)
OVER (PARTITION BY employee) AS `newcolumn`
FROM mytable;
+------+-----------+-----------+------+-----------+
| line | employee | procedure | apt | newcolumn |
+------+-----------+-----------+------+-----------+
| 1 | B Bradley | D0330 | 8210 | Yes |
| 2 | B Bradley | D1226 | 8210 | Yes |
| 3 | C Connor | D1457 | 1130 | No |
| 4 | D David | D0330 | 543 | Yes |
+------+-----------+-----------+------+-----------+
Window functions require MySQL 8.0.

Separating a comma separated string to a new table

I inherited a project that has comma separated strings stored in a field called 'subsector' in a table named 'com_barchan_project'. I need to change this horrible design, since it's proving to be an issue trying to parse through this field. See HERE for the full story:
| id | name | sector | subsector |
+----+------+--------+-----------+
| 1 | test | 2 | 3,4,7 |
+----+------+--------+-----------+
| 2 | door | 5 | 2 |
I have created a new table called 'com_barchan_project_subsector_join' with the required fields and would like to move the values stored in 'com_barchan_project' to this new empty table.
Can anyone help me with the SQL statement that would accomplish this?
Here's what the new 'com_barchan_project_subsector_join' table should look like:
| id | project_id | subsector_id |
+----+------------+--------------+
| 1 | 1 | 3 |
+----+------------+--------------+
| 2 | 1 | 4 |
+----+------------+--------------+
| 3 | 1 | 7 |
+----+------------+--------------+
| 4 | 2 | 2 |
Once I move over the data, I will remove the 'subsector' field from the 'com_barchan_project' table and be done with it.
Thanks for your help!!!
John
Using shorter table names for brevity/clarity; and assuming you have (or can easily make) a comprehensive subsectors table...and assuming your csv are stored in a consistent format (no spaces at least).
INSERT INTO `project_subsectors` (project_id, subsector_id)
SELECT p.id, s.id
FROM projects AS p
INNER JOIN subsectors AS s ON p.subsector = s.id
OR p.subsector LIKE CONCAT(s.id, ',%')
OR p.subsector LIKE CONCAT('%,', s.id, ',%')
OR p.subsector LIKE CONCAT('%,', s.id)
;
I can't guarantee it will be fast; I'd be surprised if it was.
ON FIND_IN_SET(s.id, p.subsector) > 0 may work as well, but I am not as familiar with the behavior of that function.

MySQL combine columns before matching it with LIKE

I have two columns in my database that I want to combine before matching them using LIKE statement.
My table:
|---------------------------------|
| ID | PREFIX | SUFFIX |
|---------------------------------|
| 1 | 31 | 523 |
|---------------------------------|
| 2 | 62 | 364 |
|---------------------------------|
I want to be able to supply 315 and ID 1 would be returned. Is there any easy way of doing it? At the moment I am splitting search string and matching separate columns.
Thanks.
SELECT * FROM table WHERE CONCAT(PREFIX, SUFFIX) LIKE '%315%'

Select all records from table A and join table B to get A's property

I can not figure out how I should do it...
Table 'child':
idchild | name | idability
--------------------------
1 | Joe | 1
1 | Joe | 2
2 | Peter| 1
2 | Peter| 3
3 | Kate | 4
Table 'ability':
idability | ability
-------------------
1 | run
2 | read
3 | write
4 | swim
For example, Joe can 'run' and 'read' but can't 'write' or 'swim'.
And I need a list like this about Joe's ability:
ability |
-----------------
run | +
read | +
write | -
swim | -
I've tried several SQL queries in different ways (using 'NOT EXIST') but never got the correct result. I hope somebody can tell me how I should do this.
Thank you in advance!
This should be ok:
select ability.ability, if(child.idability,'+','-') from ability left join child on ability.idability =child.idability and child.name="joe";
Try this one:
select `child`.`idChild`,`child`.`name`, `child`.`idability`, `ability`.`idAbility`,`ability`.`ability` from `child` inner join `ability` on `child`.`idAbility` = `ability`.`idability` order by `child`.`name`, `ability`.`ability`
You can remove columns that you don't need.

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