Need support with mySQL PDO JOIN statements - mysql

I need an SELECT with JOIN but have at this moment no idea how to do this. I read already a few tutorials but it does not help me with my problem.
I have 2 tables in 2 databases:
DATABASE A
-> CONTENT
--> | PARTNERID | PAYSITE |
--> | 1 | siteA.com |
--> | 2 | siteA.com |
--> | 3 | siteA.com |
--> | 3 | siteB.com |
DATABASE B
-> WMIDPP
--> | WMID | PARTNERID | PARTNERURL | PAYSITE | ACTIVE
--> | 1 | 1 | AFFLINK 1 | siteA.com | 1
--> | 1 | 2 | AFFLINK 2 | siteA.com | 1
--> | 2 | 1 | AFFLINK 1 | siteA.com | 1
The above tables contains more fields, but with these fields I need to work with.
I know already the variables $WMID and $PAYSITE if I enter the website. When I enter the website, it should be show only the following data:
The complete data from table CONTENT and the field PARTNERURL from table WMIDPP when
CONTENT.PARTNERID = WMIDPP.PARTNERID
and
WMIDPP.WMID = $WMID
and
WMIDPP.PAYISTE = $PAYSITE
but only if
WMIDPP.ACTIVE = 1
Can anybody help with my problem?
Thanks in advance
Torsten
EDIT:
Here a little bit more information about the databases and tables:
Table CONTENT is located in DATABASE A and table WMIDPP is located in DATABASE B.
I access to these databases like this:
$DB_HOST = "localhost";
$DB_NAME1 = "database1";
$DB_NAME2 = "database2";
$DB_USER = "username";
$DB_PASS = "password";
$OPTION = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8");
try {
$dbAS = new PDO("mysql:host=" . $DB_HOST . ";dbname=" . $DB_NAME1, $DB_USER, $DB_PASS, $OPTION);
$dbEC = new PDO("mysql:host=" . $DB_HOST . ";dbname=" . $DB_NAME2, $DB_USER, $DB_PASS, $OPTION);
}
catch (PDOException $e) { exit("Verbindung fehlgeschlagen! " . $e->getMessage()); }
User has permissions to access to both databases.
I have 2 different databases, because there are 2 different projects. If it not work with these configuration, I can move the table(s) from DATABASE B to DATABASE A - but this should only the worst case option. I prefer a solution to merge the data of the tables in 2 different databases.

You use One PDO connection.
The signon details must allow access to both databases you want to access.
The full 'path' to any column is:
<database name> . <table name> . <column name>.
Here is tested code that joins tables from two separate databases.
Database 1) is called: 'testmysql'
Database 2) is called: 'rags1'
They are just databases i have setup here with similar structured tables on them.
Join two tables from separate databases
/* --------------------------------------------------------------------
* Query testmysql and rags1
*/
$sqlTest = 'SELECT rags1.user.id as RagsRowId,
rags1.user.userid as RagsUserId,
testmysql.customer.id as TestRowId,
testmysql.customer.custid as TestCustId,
testmysql.customer.address as TestCustAddress
FROM testmysql.customer
JOIN rags1.user
ON testmysql.customer.custid = rags1.user.userid
AND testmysql.customer.custid = :testCustId';
$stmt = $dbTest->prepare($sqlTest);
$stmt->bindValue(':testCustId', 'rfv123', PDO::PARAM_STR);
$stmt->execute();
$testResult = $stmt->fetchAll();
$stmt->closeCursor();
echo '<pre>';
print_r($testResult);
echo '<pre>';
Connection Details:
/**
* Two databases :
* 1) testmysql
* 2) rags1
*
* Use the 'database' name that you want to refer to in the queries.
*/
/**
* must have access rights to both db's
*/
// db connection to TestMysql and Rags1
$dsn = 'mysql:host=localhost;dbname=testmysql';
$username = 'rfv123';
$password = 'rfv123';
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$dbTest = new PDO($dsn, $username, $password, $options);
$dbTest->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Output:
Array
(
[0] => Array
(
[RagsRowId] => 1
[0] => 1
[RagsUserId] => rfv123
[1] => rfv123
[TestRowId] => 3
[2] => 3
[TestCustId] => rfv123
[3] => rfv123
[TestCustAddress] => 123 Somewhere Street, Cheshire
[4] => 123 Somewhere Street, Cheshire
)
)

