Mediawiki search by infobox property - mediawiki

I want search the media wiki api using the search term on specific category (eg: song).
Search term, I am trying to use combination of song name and artist
Search term = "song name" + "artist"
https://en.wikipedia.org/w/api.php?action=query&prop=revisions&rvprop=content&format=xmlfm&titles=Why%20This%20Kolaveri%20Di%20&rvsection=0
Above api giving the infobox information like below
{{Infobox song
| Name = ''Why This Kolaveri Di''
| Cover =
| Caption- = Screenshot of the song
| Artist = [[Dhanush]]
| Album = [[3 (2012 Indian film)|3]]
| URL =
| A-side =
| B-side =
| country = India
| Released = 16 November 2011
| Format = [[Music download|Digital download]]
| track_no = 1
| Recorded = [[2011 in music|2011]] at [[Panchathan Record Inn and AM Studios|AM Studios]], [[Chennai]]
| Genre =
| Length = 4:09
| Label = [[Sony Music Entertainment|Sony Music]]
| Producer = [[Anirudh Ravichander]]
| Writer = [[Dhanush]]
| Composer = [[Anirudh Ravichander]]
| Language = [[Tanglish]]
| Chart position =
| prev =
| prev_no = 2
| Misc =
{{External music video|{{YouTube|YR12Z8f1Dh8|"Why This Kolaveri Di"}}|Type=song}}
}}
I am trying to extract information from that.
So my question how can I query to search relevant page and get the Infobox data in single query. Is it possible in single query or do I need to use multiple query!

You need to use the search query as a generator (basically merge the parameters from the two queries and prepend all the parameter names from the search query with a g).

Related

Select statement drawing from two tables and more than one column

I am developing an application to be used for scheduling chamber music session. I am trying to display information from two tables with matches on different columns. The first table has information about the piece of music like name, composer, and includes columns for up to 12 slots. The slots are populated with specific instruments. For example a piano quintet will have slot1 violin slot2 violin slot3 viola, slot4 cello and slot5 piano. I have a separate table listing all plausible instruments with two columns: an instrument ID number and name in order to make sure that instruments are spelled correctly and. For example 12 = "Violin", 4 = "Clarinet" and so forth.
I have a PHP script that creates a new piece and fills numbers some of the slots. A string quartet would have slot1 = 12, slot2 = 12, slot3 = 13 and slot 4 = 14. I want to run through the table of pieces and show the information drawn from the table of pieces and also identify the instruments using the non-coded names from the instruments table. It is easy to display all the information with instrument number codes but I have not been able to construct a select statement that will return more than a single column in addition to the Title composer and so forth. I am using command line queries to develop something I can then put into my PHP script. For example>:
select piece.cfname, piece.clname, piece.pname, slot1, slot2, slot3, slot4, slot5
FROM piece;
+----------+--------+------------------+-------+-------+-------+-------+-------+
| cfname | clname | pname | slot1 | slot2 | slot3 | slot4 | slot5 |
+----------+--------+------------------+-------+-------+-------+-------+-------+
| Wolfgang | Mozart | Clarinet Quintet | 14 | 14 | 15 | 16 | 4 |
| Johannes | Brahms | Clarinet Quintet | 14 | 14 | 15 | 16 | 4 |
+----------+--------+------------------+-------+-------+-------+-------+-------+
But I cannot manage to find a statement that lets me pull the name of the instrument based on the instid. I have tried of, where piece.slot1 = instruments.instid and piece.slot2 = instruments.instid. With a join statement I can manage to return "violin" into slot1 but cannot add the second violin, viola, cello and clarinet to the return.
I am not fluent in SQL but this really seems like something relatively basic that should work.

Trying to reorder the sequence of which MySQL determines which entry is distinct by

