Laravel join two tables on Json Column - php

I have two tables(models), one with a json column that may contain the id on other table. I want to join these two together, how do i chain a laravel join to my query.

SO it turns out the join wasn't working because the json column was storing the id field as a string and the joined table's id is stored as an integer.
Casting the result into an integer fixed this. Let's say table 'a' is the first table that contains a json column with an id on second table which is table 'b'.So I did.
DB::table('a')->join('b','b.id',DB::Raw("CAST(a.data->'$.id' AS UNSIGNED)"))->get();

Apply the JSON logic inside the join query like:
Post::select('posts.id', 'posts.field1','posts.field2','samples.id as sample_id', ..)
->join('samples', 'posts.json_col_name.id', '=', 'samples.id')
->get();
Make sure that you make no conflict for the query builder while picking columns (use field_name as another_name) when both models have fields with common name.

Related

Moving data from 1 pair of table to another similar pair in Cakephp

I have 2 similar pairs of tables (Table1 and Table2, TableA and TableB).
Table1 has many Table2. Table2 belongs to Table1. In other words, there is a one-to-many relationship between Table1 and Table2. TableA and TableB has the same one-to-many relationship as Table1 and Table2.
I would like to move a row in Table1 plus all the associated rows in Table2 to the matching table pair TableA and TableB.
What is the best way to transfer the table row and the associated rows? Do I save each row to the new table one by one using save() or is there a way to save all the rows at one go using saveall()?
Is it a problem to use saveall() to do the data transfer if the table fields are similar but not exactly the same. Between the table pair, some rows are the same and some rows are different.
I am using Cakephp 2.4.5. Thank you for your help.
You'll need to use saveAssociated to solve this, but if your tables are not exactly the same then you will first need to transform your data into something manageable. Here is an example:
$table_1 = $this->Table_1->find('first', array('conditions => array('Table_1.whatever' => 'something')));
// here you can manually build the data you need to save.
$transfer_data['Table_A'] = $table_1['whatever you needed to change'];
You might need a for loop or something to convert your data to the slightly different version that you need for table a and b, but without knowing what the difference is there I cannot write the code that does the transformation. Once the transformation is complete you can just save your save as explained in the manual using saveAssociated.

PDO: fetchAll() with duplicate column name on JOIN

I have several table with similar column name in my database.
Let say TABLE 1, TABLE 2, TABLE 3 have a column named : "name". Those are not indexed columns. They contain different and independant data.
If I run a query joining these 3 tables and fetchAll() the results, there will be only one "name" entry in the resulting array since fetchAll() overwrite the column with the same name.
The regular MySQL Library let you access such results doing:
mysql_result($result,0,'TABLE1.name');
How can I let PDO append the table name before the column name like : TABLE1.name, TABLE2.name, etc.
I want to AVOID using alias in my SQL query since I have tons of tables. The only answers I found online uses alias. Is there any parameters we can feed to PDO to do what I am looking for?
You can use aliases instead of direct column names in your SELECT statement. Something like this:
SELECT
table1.name AS t1_name,
table2.name AS t2_name,
table3.name AS t3_name
-- rest of your query

Set column to automatically pull data from referenced table

I have one column called 'speeding' in a table containing many other columns. This column contains an integer that is foreign key to an entry on a table named Speeding. This table has columns 1-25 and an id that is referenced by the 'speeding' column from the first table.
Besides using join, is there any setting I can set on 'speeding' to make it automatically pull the associated data from the table Speeding?
You could create a view, a view is basically a SQL statement that is stored on the MySQL server and acts like a table
CREATE VIEW ViewName AS
SELECT tbl1.data, tbl2.speeding
FROM tbl1
INNER JOIN tbl2 ON tbl2.key = tbl1.key;
http://dev.mysql.com/doc/refman/5.0/en/create-view.html
You then use the view as you would use any table
SELECT data, speeding
FROM ViewName

creating a mysql table from a inner join

I'm trying to create a mysql table from the inner join between two other tables. I'm dealing with a database someone creates which has the following tables:
sitematrix_sites
sitematrix_databases
They are related by another table (I don't know why don't use a foreign key) called sitematrix_sites_databases which has the following fields:
site_id and database_id.
That's how the two tables relate. Now I'm trying to remove that to make my life easier, so I have:
mysql> CREATE TABLE result AS(select * from sitematrix_databases INNER JOIN site
matrix_site_databases ON sitematrix_site_databases.database_id = sitematrix_data
bases.database_id);
ERROR 1060 (42S21): Duplicate column name 'database_id'
However, I'm getting that error. Does someone know how can I merge the two tables without repeating the database_id field?
Thanks
Remove the * in your SELECT statement and actually list out the columns you want in your new table. For columns that appear in both original tables, name the table as well (e.g. sitematrix_databases.database_id).
Don't use * instead name each column and use aliases. For instance instead of sitematrix_database.database_id you can have alternativeName. Also you can pick and choose which columns you want this way as well.
In SQL Server, you can use "select into". This might be equivalent syntax for mySql:
http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-select-into-table.html
Unfortunately, it's a two commands (not just one):
http://www.tech-recipes.com/rx/1487/copy-an-existing-mysql-table-to-a-new-table/
CREATE TABLE recipes_new LIKE production.recipes; INSERT recipes_new SELECT * FROM production.recipes;
Instead of using SELECT * ... try SELECT database_id ...
MySQL does not like joining tables that have the same column name.

Mysql commaseparated column matching from another table

I would like to select all matches from a commaseparated column in table2, where column could be like this: 0,1,2 OR 2,4,5 OR 2,5 OR 1,3,5 etc.
I have tried with:
SELECT * from table where 1,3,5 IN(SELECT commaseparated FROM table2) WHERE ..
But error on statement when using commas.
I've also tried using REGEXP but in my case i need to search for all matches within 1,3,5
How can i solve this one? :)
Can't do that in standard SQL. it's
WHERE singlevalue IN (list, of, values)
if you want to compare lists against lists, you should revamp your tables so they're properly normalized. Storing formatted data in a field basically negates the purpose of having a relational database - you can't establish relationships with the data if it's not in a format that allows relationships to be formed.
If those CSV lists were in sub-tables, you could do a very simple JOIN query to meet your specifications.

Categories