MySql - Concatenate/merge multiple columns into one column with hard codded titles - php

i should migrate multiple columns of text into one column (in another database). Now i know that it sounds complicated, but i will try my best to explain it.
There is a table in mysql database called "products_desriptions". In that table we have columns like: descriptionDosage, descriptionAction, descriptionIndications and so on. What i want to do is to merge these columns into one column called "productDescription".
Here is an example of what i have done:
SELECT
CONCAT_WS('\ntest', action, Indications, staff, dosage) AS productDescription)
FROM
products_descriptions
WHERE
product_id = 123
So the the columns are being merged successfully.
The problem is that for each column there is a title in the frontpage, which is not being stored into the respective column. For example in the "dosage" column we have text like: "2xday, 14xweek" and so on. And on the frontpage what you can see is something like:
"DOSAGE:
2xday, 14xweek" and so on.
So for each column there is a hard codded title like this one, which i don't know how to get. I mean what i want to do is: to merge columns and respectively for each column i want a title to the respective text.
I am working on php, so maybe it is not possible to be done only by mysql. Maybe i have to do it with php, but has anyone got any idea what exactly should i do?

You can use concat function.
SELECT
CONCAT('\ntest', action, '\nIndictions:', Indications,'\nstaff:', staff,'\ndosage:', dosage) AS productDescription
FROM
products_descriptions
WHERE
product_id = 123

Related

Select unique values from Database

Im having some troubles showing the unique values from my database.
As an example, I have this very simple test table:
Where you can see that there is a duplicated value on the Tags column, named intro.
I would like to echo all of the UNIQUE tags, and I've tried with the DISTINCT command, but I might be doing something wrong.
This is my actual query:
SELECT DISTINCT tags FROM blog
But this gives me ALL of the tags.
Any help would be appreciated, thanks.
According to the image there are just to rows in the table, one contains "intro" and the other contains "intro, php, warning, errors".
If so, there are not the same.
I think you try to use a row for each value.
To do it you should insert each value in a separated sentence, or in the same but using different rows, something like:
insert into blog(tags) values ("intro"),values ("intro"),values ("php")

SQL query, comparing two arrays

I have an application with images stored in multiple categories, currently being stored by category ID in a column as a space separated list (eg. 1 5 23 2).
I have a query from a search filter, which is currently an array of IDs, (eg. 1 5).
Ideally, I'd find a solution using something like WHERE IN that would see if any of my array values exist in the stored column, although I don't see an easy solution.
At the moment I have to query all the images, bring them into PHP and check there, using "array_intersect". I see this as being a problem if I have 100,000s of images in the future to pull and then check.
Can anyone think of an elegant solution? The application is still in development, so I could arguably change the structure of my tables.
I think adding a map table would probably be best here which maps the image_id with the category_id.
refactor your database tables!!!
use sth like this:
table_image
id int
name text,
content text,
...
and a second table for the categories:
table_category
id int,
image_id int,
category int
this way, you can store categories in a separate table using foreign keys. now, you can do simple sql queries like
SELECT table_image.id FROM table_image, table_category WHERE table_image.id = table_category.image_id and table_category.category = $cat_arr[0] OR table_category.category = $cat_arr[1] ...
H Hatfield has the best answer. If you really must use a single column (which I do not recommend) you could store the categories as a comma separated list instead of spaces. You can then use the MySql function find_in_set, as such:
WHERE FIND_IN_SET('3', categoryListColumnName) > 0 OR FIND_IN_SET('15', categoryListColumnName) > 0
Using your current database design you could use an IN query:
WHERE categoryListColumnName LIKE '% 3 %' OR categoryListColumnName LIKE '% 15 %'
and add more OR's for every category you want to find. When using this query you have to make sure your list separated by spaces ends and starts with a space, otherwise it won't work.
Let me just reiterate, that these methods will work, but they are not recommended.

Completely arbitrary sort order in MySQL with PHP