Consider I have a Zoo Parent assigned to a Zoo Animal, I would like to get the ID's of all Zoo Parent which are distinct by the Zoo Animal's serial tag, What I'd want to do is:
SELECT
zoo_parent.id
FROM
zoo_parent
INNER JOIN
zoo_animal ON (zoo_parent.animal_id = zoo_animal.id)
WHERE
zoo_animal.is_active = "Y"
GROUP BY
zoo_animal.serial_tag
The dilemma now is that I have a bunch of Zoo Animals with the same serial_tag because the owners of the software do not want to use historical records, instead they just save a new entry to the database using the same serial_tag. Their request to me is in a table that looks like this:
|------------------|------------------|-------------------|
| Zoo Parent.id | Zoo Animal.id | Zoo Animal.serial |
|------------------|------------------|-------------------|
| 1 | 1 | ABC-100 |
| 2 | 2 | ABC-200 |
| 3 | 3 | ABC-300 |
| 4 | 4 | ABC-100 |
|------------------|------------------|-------------------|
Ideally assuming running number for primary-key values, I would like to GROUP BY zoo_animal.serial_tag and get the zoo_parent.id = 4 instead of zoo_parent.id = 1` (Latest "version" of this Parent's Animal's Serial Number). Note, they do not want me to change the schema in any way.
if you want the max id, use the MAX function:
SELECT
MAX(zoo_parent.id) as max_id
FROM
zoo_parent
INNER JOIN
zoo_animal ON (zoo_parent.animal_id = zoo_animal.id)
WHERE
zoo_animal.is_active = "Y"
GROUP BY
zoo_animal.serial_tag

Missing an option to use SQL's HAVING clause in F3

Is there a way to use MySQL's HAVING clause with any of Fat Free Framework's SQL Mapper object's methods? Let's assume I have the following DB table:
+----+-------+--------+
| id | score | weight |
+----+-------+--------+
| 2 | 1 | 1 |
| 2 | 2 | 3 |
| 2 | 3 | 1 |
| 2 | 2 | 2 |
| 3 | 1 | 4 |
| 3 | 3 | 1 |
| 3 | 4 | 3 |
+----+-------+--------+
Now I would like to run a following query:
SELECT id, SUM(score*weight)/SUM(weight) AS weighted_score GROUP BY id HAVING weighted_score>2
Truth to be told I would actually like to count the number of these records, but a count method doesn't support $options.
I can run the query without a HAVING clause and then loop through them to check weighted_score against the value, but with a growing number of records will make it more and more resource consuming. Is there any built-in solution to solve this problem?
EDIT 1:
The way I know how to do it if there is no support for the HAVING clause (based on manual):
$databaseObject = new DB\SQL(...);
$dataMapper = new \DB\SQL\Mapper($databaseObject, "tableName");
$dataMapper->weightedScore = "SUM(weight*score)/SUM(weight)";
$usersInfo = $dataMapper->find([],["group"=>"id"]);
$place = 1;
foreach ( $usersInfo as $userInfo ) {
if ( $usersScores->weightedScore > 2) $place++;
}
If I were able to use HAVING clause then the foreach loop would not be needed and the number of items loaded by a query would be reduced:
$databaseObject = new DB\SQL(...);
$dataMapper = new \DB\SQL\Mapper($databaseObject, "tableName");
$dataMapper->weightedScore = "SUM(weight*score)/SUM(weight)";
$usersInfo = $dataMapper->find([],["group"=>"id", "having"=>"weighted_score<2"]); // rough idea
$place = count($usersInfo);
And if count method supported $options it would be even simpler and it would save memory used by the app as no records would be loaded:
$databaseObject = new DB\SQL(...);
$dataMapper = new \DB\SQL\Mapper($databaseObject, "tableName");
$dataMapper->weightedScore = "SUM(weight*score)/SUM(weight)";
$place = $dataMapper->count([],["group"=>"id", "having"=>"weighted_score<2"]); // rough idea
Use Sub Query.
select count (0) from (SELECT id, SUM(score*weight)/SUM(weight) AS weighted_score GROUP BY id) where weighted_score>2;
Hope it will help.
As far as I know, you can put the HAVING clause into the group option:
$usersInfo = $dataMapper->find([],["group"=>"id HAVING weighted_score<2"]);
Another way could be to create a VIEW in mysql and filter the records on a virtual fields in that view.

mysql select data from 3 tables using user input

I have 3 tables with the following columns and values (they have multiple entries but I'm showing you one):
protein
+--------+------+-------------+
| pdb_id | name | description |
+--------+------+-------------+
| 1AF6 | porin| maltoporin |
+--------+------+-------------+
organism:
+--------+-----------------------+
| org_id | organismName |
+--------+-----------------------+
| 4 | Comamonas acidovorans |
+--------+-----------------------+
protein_organism:
+--------+--------+
| pdb_id | org_id |
+--------+--------+
| 1AF6 | 4 |
+--------+--------+
I'm making a website where someone can see all the proteins from a specific organism that can be selected from a drop down menu.
However when I try to fetch the data the browser goes to the correct url: http://localhost:8084/response_organism?organismName=Comamonas+acidovorans
but shows nothing.
This is my sql command:
query = "SELECT * FROM protein JOIN protein_organism ON protein_organism.pdb_id = protein.pdb_id JOIN organism ON organism.org_id = protein_organism.org_id WHERE organism.organismName="+po;
po (string) is the user input fetched from my index.jsp form
What is wrong with my sql command?
You are querying the wrong way. This is the correct way of query with JOIN.
"SELECT *
FROM protein P
INNER JOIN protein_organism PO
ON PO.pdb_id = P.pdb_id
LEFT JOIN organism O
ON O.org_id = PO.org_id
WHERE O.organismName="+po;
Make appropriate changes to this query if you have some error or different result when run it.

Foreach in a while loop

I’ve two tables: “cars” and “dealerships”:
Cars table
id_car | name_car | etc.
----------------------------
1 | A3 Sportback | etc.
2 | Ranger | etc.
3 | Transit Van |etc.
4 | Cayman | etc.
etc. | etc. | etc.
Dealerships table
In deal_cars column I insert ids of correspondent cars as array.
deal_id | deal_name | deal_cars | etc.
--------------------------------------
1 | Ford | 2,3 | etc.
2 | Audi | 1 | etc.
3 | Porsche | 4 | etc.
etc. | etc. | etc. |
I’d get a page that displays the following information:
Dealership name – Cars
Ford – Ranger, Transit Van
Audi – A3 Sportback
Cayman – Porsche
I’ve no problem to extract the dealership name, but I don’t know how to extract the car names from ids.
I tried this:
$dealerships_sql = $data->query("SELECT * FROM dealerships ORDER BY deal_name ASC");
while($dealerships_obj = $data->extract($dealerships_sql)){
//Dealerships data
$deal_id[] = $dealerships_obj->deal_id;
$deal_name[] = $dealerships_obj->deal_name;
etc etc
//Try to get cars ids and turn them in cars names.
$deal_cars[] = $dealerships_obj->deal_cars;
$deal_cars[] = explode(',',$deal_cars);
$cars = array();
foreach ($deal_cars AS $deal_car) {
$cars_sql = $data->query("SELECT name_car FROM cars WHERE id_car = '$deal_car'");
while($cars_obj = $data->extract($cars_sql)){
$cars[] = stripslashes($cars_obj->name_car)." ";
}
}
}
I use smarty as template engine so I assign some vars:
$smarty->assign ("deal_id", $deal_id);
$smarty->assign ("deal_name", $deal_name);
etc etc.
$smarty->assign ("cars", $cars);
And my template is:
<table border="1">
<tr>
<td>Dealership</td>
<td>Cars</td>
</tr>
{section name="foo" loop=$deal_name}
<tr>
<td>{$deal_name[foo]}</td>
<td>{$cars[foo]}</td>
</tr>
{/section}
</table>
But code returns:
Ford – Ranger
Audi – A3 Sportback
Cayman – Porsche
It shows only the first car (first element found in array) for each dealership. How can I solve this?
I think your database design does not fit right here.
Cars Table
id_car | name_car | etc.
----------------------------
1 | A3 Sportback | etc.
2 | Ranger | etc.
3 | Transit Van | etc.
4 | Cayman | etc.
etc. | etc. | etc.
Dealer Table
deal_id | deal_name | etc.
---------------------------
1 | Ford | etc.
2 | Audi | etc.
3 | Porsche | etc.
etc. | etc. |
Dealer to Cars Table
dealerid | carid
1 | 2
1 | 3
2 | 1
etc. | etc.
As you see, I did another table for the relationships between the two tables.
$dealerships_sql = $data->query("SELECT * FROM dealerships ORDER BY deal_name ASC");
$dealers = array();
while($dealerships_obj = $data->extract($dealerships_sql)){
//Dealerships data, use object
$dealerid = $dealerships_obj->deal_id;
$dealers[$dealerid]['dealer'] = $dealerships_obj;
// Cars
$cars = array();
$car_sql = $data->query("SELECT name_car FROM cars JOIN dealerToCars ON carid = id_car JOIN dealer ON deal_id = dealerid WHERE deal_id = " . $dealerid);
// now you have all cars from the selected dealer
while ($cars_obj = $data->extract($car_sql))
{
$cars[] = stripslashes($cars_obj->name_car);
}
// Assign Cars to dealer
$dealers[$dealerid]['cars'] = $cars;
}
Now you have in $dealers all your dealers with their cars.
Since you are using smarty, just pass this whole array to smarty and let the rest do smarty in it's template. Smarty is able to use arrays and objects, so you don't need to split it into multiple arrays:
$smarty->assign ("dealers", $dealer);
Because I don't know your classes, you maybe need to add some getters or setters or just make the properties public, so smarty can access them:
<table border="1">
<tr>
<td>Dealership</td>
<td>Cars</td>
</tr>
{foreach $dealers as $dealer}
<tr>
<td>{$dealer['dealer']->deal_name}</td>
<td>{foreach $dealer['cars'] as $car}{$car}, {/foreach}</td>
</tr>
{/foreach}
</table>
Maybe you need to take a look about the identifiers in the template.
(I'm using smarty 3 for that)
I think you should have a dealership row for each car (that will allow you to get all the information with a JOIN and parse it all easily).
The best way would be to get everything at once, you can do it like that:
select
d.deal_name,
group_concat(c.name_car order by c.name_car separator ', ')
from dealerships d
join cars c on find_in_set(c.id_car, d.deal_cars) > 0
group by d.deal_name;
or (as separated fields):
select d.deal_id, d.deal_name, c.id_car, c.name_car
from dealerships d
join cars c on find_in_set(c.id_car, d.deal_cars) > 0;