Php associative array when joining tables with the same field names - php

I have this consult and I need the key names of the array I'm obtaining:
SELECT table_1.*, table_2.* FROM... INNER JOIN...
I checked other posts with similar titles and the solution is always to use an alias. This won't work for me because I have too many fields and it would be troublesome to write down every single one.
The problem is, of course, that the field names are the same in both tables.
It wouldn't be a problem if I could simply echo $arr["table_1.field_name"] but it doesn't work.
Yes, I could use the index, like $arr[0], $arr[1], $arr[2]. But if I change the table fields order or add new fields then I'll have to change it in the program and it does not seem like a proper solution either.
Thank you very much in advance.

Use AS to alias the second column. It's always the solution, because it IS the solution!
SELECT table1.mycolumn, table2.mycolumn AS table2column

Related

How to check if a DB array matches any values of a given array

I'm a little bit stuck.
I have an SQL column that contains weather codes (like Rain, Snow, etc.)
It is comma separated so the column would have a value of something like
rain,snow,haze
Now, I want to select the rows that contain values from an array.
I have an SQL code that is something like this:
SELECT * FROM locations WHERE currentWeather IN ('rain', 'snow', 'cloudy') ORDER BY name ASC
The problem is that this obviously works when currentWeather column only contains one item.
Is there a way to do it so that if the column value contains any of the items from the given array, it selects it?
Also, would it select it twice if two items match?
Best wishes
Use unnest in a subselect.
Select distinct A.myArray from (select unnest(column) as myArray from table) A where A.myArray in (your words to filter for)
Notice that using arrays in sql isn't very ideal and does not follows normalization rules. Your tables should ideally not contain arrays but rather just several rows each one containing the specific value you Want. It prevents issues such as this one.
To avoid the selection of repeated values, use the Distinct keyword right after you write select.
Rsference:
https://www.w3resource.com/PostgreSQL/postgresql_unnest-function.php
WHERE FIND_IN_SET(currentWeather, "rain,snow,cloudy")
Picks apart the string at commas (only) to see if currentWeather is any one of those 3 'words'.
See also FIELD(...)

SELECT DISTINCT is too slow, how do I use a PHP array instead?