I have a table in MySQL that I'm accessing from PHP. For example, let's have a table named THINGS:
things.ID - int primary key
things.name - varchar
things.owner_ID - int for joining with another table
My select statement to get what I need might look like:
SELECT * FROM things WHERE owner_ID = 99;
Pretty straightforward. Now, I'd like users to be able to specify a completely arbitrary order for the items returned from this query. The list will be displayed, they can then click an "up" or "down" button next to a row and have it moved up or down the list, or possibly a drag-and-drop operation to move it to anywhere else. I'd like this order to be saved in the database (same or other table). The custom order would be unique for the set of rows for each owner_ID.
I've searched for ways to provide this ordering without luck. I've thought of a few ways to implement this, but help me fill in the final option:
Add an INT column and set it's value to whatever I need to get rows
returned in my order. This presents the problem of scanning
row-by-row to find the insertion point, and possibly needing to
update the preceding/following rows sort column.
Having a "next" and "previous" column, implementing a linked list.
Once I find my place, I'll just have to update max 2 rows to insert
the row. But this requires scanning for the location from row #1.
Some SQL/relational DB trick I'm unaware of...
I'm looking for an answer to #3 because it may be out there, who knows. Plus, I'd like to offload as much as I can on the database.
From what I've read you need a new table containing the ordering of each user, say it's called *user_orderings*.
This table should contain the user ID, the position of the thing and the ID of the thing. The (user_id, thing_id) should be the PK. This way you need to update this table every time but you can get the things for a user in the order he/she wants using ORDER BY on the user_orderings table and joining it with the things table. It should work.
The simplest expression of an ordered list is: 3,1,2,4. We can store this as a string in the parent table; so if our table is photos with the foreign key profile_id, we'd place our photo order in profiles.photo_order. We can then consider this field in our order by clause by utilizing the find_in_set() function. This requires either two queries or a join. I use two queries but the join is more interesting, so here it is:
select photos.photo_id, photos.caption
from photos
join profiles on profiles.profile_id = photos.profile_id
where photos.profile_id = 1
order by find_in_set(photos.photo_id, profiles.photo_order);
Note that you would probably not want to use find_in_set() in a where clause due to performance implications, but in an order by clause, there are few enough results to make this fast.

PHP sort an array by lastname separated by whitespace in modx

I have a mysql table that looks like this:
id author public image1 image2 image3 bio media1 media2 media3 media4 media5 media6
The Field "author" normaly has Firstname (Secondname) Lastname seperated by whitespaces.
How can I sort the array after the Lastname and if just one name is present after this one.
This is the modx query I use to sort after the author but obviously it doesn't use the lastname.
$c = $modx->newQuery('AuthorDe');
$c->sortby('author','ASC');
$authors = $modx->getCollection('AuthorDe',$c);
You're shooting yourself in the foot right now, for a couple of reasons:
When there is only one word in the string, the sorting is hard to predict.
You have indexes for your data for a reason. They make it a lot faster. Using string functions force a table scan. Good enough for 100 data units, slow for 10000 rows and 'database went for a vacation" at 1000000.
Next time you have to use the author field and you realize you have to split it up to words you also have to understand and fix this code snippet on top of the old ones.
That said - I haven't tested it - but try this:
$c->sortby('substring_index(author," ",-1)','ASC');
So to elaborate on the very valuable point jous made, putting multiple points of data in one database column is counter productive.
The sorting you want to do would be simple, fast, & efficient, in a sql query (using the same construct jous showed but without the string operation).
To modify this table you would simply add the following columns to your table in place of author:
firstname
lastname
middlename
To show you how simple this is (and make it even easier) here's the code to do it:
ALTER TABLE [tablename]
ADD COLUMN firstname varchar(32)
ADD COLUMN lastname varchar(32)
ADD COLUMN middlename varchar(32)
DROP COLUMN author;
Then the modx PHP code would be:
$c->sortby('lastname','ASC');
So this is fairly easily done... and if you still need to support other references to author then create a view that returns author in the same way the un-altered table did as shown below (NOTE: you would still have to change the table name reference so it points to the view instead of the table... if this will be a big problem then rename the table and name the view the same as the old table was...):
CREATE VIEW oldtablename AS
SELECT firstname+' '+middlename+' '+lastname' ' AS author
FROM newtablename;
NOTE: if you do create a view like the above then it is probably worth your while to add all of the other columns from the new table (the multiple image & media columns).
NOTE2: I will add, however, that those would ideally be in separate tables with a join table to this one... but if I were in your spot I might agree that expedience might beat utility & future usability.... however if you did put them in different tables you could add those tables to this view (as joins to the new table) and still be able to support existing code that depends on the old table & it's structure.
While the above is all fairly easily done and will work with minor adjustments from you the last part of this is getting your custom table changes to be reflected by xPDO. If you are already comfortable with this and know what to do then great.
If you aren't this is by far the best article on the topic: http://bobsguides.com/custom-db-tables.html
(Yes it is worth getting Bob's code as a snippet so all of this can simply be generated for you once the database changes have been made... (remember you will likely need to delete the existing schema file & xpdo related class files & map files before you run Bob's generation code, or your changes that have the same table name, like the view, won't take effect).
Hope this helps you (or the next person to ask a similar question).

Using string functions on Alias title using MySQL

I want to name my Alias titles using data from my tables. Here's a totally stupid example to show what I want to do:
SELECT id AS CONCAT('id_', name)
Which would give me the output id_5 => 5. (if ID was 5 in the table)
Sounds like what you're after is a pivot - you mean that for each row in the table, you would end up with a new column, right? If so, then just google mysql pivot (sorry, I'm used to sqlserver)

Categories