Insert multiple rows into DB by only clicking one submit button - php

I've got a little problem i hope you're able to help me fix.
First of all my DB table that is involved look like this:
+---------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| KlubID | varchar(11) | NO | | 0 | |
| Medlemsnummer | varchar(11) | NO | | 0 | |
| KlubType | varchar(128) | NO | | | |
| Handling | varchar(128) | NO | | | |
| Tidspunkt | timestamp | NO | | CURRENT_TIMESTAMP | |
+---------------+--------------+------+-----+-------------------+----------------+
Say i got X entries where "Handling" equals Y in my table lets call the results P . Now I would like to take all P and insert a row foreach P where the value of "Handling" now will be equal to Q.
The problem here is that I want to do the insert with one button (submit) not multiple forms.
In advance thank you very much for your help. Feel free to ask for more info if this needs more clarity.
/Nicki
EDIT: For more clarity
public static function find_todays_children() {
global $db;
$sql = "SELECT *
FROM (
SELECT *
FROM Handlinger
AS a
WHERE date(Tidspunkt) = curdate()
AND Tidspunkt = (
SELECT max(Tidspunkt)
FROM Handlinger
AS b
WHERE a.Medlemsnummer = b.Medlemsnummer
)
)
AS c
ORDER BY handling DESC, medlemsnummer";
return static::find_by_sql($sql);
}
This query above returns the following.
+------+--------+---------------+----------+----------+---------------------+
| id | KlubID | Medlemsnummer | KlubType | Handling | Tidspunkt |
+------+--------+---------------+----------+----------+---------------------+
| 5786 | 0 | 1 | FK | Kommet | 2010-10-06 13:48:06 |
| 5787 | 0 | 2 | FK | Kommet | 2010-10-06 13:48:10 |
| 5789 | 0 | 4 | FK | Kommet | 2010-10-06 13:48:16 |
| 5790 | 0 | 3 | FK | G?et | 2010-10-06 13:48:27 |
+------+--------+---------------+----------+----------+---------------------+
I then want to be able to insert 3 rows where the field "Handling" is another value.
I can do this by HTML form with PHP but I can't figure out how to do it all by only clickin once...
The important thing is that not to insert anything where the latest entry for a specific "Medlemsnummer" (user_id) is already equal to the value "Gået"
My form looks like this:
...
if(isset($action->Handling) != "Kommet") {
$do_action = "Kommet";
} else {
$do_action = "Gået";
}
...
<section>
<form action="phineaslog_barn.php" method="post">
<label for="Status">Klub Navn: </label>
<input type="text" name="Medlemsnummer" value="<?php echo $child->Medlemsnummer; ?>" />
<input type="text" name="Handling" value="<?php echo $do_action; ?>" />
<input type="submit" name="submit" value="<?php echo $do_action; ?>" />
</form>
</section>

My understanding of the question:
For each row which is the final entry for a user, where handling = kommet
Insert another row with handling = gået, tidspunkt = now()
So... to combine the best of two worlds...
INSERT INTO tablename (KlubID,Medlemsnummer,KlubType,Handling,Tidspunkt)
SELECT KlubID,Medlemsnummer,KlubType,'Gået',NOW()
FROM Handlinger
AS a
WHERE date(Tidspunkt) = curdate()
AND Handling = 'Kommet'
AND Tidspunkt = (
SELECT max(Tidspunkt)
FROM Handlinger
AS b
WHERE a.Medlemsnummer = b.Medlemsnummer
)