I have a large database and even with indexes it's slowing down a lot when I use SELECT DISTINCT. I thought I'd change it to use an array instead but somehow it's not working. What am I doing wrong?
The original code is:
$product_countries = $this->query("SELECT DISTINCT country FROM db_products");
$listing_countries = array();
while ($listing_details = $this->fetch_array($product_countries)){
if (!empty($listing_details['country'])){
$listing_countries[] = $listing_details['country'];
}
}
Now, I tried changing it to:
// $product_countries = $this->query("SELECT DISTINCT country FROM db_products");
$product_countries = array("2084", "1993");
And the while part to:
while ($listing_details = $product_countries){
But that's not working. What am I doing wrong here? I'm pretty sure it's somewhere in that while line and the fact that the before it used a mySQL resource and then afterwards I changed it to an array, but I can't figure it out :(
Given:
$product_countries = array("2084", "1993");
There's no need for a while loop. Just get the contents of that array assigned to another array. Like this:
$product_countries = array("2084", "1993");
$listing_details = $product_countries;
And be done with it. (You already know that the values in the $product_countries array are already defined, and aren't going to evaluate to FALSE, so there's no need for any conditional test.
With the while loop as you show, how will that ever exit? Looks like a classic infinite loop to me.
If that's not the question you are asking...
As far as the MySQL query goes, the only appropriate index for the query would be a BTREE index (not a HASH index) with a leading column of country. Ideally (for this query) on just that single column:
... ON db_products(country)
The query should be equivalent to a GROUP BY query:
SELECT country FROM db_products GROUP BY country
I recommend you run an EXPLAIN on the query to verify that it's using an index and not doing a "Using filesort" operation. (This assumes that db_products is a table, and not some harebrained view definition.)
I'm not understanding why the conditional test on the return of the empty function is needed. If fetch_array returned a row, then variable is going to be defined, so that test really only checking if the value returned from the database evaluates to FALSE. If I wanted to exclude values of country that evaluate to FALSE, I would tend to include the appropriate predicate in the query definition.
First, this query:
SELECT DISTINCT country
FROM db_products
should be able to make good use of an index on db_products(country).
Second, you should have a separate table of countries, with db_products containing a countryId, referring to the other table. If you had that, then displaying the list of countries would be a no-brainer.
AS I stated in the comments, the better way to do this is have a list of countries in a separate table, and reference them in your product table.
This is called normalization, generally you should think of it like this. A product is a thing with certain attributes of which country is only one, it might have a price, or a SKU number for example..
Countries too are a thing, they may have abbreviations, shipping codes, laws that deal with this or that, many things. They are not as simple as say a SKU number or a price. But, could contain other useful data unrelated to a specific product, don't they deserve a table all their own?
It's hard to say the structure of this table or the relationship between a product and a country without knowing more. But, you may be able to eliminate a lot of redundant data. Ask yourself these two things:
Can a product have more then one country?
Can a country supply more then one product?
Those will tell you the relationship you need.

Laravel 4 Query groupBy: all columns from table

I have to call the $model->groupBy(?allcols?) function with all columns as a param.
How should I do this?
Edit: I have all Columns as an Array, so i can't pass them like 'col1','col2',...
I'm asking this because i have this poblem (github) and i found out, that there the prob is on Line 119.
I tried it manually like col1,col2 which worked, but it should by dynamically for all models.
I found this snippet, to get all cols from the current table as an array, but i can only pass a String.
Ok, if I'm understanding your edit correctly, you've got an array of column names you wish to group by. If $model is the name of your query, I'd recommend just using a foreach loop and appending each field:
foreach($allcols as $col){
$model->groupBy($col);
}
$model->get();
There is no such function for grouping all columns but you may use groupBy(col1, col2, ...), for example, if you have a posts table then you may use:
DB::table('posts')->groupBy('col1', 'col2')->get();
Or using Eloquent Model, for example a Post model:
Post::groupBy('col1', 'col2')->get();
If all you're trying to do is get rid of duplicate records (which is all that groupBy(all) would do as far as I can envision), you could also just use $model->distinct() instead. However, unless you add a select() to exclude the id field, you're going to wind up with the full recordset with no grouping, as by definition the id is unique to each record and thus won't collapse across records by either manner.

Automatically get columns names in form: name_of_table.name_of_row

I want to obtain data from several tables in database using join. Tables contains rows with equal names. Is it possible automatically get columns names in form: name_of_table.name_of_column?
For example instead of Select using table1.column as t1col from... write only Select * from...?
Not possible. You have to explicitily ask for the fields by assigning aliases, this way: ... name_of_table.field1 as name_of_table_field1, name_of_table.field2 as name_of_table_field2 ...
I researched this same question myself weeks ago and finally adopted this solution.

Search for column format

This is a bit of a difficult problem for me to word, and I may be going about it in the completely wrong way.
I'm storing a set of options in a database, where each option is its own column. The user can change the number of options, however, so I need a way of allowing PHP to always select all the options.
Let's say I have these columns: options_dialog_1, options_dialog_2, options_dialog_3, options_dialog_4
There could be a varying number of these dialog option columns, eg, another called options_dialog_5 could be added.
How do I select all the dialog option columns, based on their column name format?
I think you have a database design problem here; repeating columns like that always leads to trouble in the end. I think you need two tables, one for the user and one for the options defined something like this...
USERS
id
name
OPTIONS
id
user_id
option_dialogue_number
option_dialogue_value
That turns the columns into rows, which are rather easier to get at.
Brian's answer will really, really pay you off in longer period. But if you need something quick & ugly, you can check out the "metadata dictionary" (tables that store information about all other tables, columns etc). You could get list of columns from it with first query and use it to build the second one.
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='mytable' AND COLUMN_NAME LIKE 'options_dialog%'
Visit the manual on INFORMATION_SCHEMA for more goodies.
I am not sure I understand the problem. Are you looking for
SELECT * FROM options_table
Something like (faux SQL - wont work)
SELECT ( SELECT column_names where column_name LIKE 'options_dialog%' )
FROM options_table
sounds not feasible to me (though I am sure it's possible somehow). If you need this, either consider refactoring the database design or maybe use a bitmask to store the selected options in a single column.

Categories