Excuse me, I do not make a clear question in english.
I need some mysql query like this: query out all the item names, UNION by two tables, but not repeat.
here is my table structure:
table: cxt_20110105
item | ... many columns, but does not affect query, because I just need item.
art |
collectibles |
furniture |
books |
arts |
books |
... many lines...
table: cxt_20110106
item | ... many columns, the columns structure is as well as table: cxt_20110105.
art |
tickets |
cars |
furniture |
tickets |
cars |
... many lines...
So
mysql_query(//how to write in here?)
while ($row = mysql_fetch_array($result))
{
//the result should be: art, collectibles, furniture, books, tickets, cars(every word, but not repeat) ;
}
Thanks.
SELECT item FROM cxt_20110105
UNION DISTINCT <---the important bit.
SELECT item FROM cxt_20110106
UNION will remove the duplicates for you.
SELECT item FROM cxt_20110105
UNION
SELECT item FROM cxt_20110106
feel free to delete this post....I misconstrued what he was asking
echo mysql_field_name ( $row , 0 ); //art
you can stick it in a loop and exit on failure (no more entries), or go the length of $row
$n = count($row);
$i=0;
while ($i<$n) {
echo mysql_field_name ( $row , $i );
$i++;
}
note, as the array returned by mysql_fetch_array returns both an numeric and text index, $n might be 2x what you need...so $n = int(count($row)/2)
It looks like I may have misunderstood the question though - I was thinking he wanted the field names output within the middle. Then again, that within a while loop itself wouldn't make sense. my apologies
Related
I have two rows of data - always just two rows, but there could be a maximum of around forty columns. The column names are different on a case by case basis, but here is a representative example:
id | height | width | colour | in_stock | featured | on_sale
------------------------------------------------------------
1 | 30 | 20 | black | yes | no | yes
2 | 30 | 25 | red | yes | yes | no
I want to get all of the differences between those two rows into an array so that I can log what was changed from row 1 to row 2.
I thought it array_diff() would do the job!
So I cheerfully chucked array_diff() at it thus:
//Simplified queries for the example
$sql1 = "SELECT * FROM table WHERE id = 1";
$rs1 = $conn->Execute($sql1);
$rs1 = $rs1->fields;
$sql2 = "SELECT * FROM table WHERE id = 2";
$rs2 = $conn->Execute($sql2);
$rs2 = $rs2->fields;
//Build first array
foreach($rs1 as $key => $value){
$data1[$key] = $value;
}
//Build second array
foreach($rs2 as $key => $value){
$data2[$key] = $value;
}
//Find the differences
$theDifferences = array_diff($data1, $data2);
//Loop through the differences logging the changes
foreach($theDifferences as $field => $value){
echo "Change found for ".$field."!";
}
Why that doesn't work.
This "looked like" it was working. Since many columns contain long strings, colour names, dates etc, so when one changed it was duly pushed into the differences array. The problem was (of course) that the multiple "yes" or "no" columns did not behave as I had expected. Thus the result of the code above, for the table example is:
colour, width
It is not "seeing" the featured or on_sale columns as changed because the data1 array AND the data2 array both contain no's and yes's.
I suppose I need to compare on a key by key basis? Something like the opposite of array_diff_key()? But here I am stuck.
I also considered if this could be done solely with the SQL query, which would I suppose be more efficient, but that is way beyond my SQL ability.
Thanks in advance.
I think you're very nearly there. Maybe something like this after your queries:
$theDifferences = array();
foreach($rs1 as $key => $value){
if ($rs2[$key] != $value){
$theDifferences[$key] = $value;
}
}
As for SQL, you can use an EXCEPT to get a list of rows which are different between two queries, but you'd still have to loop through the keys and look for nulls - which doesn't save you a whole lot.
I have 600 rows of data in one table and table structure is,
Table Name: city_Data
------------------------------
cityId | cityName
------------------------------
1 | chennai
2 | madurai
3 | trichy
4 | kovai
...
...
...
------------------------------
cityId - autoincrement
now i would like to mix this table data and inset into another table. this table's name is city_Mix.
---------------------------------------
mixId | city1 | city2
---------------------------------------
1 | chennai | madurai
2 | chennai | trichy
3 | chennai | kovai
4 | madurai | chennai
5 | madurai | trichy
6 | madurai | kovai
7 | trichy | chennai
...
...
...
---------------------------------------
here, city1 and city2 are should not be same and mixId - autoincrement
how to do this? anyone plz help me with sample code..
try the following query, which uses join to combine the city names which dont match and insert the dat to city_mix table
INSERT INTO city_mix
(city1,city2) select t1.cityName,t2.cityName from Table1 t1 join Table1 t2 on t1.cityName != t2.cityName;
http://sqlfiddle.com/#!9/2e01ea/3
I'm making some assumptions about what you are specifically asking, if you were to supply a little more information it might help:
Does city_Mix already contain the field city2 or is that the column you wish to join from city_Data?
Are you doing this in PHP or SQL?
Is city_Mix really a self-iteration of the city_Data table?
Is the data you've presented representational of a database table, or a PHP data structure?
Once again, I am making some assumptions here, but I'll try to help based on what you've provided...
It appears that city_Mix matches #3 from my question list (so you want to take a list of items, and for each item in the list, map it to all other items on the list). If this assumption is correct, here is one way to approach the solution:
Using SQL
// You'll probably want to use an INNER JOIN to accomplish this quickly, something like the following
(SELECT 'cityName' FROM `city_Data` c INNER_JOIN `city_Data` m ON m.cityName != c.cityName)
Using PHP
FYI: I would recommend against this in favor of doing this with SQL, but wanted to provide it as "a way to do it" since you did not indicate which way you were approaching the solution.
<?php
$cityMixData = []; //Final data table as you've indicated you desire
//Connect to your database
$con = mysql_connect("localhost","inmoti6_myuser","mypassword");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("databaseName", $con);
// Define our SQL query
$query = "SELECT DISTINCT `cityName` FROM `city_Data` ORDER BY `cityId`";
// Execute the query
$cities = mysql_query($query);
$i = 1; // Iterator index
$cityMixData = [];
// Loop through the list of unique city names and map all other items accordingly
while( $city = mysql_fetch_array( $cities, MYSQL_ASSOC ) ) {
$tmpArr = $cities;
unset($tmpArr[$row[$i - 1]); // Remove self
$cityMap = array_values($tmpArr); // reindex array
$mixRow = array($mixId => $i, $city1 => $city['cityName'], $city2 => $cityMap); // Create a row with auto-increment ID, city1 === unique city name, city2 === list of unique cities sans-city1
$cityMixData[] = $mixRow; // Add row to cityMixData which is multi-dimensional array
$i++; // Increment iterator
}
// Connect to DB
// Create city_Mix table if not exist
// Appropriately generate SQL based on $cityMixData structure, might get messy
// Save to DB
?>
If you answer the questions I posed above, I will be able to help more.
I am not sure if there is no answer here on Stack Overflow, but I did not find exact thing there.
So, I have a table with data like this:
id | sector | type | level
| | |
1 | TMT | Long | First
2 | Energy | Long | Second
3 | TMT | Short | Third
4 | Other | Long | First
5 | TMT | N/A | Sixth
6 | Other | Short | First
What I need is summary of each different value in each field, like this:
Sector TMT: 3
Sector Energy: 1
Sector Other: 2
Type Long: 3
Type Short: 2
Type N/A: 1
Level First: 3
Level Second: 1
Level Third: 1
Level Sixth: 1
Type and Level have fixed values. Sectors could be dynamic, I mean there is no final list as they are adding with each item.
For now I am selecting all rows and processing it with PHP:
SELECT `sector`, `type`, `level` FROM `table`;
and for example:
<?php
$result['type_long'] = 0;
$result['type_short'] = 0;
$result['type_na'] = 0;
foreach ($rows as $row)
{
if ($row['type'] == 'Long')
{
$result['type_long']++;
}
else if ($row['type'] == 'Short')
{
$result['type_short']++;
}
else if ($row['type'] == 'N/A')
{
$result['type_na']++;
}
}
etc. For 10000 records it's not really fast cause I need to select all rows from database and then do something to them via PHP.
Is there any way I can do this faster with MySQL?
Thanks!
This is a straightforward application of the union of several summary queries. A typical summary query would be
SELECT Sector, COUNT(*) cnt
FROM mytable
GROUP BY Sector
To get your exact result set you could do something like this:
SELECT CONCAT('Sector ', Sector, ':') item, COUNT(*) cnt FROM mytable GROUP BY Sector
UNION ALL
SELECT CONCAT('Type ', Type, ':') item, COUNT(*) cnt FROM mytable GROUP BY Type
UNION ALL
SELECT CONCAT('Level', Level, ':') item, COUNT(*) cnt FROM mytable GROUP BY Level
If you want this to be optimally fast, you might try adding indexes on the three columns.
MySQL is quite good at handling summary queries with high performance. Even with multiple separate SELECT queries in this UNION, it will perform an order of magnitude better than transferring all your raw data rows from the server to your MySQL program.
I have a table that looks like this:
+----------------------------------+
| Category | Sub-Category |
+---------------+------------------+
| Cell Phones | Smart Phones |
| Cell Phones | Tablet Phones |
| Cell Phones | Other Phones |
| Computers | Desktops |
| Computers | Laptops |
| Computers | Chromebooks |
+---------------+------------------+ etc..
And I would like to display this data on my website using PHP, like this:
How would I display the information as above(one category, all subcategories under) using PHP? Also how can I evenly divide the list of category/subcategories into 3 columns?
I've found tutorials but none seemed to use PHP, which is the part I'm having trouble with.
Thank you guys for your time.
This type of reports are called cross tabing reports. In sql there is pivot function which gives data as you require. But in mysql there is no pivoting so you need to use your own logic.
To achieve this you will need to have two loops as described below a short idea on how to do this.
Select distinct maincategory from table
Loop for main category{
select subcategory from table where maincategory='category'{
print all sub categories
}
}
$data = query_data();
$cat = array();
foreach($data as $item)
{
$cat[$item['category']][] = $item['sub_category'];
}
Now, $cat is what you need.
You can give category id to them for example, say cellphones has an id of 1 then all items inside this will also have a subcategory_id of 1. Similarly if the printers have id of 2 then all subcategory_id under it will have id as 2.
Now you can run simple query to retrieve the field specific category. like:
SELECT * from table_name WHERE subcategory_id = 1;
This will give out all the categories inside cellphones...similarly you can do for all fields...
This should work -
$categories = Array();
//Assuming database handle is $db
$r1 = $db->query("select distinct(Category) from table_name") or die("err in q1");
while($cat_arr = $r1->fetch_assoc()){
$cat = $cat_arr['Category'];
$sub_cats = Array();
$db->query("select Sub-Category from table_name where Category = $cat") or die("err in q2");
while($sub_arr = $r2->fetch_assoc()){
array_push($sub_cats,$sub_arr['Sub-Category']);
}
$categories[$cat] = $sub_cats;
}
The $categories array now has the details of the table, and can be used as is.
I am using PHP and MySQL database
I Have a table which has a column: actors
In a row in the table, in the actors column, there maybe several actors listed e.g. Denzel Washington, Charlie Sheen, Matt Damon
The next row might be: Matt Damon, Robert De Niro, Denzel Washington
They are always comma seperated.
I have an autocomplete where I am asking the user to choose an actor. So, when the autocomplete looks in the column, it returns the whole column value.
e.g. someone searching for Denzel will get in their autocomplete results:
Denzel Washington, Charlie Sheen, Matt Damon
Matt Damon, Robert De Niro, Denzel Washington
As far as I know there's no way to seperate this at that level so I'm thinking I might have to strip out the actors from that table, into a seperate table which just services the autocomplete.
Is this the best way to do it and if so, can it be done? Is there a simple SQL query i could use to get the actors out, seperately, then load another table. This is constantly updated data so needs to run every day but I presume if I had the actor column in a new table as unique then i wouldn't have duplicates.
Or is there a more efficient way?
NOTE: I need to point out that this is a XML feed and I have no control over the data - yes, I know it should all be seperate from the get go but unfortunately I'm just working with what I have
What you need is something like this
table actors
id | name
table actor_entries
id | data_id | actor_id
table data
id | <other columns>
Then your data would like something like this
table actors
1 | Denzel Washington
2 | Charlie Sheen
3 | Robert De Niro
table data
1 | some data // this row is associated with actors 1 and 2
2 | some data // this row is associated with actors 2 and 3
table actor_entries ( id | data_id | actor_id )
1 | 1 | 1
2 | 1 | 2
3 | 2 | 2
4 | 2 | 3
What you should have had is three different tables:
Movies Actors MovieActors
---- ---- ----------
movie_id PK actor_id PK movie_id FK
title name actor_id FK
year born
gender
Then you would not have that huge mess. Also you would be able to search data
SELECT Actors.name FROM Actors WHERE Actors.name LIKE '%Pam' LIMIT 5
Or get all movies where actor has participated:
SELECT
Movies.title
FROM Movies
LEFT JOIN MovieActors USING(movie_id)
LEFT JOIN Actors USING(actor_id)
WHERE
Actors.name = 'Foo Bar'
AND Movies.year > 1990
If you already know the basics of SQL, i would suggest for you to read SQL Antipatterns. That book covers this an many other issues.
This is probably not a very good way to store data since it would become very slow and difficult to maintain once the csv reaches a certain size.
Anyway, as for your question, let me know if this helps:
<?php
$search = $_GET['search']; // assume it's 'de'
$result = array(); // this contains the result
$sql = 'SELECT `actors` from `tablename`;';
$run = mysql_query( $sql );
if ( $run && mysql_num_rows( $run ) ) {
while ( ( $data = mysql_fetch_assoc( $run ) ) !== FALSE) {
$num = explode( ',', $data[ 'actors' ] );
for ($i=0; $i < $num; $i++) {
if( stripos( $data[ $i ], $search ) !== false ) {
$result[] = trim( $data[ $i ] );
}
}
}
}
// here's the result you want
$result = array_values( array_unique( $result ) );
?>
This will work, but again, as many have suggested, this is not a very good choice.
You can use the php explode function with ',' as separator. It will return an array with all
actor name