In essence, you want to run this query?
INSERT INTO tablename (KlubID,Medlemsnummer,KlubType,Handling,Tidspunkt)
SELECT KlubID,Medlemsnummer,KlubType,'Gået',NOW()
FROM tablename
WHERE Handling = 'Kommet';
Or, more in PHP:
$from = $_POST['Handling'] == 'Kommet' ? 'Kommet' : 'Gået';
$to = $from == 'Kommet' ? 'Gået' :'Kommet';
mysql_query("
INSERT INTO tablename (KlubID,Medlemsnummer,KlubType,Handling,Tidspunkt)
SELECT t1.KlubID,t1.Medlemsnummer,t1.KlubType,'$to',NOW()
FROM tablename t1
LEFT JOIN tablename t2
ON t1.Medlemsnummer = t2.Medlemsnummer
AND t2.Tidspunkt > t1.Tidspunkt
WHERE DATE(t1.Tidspunkt) = CURDATE() AND t1.Handling = '$from' AND t2.id IS NULL");
Or are there more restrictions on which rows you'd like to insert besides Handling?

You could do something like this:
Write a Method to return a DataTable
Ex:
private DataTable pResutls()
{
do your select handling=Y;
return DataTableWithResult;
}
in your button click event
DataTable p = pResutls();
foreach(DataRow row in p)
{
if (row["Handling"].toSring()=='Q')
{
then insert this row (write your method to insert)
}
}
By this way you will need a method to get the Results (handling=='y')
A method that insert a row (you could pass a DataRow as parameter and perform the update from there)
And then from your Button you can do everything in one single Click like above.

Related

Optimization of SQL with subquery and Having

Currently we are using a custom CI library to generate PDF files from documents which exist as database records in our database.
Each document is related to the contents (== rows) with a one-has-many relation. Each row has a number (field: row_span) to indicate how many lines it will use once it gets printed in the PDF.
Per PDF page that gets build, Rows needed for that page only are selected using a subquery:
$where = $this->docType."_id = ".$this->data['doc']->id." AND visible = 1";
$sql = "SELECT *,
(SELECT
sum(row_span) FROM app_".$this->docType."_rows X
WHERE X.position <= O.position
AND ".$where."
ORDER BY position ASC) 'span_total'
FROM app_".$this->docType."_rows O
WHERE ".$where."
HAVING span_total > ".(($i-1)*$this->maxRows)." AND span_total <= ".($i*$this->maxRows)." ORDER BY O.position ASC ";
$rows = $rows->query($sql);
In the code $i is the page number and $this->maxRows is loaded from the document template record which indicates how many available lines the PDF template has.
So when the SQL renders it might look like this for page 1 of an order with ID 834:
SELECT `app_order_rows`.*,
(SELECT SUM(`app_order_rows_subquery`.`row_span`) AS row_span
FROM `app_order_rows` `app_order_rows_subquery`
WHERE `app_order_rows_subquery`.`position` <= 'app_order_rows.position'
AND `app_order_rows_subquery`.`order_id` = 834
AND `app_order_rows_subquery`.`visible` = 1
ORDER BY `app_order_rows_subquery`.`position` asc) AS span_total
FROM (`app_order_rows`)
WHERE `app_order_rows`.`order_id` = 834
AND `app_order_rows`.`visible` = 1
HAVING span_total > 0
AND span_total <= 45
ORDER BY `app_order_rows`.`position` asc
And running this with EXPLAIN gives this as output:
+====+=============+=========================+======+===============+======+=========+======+======+=============================+===+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | |
+====+=============+=========================+======+===============+======+=========+======+======+=============================+===+
| 1 | PRIMARY | app_order_rows | ALL | NULL | NULL | NULL | NULL | 1809 | Using where; Using filesort | 1 |
+----+-------------+-------------------------+------+---------------+------+---------+------+------+-----------------------------+---+
| 2 | SUBQUERY | app_order_rows_subquery | ALL | NULL | NULL | NULL | NULL | 1809 | Using where | 2 |
+====+=============+=========================+======+===============+======+=========+======+======+=============================+===+
This is working great, but... When we have large orders or invoices it renders the documents very slow. This might be due to the subquery.
Does anyone have an idea on how to do the same select without subquery? Maybe we will have to go for a whole new approach to select rows and build the PDF. We are open for suggestions ^^
Thanks in advance
------------------------------- edit ------------------------------
The EXPLAIN after index creation:
+====+=============+=========================+=======+===============+============+=========+=======+======+=============+===+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | |
+====+=============+=========================+=======+===============+============+=========+=======+======+=============+===+
| 1 | PRIMARY | app_order_rows | ref | index_main | index_main | 5 | const | 9 | Using where | 1 |
+----+-------------+-------------------------+-------+---------------+------------+---------+-------+------+-------------+---+
| 2 | SUBQUERY | app_order_rows_subquery | range | index_main | index_main | 10 | NULL | 1 | Using where | 2 |
+====+=============+=========================+=======+===============+============+=========+=======+======+=============+===+
As you confirmed in the comments, the tables have no indexes.
The immediate solution would be:
create index index_main on app_order_rows (order_id, position);

Inserting value in one column from another table mysql

school
+-----+-----------+----------+
| id | the_photo | column3 |
+-----+-----------+----------+
| 11 | NULL | abc |
| 22 | NULL | asf |
| 33 | NULL | asag |
+-----+-----------+----------+
school_images
+-----+-----------+-------+
| id | school_id | photo |
+-----+-----------+-------+
| 1 | 11 | 1 |
| 2 | 22 | 0 |
| 3 | 33 | 1 |
+-----+-----------+-------+
...
Need to insert values into the_photo column of school only if photo value = 1 for school_images like this:
School
+-----+-----------+
| id | the_photo |
+-----+-----------+
| 11 | 1 |
| 22 | NULL |
| 33 | 3 |
+-----+-----------+
Is there a simple query that can be written to do this for all rows? For one row i know how to insert it but how can i auto inert for multiple rows.
This might be what you're looking for: SELECT INTO.
Taken from the link:
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_temp1.fld_order_id
FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
BEWARE!! This answer is good only if you want to perform the above requested action upon a new insertion. Otherwise, you will need a different strategy
you should have something like this:
Select all you values from school_images then foreach them:
foreach($result as $res) {
if($res['photo'] == 1) {
// see step 2
} else {
// see step 3
}
}
if you have the value 1 in school_photos then:
INSERT INTO school (the_photo, colum3) VALUES ($res['id'], $some_value)
if you don't have it, then perform a normal insert like you did by now.
You can also use inner join to achieve that.
Update School inner join school_images on School.id = school_images.school_id and photo=1
set the_photo = school_images.id ;
You should use an INNER JOIN to join school with school_images:
UPDATE
school INNER JOIN school_images
ON school.id = school_images.school_id
AND school_images.photo=1
SET
school.the_photo=school_images.id
UPDATE school AS s, school_images AS si SET s.the_photo = si.id WHERE s.id = si.school_id AND si.photo = 1;

load posts from each friend

I'm currently working on a "news feed" type of script and I am trying to load the posts created by the user's friends. My current code partially works; it only loads from one friend and finishes. What am I doing wrong?
<?php
$infofriends = mysql_fetch_array(mysql_query("SELECT * FROM btfriend WHERE `user_id`='".$infousr['auto']."'"));
$infofrnd = mysql_fetch_array(mysql_query("SELECT * FROM btaccs WHERE `auto`='".$infofriends['friend_id']."'"));
$posts = mysql_query("SELECT * FROM btpost WHERE `user`='".$infofrnd['user']."' ORDER BY `auto` DESC") or die('Error: '.mysql_error());
while($row = mysql_fetch_array( $posts )) {
$infobeer = mysql_fetch_array(mysql_query("SELECT * FROM btbeer WHERE `beer`='".$row['beer']."'"));
$infouser = mysql_fetch_array(mysql_query("SELECT * FROM btaccs WHERE `user`='".$row['user']."'"));
....
(Currently sloppy, I'll be editing that afterwards).
MySQL structures:
btfriend
mysql> DESCRIBE btfriend;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| auto | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | YES | | NULL | |
| friend_id | int(11) | YES | | NULL | |
+-----------+---------+------+-----+---------+----------------+
btaccs
mysql> DESCRIBE btaccs;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| auto | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(150) | YES | | NULL | |
| display | varchar(150) | YES | | NULL | |
| pass | varchar(250) | YES | | NULL | |
| email | varchar(150) | YES | | NULL | |
| firstname | varchar(150) | YES | | NULL | |
| lastname | varchar(150) | YES | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
btpost
mysql> DESCRIBE btpost;
+---------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------+------+-----+---------+----------------+
| auto | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(500) | YES | | NULL | |
| beer | varchar(911) | YES | | NULL | |
| img | varchar(30) | YES | | NULL | |
| rate | varchar(10) | YES | | NULL | |
| loc | varchar(1000) | YES | | NULL | |
| comment | varchar(1500) | YES | | NULL | |
| fb | varchar(10) | YES | | NULL | |
| type | int(2) | YES | | NULL | |
+---------+---------------+------+-----+---------+----------------+
It'd be great if someone could help!
First of all, you're using mysql_* functions; those have been deprecated, and will stop working at some point in the future. Look at switching to mysqli_ or PDO instead - they both make it easier to write safer code.
Secondly, you're calling your code in such a way that you're expecting it to work:
$infofriends = mysql_fetch_array(mysql_query("SELECT * FROM btfriend WHERE `user_id`='".$infousr['auto']."'"));
If the query fails, you'll be passing a boolean false to mysql_fetch_array; it's a lot easier to make each statement one at a time, and handle errors as they come up:
$friendset = mysql_query("SELECT * FROM btfriend WHERE `user_id`='".$infousr['auto']."'") or die (mysql_error());
$infofriends = mysql_fetch_array($friendset) or die (mysql_error());
That will generate an error on the appropriate line if something goes wrong - it's a little more code, but it's much easier to debug and maintain.
Finally, your actual question; you're only getting one friend, because you're only calling mysql_fetch_array() once on the friend query; that will return to the top row. A quick solution would be to loop through the results separately to generate a list, and then pass that into the second query:
$friendset = mysql_query("SELECT * FROM btfriend WHERE `user_id`='".$infousr['auto']."'") or die (mysql_error());
$friendArray = array();
while ($infofriends = mysql_fetch_array($friendset)) {
$friendArray[] = $infofriends['friend_id'];
}
$friendArray[] = $infousr['auto'];
// At this point, you have an array of friend IDs.
$posts = mysql_query("SELECT * FROM btpost INNER JOIN btaccs ON btpost.user=btaccs.user WHERE btaccs.auto IN (" . implode(',', $friendArray) . ") ORDER BY btpost.auto DESC") or die('Error: '.mysql_error());
Note that it's using an IN to retrieve all the IDs at once; you might want to add an extra parameter to the ORDER BY to arrange the posts by friend.
Note that I've not tested this, so there may be issues with the syntax, but I hope it's enough for you to get the general idea.
--
We solved this in the chat and have added $friendArray[] = $infousr['auto']; which would also include the posts from the current user. The current user's ID, along with the friend IDs, would then go into the implode function in the query. We also linked the btpost and btaccs tables because btaccs held the user's ID, while btpost held the username. Full chat transcript -alexpja
Try this with using single query with join
SELECT p.*
FROM btpost p
INNER JOIN btfriend f ON (p.`user` = f.friend_id)
WHERE f.user_id =$infousr['auto']
Then loop through all the results from query,this will give you all the posts where btpost's user is equal to the friend's id btfriend and these are the friends of your given user id $infousr['auto'] I assume $infousr['auto'] will have the user id
I think you're missing a loop. Let's break down your code:
<?php
// Here, you run a query that presumably returns multiple rows, but you're only looking at the first row:
$infofriends = mysql_fetch_array(mysql_query("SELECT * FROM btfriend WHERE `user_id`='".$infousr['auto']."'"));
// That gave you a single array of the first friend that MySQL found
// Now, you take the `friend_id` field from that single result, and you run it against the `btaccs` table to get some more information:
$infofrnd = mysql_fetch_array(mysql_query("SELECT * FROM btaccs WHERE `auto`='".$infofriends['friend_id']."'"));
// Once again, you have a single row at this point. (Although here, I'm assuming that's ok, since a user's ID probably appears only once in this table
// Now, you take the single user that you've looked up, and you find posts associated with that user:
$posts = mysql_query("SELECT * FROM btpost WHERE `user`='".$infofrnd['user']."' ORDER BY `auto` DESC") or die('Error: '.mysql_error());
I think you can see that it's the first statement that limits it to a single user. Try creating an array before running that statement, and then looping through your result set, adding to that array.
A few other things I'd seriously consider:
1) Take advantage of PHP's double-quote string substitution...
mysql_query("SELECT * FROM btfriend WHERE `user_id`='{$infousr['auto']}'"
is a little easier to read than
mysql_query("SELECT * FROM btfriend WHERE `user_id`='".$infousr['auto']."'"
2) Read up on JOINs in MySQL. Everything you've done here can actually be collapsed into a single query in MySQL. It'd be a little too much to go into detail here, but you can start with the MySQL docs: http://dev.mysql.com/doc/refman/5.0/en/join.html

How to fetch field type and value?

I am currently trying to build a form using mysql/php, below is part of the code I have so far
BLOCK#1:
$proceso = mysqli_fetch_assoc($result); // my query returns only one row
...
<form action='actualizar.php' method='Post'>
<?php
foreach(array_keys($proceso) as $key){
echo "<label for='$key'>$key: </label>";
echo "<input name='$key' value='".$proceso[$key]."'><br/>";
}
echo "<input type='hidden' name='View' value='$view'>";
?>
<input type="submit" value="Actualizar">
</form>
This so far is getting me a form where I'm using the field names to generate labels and input boxes where i show the field value. I would like to further format some of the fields using the jquery datepicker, but only for those fields which have a type = Date in the mysql table.
I've been trying mysqli_fetch_field_direct using something like:
BLOCK#2:
$fields = mysqli_num_fields($result);
for ($i=0; $i < $fields; $i++) {
$field_types[] = $result->fetch_field_direct($i)->type;
}
but in this case I can't get the value, just the type
Is there a straightforward way to get the type and value of a field?
Edited to (try) to simplify:
Let's say I have a field called email which has type = varchar and my SQL query generates one result test#example.com
From BLOCK#1 I get:
-------------------------------
Field-Name | Field-Value
email | test#example.com
From BLOCK#2 I get:
-------------------------------
Field-Name | Field-Type
email | varchar
what I would like is to get
-------------------------------
Field-Name | Field-Type | Field-Value
email | varchar | test#example.com
This is because I would like to use the field type to add a css class to the input box (such as to use the datepicker).
Edit: I put the output in a table because I can't sleep...
Okay... see if this is what you want...
This is a table I made for a different SO question:
mysql> describe user;
+-------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+----------------+
| User_ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
| Email | varchar(100) | YES | | NULL | |
| Name | varchar(100) | YES | | NULL | |
| Password | varchar(100) | YES | | NULL | |
| FB_ID | int(11) | YES | | NULL | |
| Total_Score | int(11) | YES | | 0 | |
| add_date | datetime | YES | | NULL | |
+-------------+------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
and from the DB:
mysql> select * from user limit 1;
+---------+-------+------+----------+-------+-------------+---------------------+
| User_ID | Email | Name | Password | FB_ID | Total_Score | add_date |
+---------+-------+------+----------+-------+-------------+---------------------+
| 1 | NULL | kim | NULL | NULL | 10 | 2013-11-03 23:04:08 |
+---------+-------+------+----------+-------+-------------+---------------------+
+
1 row in set (0.00 sec)
And the code:
<?php
$mysqli = mysqli_connect("localhost", "root", "", "test");
// this came from http://php.net/manual/en/mysqli-result.fetch-field-direct.php
$mysql_data_type_hash = array(
1=>'tinyint',
2=>'smallint',
3=>'int',
4=>'float',
5=>'double',
7=>'timestamp',
8=>'bigint',
9=>'mediumint',
10=>'date',
11=>'time',
12=>'datetime',
13=>'year',
16=>'bit',
//252 is currently mapped to all text and blob types (MySQL 5.0.51a)
253=>'varchar',
254=>'char',
246=>'decimal'
);
// run the query...
$result = $mysqli->query("select * from user limit 1");
// get one row of data from the query results
$proceso = mysqli_fetch_assoc($result);
print "<table>
<tr>
<th>\$key</th>
<th>\$value</th>
<th>\$datatype</th>
<th>\$dt_str</th>
</tr> ";
// to count columns for fetch_field_direct()
$count = 0;
// foreach column in that row...
foreach ($proceso as $key => $value)
{
$datatype = $result->fetch_field_direct($count)->type;
$dt_str = $mysql_data_type_hash[$datatype];
$value = (empty($value)) ? 'null' : $value;
print "<tr>
<td>$key</td>
<td>$value</td>
<td class='right'>$datatype</td>
<td>$dt_str</td>
</tr> ";
$count++;
}
print "</table>";
mysqli_close($mysqli);
?>
<style>
/* this is css that you don't need but i was bored so i made it pretty...! */
table { font-family:Courier New;
border-color:#E5E8E3; border-style:solid; border-weight:1px; border-collapse:collapse;}
td,th { padding-left:5px; padding-right:5px; margin-right:20px;
border-color:#E5E8E3; border-style:solid; border-weight:1px; }
.right { text-align:right }
</style>
So... to clarify...
You can use these variables in that foreach to output or use the information however you want: (I am using my first row of output, for the user_id, as an example)
$key is the column/field name (such as user_id)
$field_types[$key] comes from $result->fetch_field_direct($i)->type (such as 3)
$mysql_data_type_hash[$datatype] is the string version of the datatype using the $mysql_data_type_hash array at the top of the code. This isn't necessary but I included it so this example is more clear. (such as int)
$proceso[$key] = $value = is your value for this iteration of the foreach statement (such as 1)
Output:
$key $value $datatype $dt_str
User_ID 1 3 int
Email null 253 varchar
Name kim 253 varchar
Password null 253 varchar
FB_ID null 3 int
Total_Score 10 3 int
add_date 2013-11-03 23:04:08 12 datetime

PHP mysql LEFT JOIN output

I have php-script running on top of apache. Every time when user goes to specific URL, he/she will get csv-file.
Column names are fetched like this (thanks to Daniel Figueroa :)
$csv_output .= "\n";
// get the column name from the first DB (ins.data)
mysql_select_db($db, $link) or die("Can not connect to DB1.");
$result = mysql_query("SHOW COLUMNS FROM ".$table." WHERE Field NOT IN
('ID','Key','Text')");
$i = 0;
if (mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_assoc($result)) {
$csv_output .= $row['Field']."; ";
$i++;
}
}
// get the column names from the second DB (Cu.data)
mysql_select_db($db2, $link) or die("Can not connect to DB2.");
$result = mysql_query("SHOW COLUMNS FROM ".$table2." ");
;
$i = 0;
if (mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_assoc($result)) {
$csv_output .= $row['Field']."; ";
$i++;
}
}
$csv_output .= "\n";
Actual query on PHP-script goes like this:
$values = mysql_query(" SELECT ins.data.`Date`, ins.data.`Number`,
ins.data.`Email`, ins.data.`TargetId`, ins.data.`CSW`,
ins.data.`TSW`, ins.data.`CType`,
Cu.data.`Cus`, Cu.data.`Co`,Cu.data.`Ci`,
Cu.data.`SID`, Cu.data.`SType`
FROM ins.data
LEFT JOIN Cu.data ON (ins.data.TargetId = Cu.data.TargetID)
ORDER BY ins.data.ID DESC");
Output of 'desc':
mysql> desc ins.data;
+-------------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------------------+----------------+
| ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
| Date | timestamp | NO | | 0000-00-00 00:00:00 | |
| Number | text | NO | | NULL | |
| Text | text | NO | | NULL | |
| Email | text | NO | | NULL | |
| TargetId | varchar(20) | NO | | NULL | |
| CSW | text | NO | | NULL | |
| TSW | text | NO | | NULL | |
| Key | text | NO | | NULL | |
| CType | text | NO | | NULL | |
+-------------------+------------------+------+-----+---------------------+----------------+
10 rows in set (0.00 sec)
mysql> desc Cu.data;
+----------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------+------+-----+---------+-------+
| Title | decimal(15,0) | NO | | NULL | |
| Cu | text | NO | | NULL | |
| Co | text | NO | | NULL | |
| Ci | text | NO | | NULL | |
| SID | text | NO | | NULL | |
| TargetID | varchar(20) | NO | MUL | NULL | |
| SType | text | NO | | NULL | |
| empty1 | int(11) | NO | | NULL | |
| empty2 | int(11) | NO | | NULL | |
| empty3 | int(11) | NO | | NULL | |
| empty4 | int(11) | NO | | NULL | |
| empty5 | int(11) | NO | | NULL | |
| empty6 | int(11) | NO | | NULL | |
| empty7 | int(11) | NO | | NULL | |
+----------+---------------+------+-----+---------+-------+
12 rows in set (0.00 sec)
UPDATE 3:
This is no more NATURAL LEFT JOIN-issue. Replaced with LEFT JOIN.
Added fields empty1-5 to ins.data to get data to csv-file. Without fields empty1-5, only data from first db (ins.data) was on csv.file.
Now i have data on all fields but field (or column names on excel) names on csv are on wrong order and not wanted fields (columns) are visible like Title and empty1-5.
Any ideas how to fix this? Some other way to get Field names to csv-file without "SHOW COLUMNS"?
I could write with 'echo' in the beginning of csv-file values what i want. ie
"Date; Number; Email; TargetID, CSW; TSW; CType; Cu; SID; Co; Ci; SType;" but i am so newbie with PHP that i don't know how :(
Another issue is that if field ID is first column on excel, excel cannot handle that and it must be excluded from SHOW COLUMNS output.
UPDATE4: Added more empty-fields to DB2 (Cu.data) and reordered SQL-query, now all values are visible and on right order.
EDIT
First of all, your table naming schema is weird and unusual... but assuming I understand it correctly then this query should work (if it does not then rename your tables without the dots (periods) to make things less confusing:
mysql_query('SELECT ins.data.Date, ins.data.Number, ins.data.Email, ins.data.TID, ins.data.CSW, ins.data.TSW, ins.data.CType, CU.data.SID, cu.data.SType, cu.data.CU, cu.data.CO, cu.data.Ci, FROM ins.data, cu.data ORDER BY ins.data.ID DESC');
According to to the mysql_query function reference, data should not end with a semicolon when using mysql_query in PHP... i never put the semicolon in there so I don't ever have a problem, that's what I initially noticed with your script (as I said i've never tried it so I don't know if thats the issue). Should be:
$values = mysql_query("SELECT Date, Number, Email, TID, CSW, TSW, CType, SID, SType, Cu, Co, Ci FROM ins.data NATURAL LEFT JOIN Cu.data ORDER BY ID DESC");
Also, when doing JOINS, usually you specify what column belongs to what table... like in the standard mysql example here:
<?php
// Make a MySQL Connection
// Construct our join query
$query = "SELECT family.Position, food.Meal ".
"FROM family LEFT JOIN food ".
"ON family.Position = food.Position";
$result = mysql_query($query) or die(mysql_error());
// Print out the contents of each row into a table
while($row = mysql_fetch_array($result)){
echo $row['Position']. " - ". $row['Meal'];
echo "<br />";
}
?>
I don't always use the JOIN commands either... you can use an alternative syntax like so:
mysql_query('SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c AND t1.a = t3.a');
Try putting aliases on table names. It will make the query more readable, too:
SELECT
i.`Date`, i.Number, i.Email, i.TID, i.CSW, i.TSW, i.CType,
c.Cu, c.Co, c.Ci, c.SID, c.TID, c.SType
FROM
ins.data AS i
LEFT JOIN
Cu.data AS c
ON i.TID = c.TID
ORDER BY
i.ID DESC ;

Categories