Related

How to get data of joined table using query() method

I have an issue with getting data of the joined table if I use query().
I did not get the data of product table, how can I solve this using query() without using Active record?
Here is my db table structure
category table
+--------------------------+
| cId | added | category |
+-----+--------+-----------+
| 1 | 1.2.20 | PC |
| 2 | 1.7.20 | electron |
+-----+--------+-----------+
product table
+--------------------------+
| id | cId | cost |
+-----+--------+-----------+
| 1 | 1 | 3000 |
| 1 | 2 | 9000 |
+-----+--------+-----------+
My Model
protected $table = 'category';
public function showProduct()
{
$sql = "SELECT
category.*, COALESCE(SUM(product.cost),0) as price
FROM category
JOIN product
ON product.cId = category.cId
GROUP BY category.cId
";
$this->db->query($sql);
return $this;
}
My Controller
public function index()
{
$result = $this->model->showProduct();
echo "<pre>";
print_r($result->asObject()->paginate(1));
//pagination
$pager = $this->model->showProduct()->pager->links();
}
Result I get
Array
(
[0] => stdClass Object
(
[cId] => 1
[added] => 1.2.20
[category] => PC
)
[1] => stdClass Object
(
[cId] => 2
[added] => 1.7.20
[category] => electron
),
)
You are requested to run this code.
SELECT category.cId,category.added,category.category,product.id,COALESCE(SUM(product.cost),0) as price
FROM category,product
WHERE category.cId=product.cId
GROUP BY category.cId;
If you are using CodeIgniter-4 then you can easily write this using Query Builder Class.
$sql="SELECT category*,product* FROM category INNER JOIN product.cid=category.id WHERE category.id";
I found solution to this by setting this table property within a function.
Model
$protected $table = array("default bd table here");
public function showProduct()
{
$this->table = array('category');
$sql = "SELECT
category.*, COALESCE(SUM(product.cost),0) as price
FROM category
JOIN product
ON product.cId = category.cId
GROUP BY category.cId
";
$this->db->query($sql);
return $this;
}
My Controller
public function index()
{
$result = $this->model->showProduct();
//pagination
$pager = $this->model->showProduct()->pager->links();
}

Mysql Nested and declare as array

I have 2 table that want to call in and make another array from it.
The first table is groups
| id | name | type |
1 premium pr
2 basic bs
The second table is sub-groups
| id | group_id | name |
1 1 forever
2 2 short
Actually I want to show the code like this. To have another array function declare as sub-groups
Array (
[id] => 1
[name] => Premium
[type] => pr
)[sub-groups] => Array (
[0] => Array (
[id] => 1
[group_id] => 1
[name] => forever))
I created this PDO sql connection
=================EDITED CODE====================
function getGroups(){
global $conn;
$stmt = $conn->prepare("SELECT * FROM groups");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$groups = $stmt->fetchAll();
foreach($groups as $key => $val){
$stmt = $conn->prepare("SELECT * FROM sub_groups WHERE group_id = {$val['id']}");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$program = $stmt->fetchAll();
foreach($program as $key => $val){
$groups['sub-groups'] = $program;
}
}
return $groups;
}
The code successfully show the groups Premium and Basic, But it's not showing the sub-groups inside the main groups. Did I miss something?
Anyone with help will be nice.
Array keys have to be unique. If you have two columns with the same name, only one of them can appear in the resulting associative array for the rows.
You need to assign an alias to at least one of the columns with the same name so it will show up differently in the results.
SELECT g.name as group_name, sg.group_id, sg.id AS subgroup_id, sg.name AS subgroup_name
FROM groups AS g
LEFT JOIN subgroups AS sg ON sg.group_id = g.id
When you're creating the PHP result, $groups['sub-groups'] needs to be an array. You're overwriting it with a single element each time through the loop.
<?php
function getGroups(){
global $conn;
$groups = [];
$stmt = $conn->prepare("
SELECT g.name as group_name, sg.group_id, sg.id AS subgroup_id, sg.name AS subgroup_name
FROM groups AS g
LEFT JOIN subgroups AS sg ON sg.group_id = g.id");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($row = $stmt->fetch()){
if (!isset($groups[$row['group_name']])) {
$groups[$row['group_name']] = $row;
$groups[$row['group_name']]['sub-groups'] = [$row['subgroup_name']];
} else {
$groups[$row['group_name']]['sub-groups'][] = $row['subgroup_name'];
}
}
return $groups;
}

