Related question
I have a very similar query to this question below:
Search GROUP_CONCAT using LIKE
I think my question is pretty much identical, but in CodeIgniter. Therefore I think I am just looking for the same answer but converted into active record language...
My question
To provide some background, in my case I have a many to many relationship so with three tables:
companies which has two fields (company_id and company_name)
sectors which has two fields (sector_id and text)
companies_sectors which has two fields (company_id and sector_id)
(One company can operate in multiple sectors, multiple companies operate in the same sector.)
I have grouped by company to show sectors.sector_name as a group_concat field and I have given an alias to this concatenated field at the select level:
$this->db->select('sectors.sector_id, GROUP_CONCAT(DISTINCT sectors.text SEPARATOR "; ") as sector_text', false);
I want to include a filter which selects where 'sector_text' (the group_concat field) includes the text from the query form. I understand that, because I want to run the filter on an aggregated list, I should use "having" and not "where". Per the answer to the link above, it looks like MySQL has a HAVING LIKE, but I was struggling to replicate this under CodeIgniter's active record (in fact my understanding is that CodeIgniter's ->like() is a WHERE x LIKE y which is not what I am looking for...)
At the moment I am only using a LIKE:
$this->db->like('sectors.text', $this->input->post('sector_text') );
But this filters before the grouping, which means the output will only show the sector that was searched for. For example, if Company A operates in "fishing" and "shipping" while Company B operates only in "fishing", and a user searched for "fishing", I want the result to show:
Company A - Fishing; Shipping
Company B - Fishing
(This is the desired result!)
But at the moment I am only getting:
Company A - Fishing
Company B - Fishing
... which I think is because I have used like, which filers pre-grouping?
Can someone please assist? Many thanks in advance!
PS If I can also use the alias "sector_text" instead of sector.text that would be ideal (I think I have read that "Having" allows you to use the alias?)
I found the answer! I just modified the "LIKE" to:
$sector_text = $this->input->post('sector_text');
$this->db->having("sector_text LIKE '%$sector_text%' ");
It feels a little off doing it via active record, but it works. If there is a solution that keeps it within active record then please let me know as I would probably prefer this!
Many thanks!
Related
I was wondering if mysql has a way to look at a column and only retrieve the results when it finds a unique column once. For example
if the table looks like this:
id name category
1 test Health
2 carl Health
3 bob Oscar
4 joe Technology
As you can see their are two rows that could have the same category. Is their a way to retrieve the result where the array will one only return the category once?
What I am trying to do is get all the categories in the database so I can loop through them later in the code and use them. For example if I wanted to created a menu, I would want the menu to list all the categories in the menu.
I know I can run
SELECT categories FROM dbname
but this returns duplicate rows where I only need the cateogry to return once. Is there a way to do this on the mysql side?
I assume I can just use php's array_unique();
but I feel like this adds more overhead, is this not something MYSQL can do on the backend?
group by worked perfectly #Fred-ii- please submit this as answer so I can get that approved for you. – DEVPROCB
As requested by the OP:
You can use GROUP BY col_of_choice in order to avoid duplicates be shown in the queried results.
Reference:
https://dev.mysql.com/doc/refman/5.5/en/group-by-handling.html
By using database normalization, you would create another table with an unique id and the category name and by that link those two together, like
select * from mytable1
on mytable1.cat = mytable2.id
group by mytable1.cat
You can ofcourse also use group by without multiple tables, but for the structure, I recommend doing it.
You can use select distinct:
SELECT DISTINCT categories
FROM dbname ;
For various reasons, it is a good idea to have a separate reference table with one row per category. This helps in many ways:
Ensures that the category names are consistent ("Technology" versus "tech" for instance).
Gives a nice list of categories that are available.
Ensures that a category sticks around, even if no names currently reference it.
Allows for additional information about categories, such as the first time it appears, or a longer description.
This is recommended. However, if you still want to leave the category in place as it is, I would recommend an index on dbname(categories). The query should take advantage of the index.
SELECT id, name from dbname GROUP BY categoryname
Hope this will help.
You can even use distinct category.
I have been relentlessly trying to edit my database relationships but to no avail. Here is the scenario:
i have an inventory table. an inventory can be classified into 2 categories(technical eg. guns, radios and general eg. uniforms). i was hoping there could be a way for me to add details(from different tables eg. technical_inventory_table and general_inventory_table) to the inventory table through the category since the two categories have different fields. is there any way for me to do that? please do note that a technical inventory will be listed individually since a single item will have a serial number attached to it.
or does the answer provided here - https://dba.stackexchange.com/questions/33099/storing-different-products-and-joining-on-table-names - be an already good solution for my problem? i would like to avoid creating a table where it will be made up of what usually are the fieldnames as described in the link to prevent confusion within my team.
thanks for any help in advance
Firstly, I'm quite new to PHP having only dived in some three weeks ago but loving it as a new thing to learn! I have a specific problem that I cannot seem to find a solution for via Google. I'm running a test page that will form the basis of a final product for a local recreational club that runs competitions and wants to display the results online on their website.
I've created a MySQL database and called it 'results' and imported as a CSV a sample of competition results. My code to connect to the database works as the page displays the "Database Connection Established" message.
The database contains a table called 'z_any_year_results' and the table structure looks like this:-
Record_Number Field Value
1 Field_1 Value_1
2 Field_2 Value_2
3 Field_3 Value_3
4 Field_4 Value_4
5 Field_5 Value_5
I understand how to select the specific table using
mysql_select_db("results") or die(mysql_error());
$data = mysql_query("SELECT z_any_year_results FROM results")
but I need to echo a specific field from the table in a specific section of the web page. So for example, in one section of the page I need to output the field containing the value Field_1 and nearby on the page the field containing the value Value_1. But in another section of the page I need to output the field with the value Field_4 and nearby on the page, the field containing the value Value_4. So I guess my problem is how to extract a specific piece of data from a table to the exclusion of all other records in the table and outout it as an echo on the web page. I cannot find anything on the web that is written in a simple step-by-stepway to help novices like myself understand.
Can anyone point me in the right direction on how to achieve this?
Many thanks in advance.
You are using a type of data design known as key/value design. In other words, each row has the name of a data item and its value. That's not an ideal sort of design for a beginner to use, because it makes for fairly intricate queries.
To answer your question, if you want a certain named field's value you use this query.
SELECT Value FROM z_any_year_results WHERE Name = 'Field4'
But, maybe you want a design that resembles your application's entities a little more closely.
You might have an entity, a table, called, contestant, another called contest, and another called prize.
contestant is a table with columns like contestant_id, surname, givenname, email etc
e.g. 1 , Ellison, Larry, larry#oracle.com
Then you can use queries like SELECT * FROM contest WHERE YEAR(datestart) = 2016 which will make your queries more closely reflect the logic of your application.
I've got a tree-algorithm and database problem I'd like to have an answer to.
I've got a few areas, let's say 20. Each of these areas have sub-areas ~ 20 each.
These parent areas are spread out on a map. Some of these parent areas are close to eachother.
The database looks like this: [area_id, title, parent_id] - Some has multiple children, there's a root node containing all areas. (The Adjacency List Model)
To make this in a picture I could do this:
The different areas as I said, can be close to eachother, (or far away). I'd like someway to tie let's say Area 1 and Area 5 together because I know they're close, and Area 1 is also close to Area 4. Now, here's the problem, let's say that Area 4 is also close to Area 5.
It would look like something like this:
Which makes it an infitite loop? because I want Area 1 to be close to Area 4, but also Area 4 is close to Area 1.
I'd like to do a search, where you can select "search nearby areas", so you select one area then you can search the nearby ones. I could use some tips, on how to solve this with a database and php.
I've been looking around on this forum for help but I don't really know the "name" of this problem, I'd be happy if someone could point me in the right direction or straight up help me out in thist thread.
Thanks guys, and if it's something else you need to know I'll try to answer as soon as possible.
For anything that is dealing with proximity, I would certainly take an approach of putting in either geospatial information (if these are true areas/regions) and then applying a radial search which can be done via any number of simple through to complex queries and calculations.
If these places are on the other hand fictional, it might be interesting to consider making a fake location - even if it a simple x,y coordinate system. This will allow you to perform radial searches again - which you can enlarge or shrink to your needs - or even simply order the results in ascending distance from site a to b.
To subdivide an area you need a rectangle that you can split along the axis. Look at kd-tree, r-tree, or quadtrees and spatial index. I can recommend you my php class Hilbert curve. It's a monster curve and fills completely the plane. You can find it at phpclasses.org.
I finally solved it using a kind of "neighboring" select statment.
I did this by creating another table which contains neighbor-relationships. That table looked like: [table_id, area_id, neighbor_area_id]
Here I added all the neighbors that are avaliable, with some INNER JOIN and select statment I managed to get out what I wanted, so a search can be done for all areas neighboring the selected one.
The sql-statment looked like this:
SELECT adds.title, categories.title, area.title
FROM adds
INNER JOIN categories ON categories.category_id = adds.category_id
INNER JOIN areas ON adds.area_id = areas.area_id
WHERE areas.area_id IN (SELECT area_neighbors.area_neighbor_id
FROM area_neighbors
WHERE area_id='25')
OR adds.area_id='25'
This would give me all adds in neighboring areas to area_id 25.
I cannot say if this is the smartest or best solution but it's one that works for me. Hope this helps someone! and thanks for all the replies!
i'm making a questionnaire about a service quality, its contains the options (poor, regular, good, very good). It's contains 6 questions (radio button) and a suggestion box (textbox).
In the table of the database i created 6 rows for questions, 1 for suggestion and 1 for date (a friend of mine tole me to use this but i didn't get why).
q1) I'm going to atribute a value form 1 to 4 to the radio buttons options, and i'd like to sum every answer for each question, and then divide by the numbers of user that answered that question and give the mean. how am i supposed to to that? I'd also like generate reports of the month, of the year.
q2) not only about the questionnaire but for registration too. I need all the fields to be completed, no blank options, if he don't complete all of fields it'll not be submitted and there will be a warning message to the user.
q3) about the field type, i'd like it to be the same class that is in the database, i'm having a "problem". Ex: Name(varchar) : 1234(int), in the field 'name' of the table of the database 1234 will be shown as name, and i don't want this, i want only the type that i declared in the construction of the table.
q4) i'd also like to know if it's possible to create pizza graphics, about the percentage of each question, is this possible?
q5) I'm using phpmyadmin and some of my id's are auto_increment, but 'cause of my tests they at a high number, i'd like to restart to 0 the ids number, is this possible?
Thanks for the attention.
To me this sounds like what you more need is a complete surveying package. This has been done before and there are many great paid and free options.
If you are attached to a php/mysql answer, a quick search finds this as a nice open source option.
http://www.limesurvey.org/