Perl read from xls insert to mysql

I'm am pretty new to Perl and I'm writing a Perl script to read data from xls and insert the results to MySQL DB but i have problem...
here is my code:
#!/usr/local/bin/perl
use strict;
use warnings;
use diagnostics;
use Spreadsheet::ParseExcel;
use DBI;
use Data::Dumper qw(Dumper);
my $parser = Spreadsheet::ParseExcel->new();
my $workbook = $parser->parse('test.xls');
my $dbh = DBI->connect("dbi:mysql:parser", "root", "123qwe", { RaiseError => 1}) or die $DBI::errstr;
my $query = 'INSERT INTO parser (Name,Country) VALUES (?,?)';
my $sth = $dbh->prepare($query) or die "Prepare failed: " . $dbh->errstr();
if ( !defined $workbook ) {
die $parser->error(), ".\n";
}
for my $worksheet ( $workbook->worksheets() ) {
my ( $row_min, $row_max ) = $worksheet->row_range();
my ( $col_min, $col_max ) = $worksheet->col_range();
for my $row ( $row_min .. $row_max ) {
for my $col ( $col_min .. $col_max ) {
my $cell = $worksheet->get_cell( $row, $col );
next unless $cell;
my $results = $cell->value();
open(my $fh, '>>', "test");
print $fh "$results\t";
close $fh;
}
}
}
open my $fh, "<", "test" or die $!;
while (<$fh>)
{
chomp;
my #vals = split;
$sth->execute(#vals);
}
close $fh;
So when i execute the script it ends with the following error:
DBD::mysql::st execute failed: called with 6 bind variables when 2 are needed at ./parser.pl line 39, <$fh> line 1.
Uncaught exception from user code:
DBD::mysql::st execute failed: called with 6 bind variables when 2 are needed at ./parser.pl line 39, <$fh> line 1.
Which is natural because i have indeed 6 variables in the output:
John Smith USA Ognyan Penkov Egypt
So the problem is that i cant seem to find a way to split the results from every column/row and put them in the MySQL tables because the Spreadsheet::ParseExcel reads all the date as 1 row.(For example the names must go to table Name and the country to table country)
My XLS file looks like this:
A B
1. John Smith USA
2. Ognyan Penkov Egypt
...etc...
My MySQL tables:
+--------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+----------------+
| id | int(6) | NO | PRI | NULL | auto_increment |
| Name | varchar(255) | YES | | NULL | |
|Country | varchar(255) | YES | | NULL | |
+--------+--------------+------+-----+---------+----------------+
You are opening a file called test for append writing for every single cell in the document. You then add the current cell's value, followed by a tabulator \t character. Afterwards you open and read that same file line by line (but there is only one line), chomp off a line ending that is not there (because you didn't put one) and split on whitespace, because split without a delimiter uses \s, which is a single whitespace.
If omitted, PATTERN defaults to a single space, " " , triggering the previously described awk emulation.
And that's exactly the problem, because your file looks like this:
John\tSmith\tUSA\tOgnyan\tPenkov\tEgypt
The \t are single whitespaces, so you end up with #val being all of those. And if you pass that to your query, it fails.
Since you do not, as you say, have a table for names and a table for countries, but instead all you do is put the data from the Excel file into a single MySQL table row by row, you can just do that in your $row loop.
for my $worksheet ( $workbook->worksheets() ) {
my ( $row_min, $row_max ) = $worksheet->row_range();
my ( $col_min, $col_max ) = $worksheet->col_range();
for my $row ( $row_min .. $row_max ) {
my #values;
for my $col ( $col_min .. $col_max ) {
my $cell = $worksheet->get_cell( $row, $col );
next unless $cell;
push #values, $cell->value();
}
$sth->execute(#values) or die $dbh->errstr;
}
}

I a, getting error - Warning: mysql_fetch_assoc() expects parameter 1 to be resource

Here is the code.........
<?php
include('../inc/php/inc/dbc.php');
$query = "SELECT * FROM available_fsv WHERE a_status = '1'";
$result_query = mysql_query($query);
while($row = mysql_fetch_assoc($result_query)){
$billingid = $row['billingid'];
$query = "UPDATE available_fsv SET b_status = '1' WHERE billingid = '$billingid'";
$result_query = mysql_query($query);
echo $result_query;
}
?>
The error i am getting...........
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in C:\wamp\www\php\fsv_shutdown_cron.php on line 6
Database structure is like--
____________________________________________________
| id | a_status | b_status | billingid |
|--------|------------|-------------|--------------|
| 1 | 1 | 0 | 1 |
|--------|------------|-------------|--------------|
| 2 | 0 | 0 | 12 |
|--------|------------|-------------|--------------|
| 3 | 0 | 0 | 9 |
|--------|------------|-------------|--------------|
| 4 | 1 | 0 | 3 |
|________|____________|_____________|______________|
What i wanna do is if a_status is 1 then update b_status to 1.
I am learning php and I know this is a stupid question but please help me. Thanks in advance.. :)
you mess up the $query and $result_query, they appeared twice in the code
error is on the while($row = mysql_fetch_assoc($result_query)){ line.. here your $result_query is nothing but the response of your update query..
try this :
<?php
include('../inc/php/inc/dbc.php');
$query = "SELECT * FROM available_fsv WHERE a_status = '1'";
$result_query = mysql_query($query);
while($row = mysql_fetch_assoc($result_query)){
$billingid = $row['billingid'];
$update_query = "UPDATE available_fsv SET b_status = '1' WHERE billingid = '$billingid'";
$update_result_query = mysql_query($update_query);
echo $update_result_query;
echo "<br />";
}
?>
This call mysql_query($query) returned FALSE, instead of result set, which means that your query had errors in it. Use the following code to see the error:
$result_query = mysql_query ($query);
if ($result_query === FALSE)
{
echo (mysql_error ());
die (1);
}
Looks like I was wrong. You really overwrite original value of $result_query when you execute your update query.
you can directly update using inline IF
UPDATE tableName
SET b_status = IF(a_status = 1, 1 , b_status )
if you are executing this, you don't need to communicate on the database twice.

Sphinx Mysql query problem

source logs
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass =
sql_db = bot
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = SELECT * FROM logs
sql_attr_uint = host
sql_query_info = SELECT * FROM logs WHERE id=$id
}
index logs
{
source = logs
path = D:\Webserver/Sphinx/index/logs
morphology = stem_ru, stem_en
min_word_len = 1
charset_type = utf-8
}
searchd
{
listen = 9312
log = D:\Webserver/Sphinx/log/searchd.log
query_log = D:\Webserver/Sphinx/log/query.log
pid_file = D:\Webserver/Sphinx/log/searchd.pid
}
My database:
ID | HOST | POST | URL
1 | yahoo.com | *js3s7Hs56 | http://yahoo.com
2 | google.com | 7sf6jsg73 | http://google.com/?asfaa=23
PHP Code Sphinx (search)
<?php
include('sphinxapi.php');
$cl = new SphinxClient();
$cl->SetServer( "localhost", 9312 );
$cl->SetMatchMode( SPH_MATCH_ANY );
$result = $cl->Query("google");
if ( $result === false )
{
echo "Query failed: " . $cl->GetLastError() . ".\n";
}
else
{
print_r($result);
}
This code is returned :
2
As now I'm using sphinx to withdraw all data id 2??
Sorry for bad english
You can now take that ID returned in $result and query your database with it.
Something like:
<?php
foreach ($result['IDs'] as $ID) {
$r = mysqli_query('SELECT * FROM `table` WHERE `ID` = ' . $ID);
# Handle $r
}
# Or, more efficiently (depending on how many results you have):
$IDs = implode(',',array_map('intval',$result['IDs']));
$r = mysqli_query('SELECT * FROM `table` WHERE `ID` IN (' . $IDs . ')');
# Handle $r