MYSQL query not working as wanted - mysql

I want to be able to get the pieces evidence within a trybe. But I have to go through the ambition table which is the relation from trybe to evidence.
So basically get count(e.id) from
The query i have at the moment is as follows:
$evidence = array(1,2,10,20,40,60,80,100,200,300,400,500,1000,1500,2000);
$evidence = implode(", ", $evidence);
# no of evidence in trybe = the x trybe now has over x evidence
$query = sprintf("SELECT t.id, t.name, COUNT(e.id) as number, 'trybe_evidence' AS type
FROM x_trybes t
INNER JOIN x_ambition_owner ao ON (t.id = ao.trybe_id)
LEFT JOIN x_evidence e ON (ao.id = e.ambition_id)
GROUP BY t.id, t.name
HAVING COUNT(e.id) in (%s)",$evidence);
How can I get all the pieces of evidence from all the ambitions within the trybe table?
The structure of the tables are as follows:
x_trybes
id name
x_ambition_owner
id ambition_id trybe_id
x_ambition - ambition info
id name etc.
x_evidence
id ambition_id name
Please note there can be many trybes, many ambitions and many pieces of evidence.
Thanks

Related

Select from SQL database information with newest revisions

I coding web app for my client and have issue with selecting from database raports with newest revisions.
SELECT
raports.*,
r1.*,
users.*,
(SELECT COUNT(*) FROM changes WHERE changes.changes_raports_id = raports.raports_id) as changes,
(SELECT changes.changes_date FROM changes WHERE changes.changes_raports_id = raports.raports_id ORDER BY changes.changes_date DESC LIMIT 1) as last_change,
(SUM(injuries.injuries_min_procent) / COUNT(injuries_to_raports.injuries_to_raports_id)) as min,
(SUM(injuries.injuries_max_procent) / COUNT(injuries_to_raports.injuries_to_raports_id)) as max
FROM raports
LEFT JOIN users
ON users.users_id = raports.raports_users_id
LEFT JOIN changes
ON changes.changes_raports_id = raports.raports_id
LEFT JOIN raports_to_changes r1
ON r1.raports_to_changes_raports_id = raports.raports_id
LEFT JOIN injuries_to_raports
ON injuries_to_raports.injuries_to_raports_raports_id = r1.raports_to_changes_raports_id
LEFT JOIN injuries
ON injuries_to_raports.injuries_to_raports_injuries_id = injuries.injuries_id
WHERE r1.raports_to_changes_changes_id = (SELECT max(raports_to_changes_changes_id) FROM raports_to_changes r2 WHERE r2.raports_to_changes_raports_id = r1.raports_to_changes_raports_id)
GROUP BY raports.raports_id ORDER BY raports.raports_id ASC;
In columns max and min i have not correct average from injuries. When i checked it and count all injuries i had 36 when true number is 2 but i have 18 revisions. So is logic that i have looped COUNT with all revisions but i want only the newest
I try changing WHERE statements and more LEFT JOINs but nothing helped.
Could someone fixed that code?
Thank you in advanced
Based on the clues revealed by your queries, the data model may look like this:
The select list shows that you need:
users information of a reports_id
aggregated injuries_min_procent and injuries_max_procent at raports_id level. (see cte_raport_injuries)
number of changes of a raports_id (see cte_raport_changes)
the last change_date of a raports_id (see cte_raport_changes)
I'm not sure about the need for raports_of_changes based on information revealed in the question, so I'm going to ignore it for now.
with cte_raport_injuries as (
select r.raports_id,
sum(i.injuries_min_procent) / count(*) as injuries_min_procent,
sum(i.injuries_max_procent) / count(*) as injuries_max_procent
from raports r
join injuries_to_raports ir
on r.raports_id = ir.injuries_to_raports_raports_id
join injuries i
on ir.injuries_to_raports_injuries_id = i.injuries_id
group by r.raports_id),
cte_raport_changes as (
select r.raports_id,
count(c.changes_id) as changes,
max(c.changes_date) as last_change
from raports r
join changes c
on r.raports_id = c.changes_raports_id
group by r.raports_id)
select u.users_id,
r.raports_id,
ri.injuries_min_procent,
ri.injuries_max_procent,
rc.changes,
rc.last_change
from raports r
join users u
on r.raports_users_id = u.users_id
join cte_raport_injuries ri
on r.raports_id = ri.raports_id
join cte_raport_changes rc
on r.raports_id = rc.raports_id;
The result looks like this:
users_id|raports_id|injuries_min_procent|injuries_max_procent|changes|last_change|
--------+----------+--------------------+--------------------+-------+-----------+
1| 11| 15.0000| 25.0000| 2| 2022-12-02|
So my question for you is what's in reports_to_changes that you need and what's its relationship between others? For further involvement from the community, you may want to share the following information in text format:
DDLs of each tables (primary key, foreign key, column names & data types)
Some representable sample data and basic business rules
Expected output

Query to get data form different columns

I got a problem regarding my query, I cannot seem to get the right one to get the data I want. I've got the following tables I need to get data from:
app_exhibition
- id
- name
- form_id
app_forms
- id
- name
app_languages
- id
- name
- code
app_link_lang
- id
- form_id
- lang_id
I want to select the name of the exhibition (app_exhibition) the id and name of the form (app_forms) the name of the language (app_languages), and I know which one to select (language wise) because it's linked in the app_link_lang table.
Now I got the following query, but that is (obviously) not working..:
select f.form_id, f.name, b.name as beursnaam, l.name as languagename
FROM app_forms f, app_lang_link ll
WHERE f.id=1
LEFT JOIN app_beurzen b ON (b.form_id = f.id)
LEFT JOIN app_languages l ON ll.form_id = f.id
This should do the job:
SELECT e.name ename, f.id fid, f.name fname, l.name lname
FROM app_exhibition e
INNER JOIN app_forms f ON f.id=e.form_id
INNER JOIN app_link_lang al ON al.form_id=f.id
INNER JOIN app_languages l ON l.id=al.lang_id
You forgot to weave in the link table app_link_lang providing the m-to-n link. The result can now consist of several lines per exihibition, depending on the languages linked to it in app_link_lang.
Edit
I extended your fiddle (filled in some data) and it works, see here: http://sqlfiddle.com/#!9/a86be/1

Selecting columns using variables

Probably not the best description for a title but I really couldn't think of anything.
What I want to happen is that I can create a query that selects the type from listings using the userID as a relationship and then selecting the town.
TABLE listings
saleID userID type description
1 23 clothing nice clothing
2 45 clothing More nice Clothing
TABLE users
userID country county town
23 uk county townname1
24 uk county townname2
The variables are set in the url as a get eg) ?type=clothing&town=townname2
if (!isset($type)){
$query = "SELECT * FROM listings";
}
if (isset($type)) {
$query = "SELECT * FROM listings WHERE type = '{$type}'";
}
This is the bit i'm stuck on I want to get all listings with the variable $type 'clothing' and then select from users with the town of the variable $town
if (isset($town)) {
$query = "SELECT users.town listings.userID listings.type FROM listings
WHERE type = '{$type}'
INNER JOIN users
ON users.town = '{$town}'";
}
Hope I've explained this well enough to understand.
Please help me with this last query
SELECT u.town l.userID, l.type
FROM listings l
INNER JOIN users u on u.userID = l.userID
WHERE l.type = '{$type}'
AND u.town = '{$town}'
SELECT b.town, a.userID, a.type
FROM listings a
INNER JOIN users b
ON a.userID = b.userID
WHERE a.type = '{$type}' AND
b.town = '{$town}'
To further gain more knowledge about joins, visit the link below:
Visual Representation of SQL Joins
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?

How do i deal with this situation for searching records in mysql?

i am developing a PHP/MYSQL search module, where i have to search tables based on many different criteria, i have some 11 tables, and i have used multiple joins to create one single MySQL query and based on WHERE clause i intend to search for specific records, here is the MYSQL Query that i am using.
SELECT
prop.id,
prop.serial,
prop.title,
prop.rating,
prop.addDate,
prop.approve,
prop.status,
prop.user_id as userId,
user_det.email as email,
user_det.name as name,
prop.area_id as areaId,
area.name as areaName,
area.zipCode as zipCode,
area.city_id as cityId,
city.name as cityName,
city.state_id as stateId,
state.name as stateName,
state.country_id as countryId,
country.name as countryName,
prop.subCategory_id as subCategoryId,
subCat.name as subCategoryName,
subCat.category_id as categoryId,
cat.name as categoryName,
prop.transaction_id as transactionId,
trans.name as transactionName,
price.area as landArea,
price.price as priceSqFt,
price.total_price as totalPrice,
features.bedroom,
features.bathroom,
features.balcony,
features.furnished,
features.floorNum,
features.totalFloor
FROM properties prop
LEFT JOIN user_details user_det ON (prop.user_id = user_det.user_id)
LEFT JOIN areas area ON (prop.area_id = area.id)
LEFT JOIN cities city ON (area.city_id = city.id)
LEFT JOIN states state ON (city.state_id = state.id)
LEFT JOIN countries country ON (state.country_id = country.id)
LEFT JOIN subCategories subCat ON (prop.subCategory_id = subCat.id)
LEFT JOIN categories cat ON (subCat.category_id = cat.id)
LEFT JOIN transactions trans ON (prop.transaction_id = trans.id)
LEFT JOIN prop_prices price ON (price.property_id = prop.id)
LEFT JOIN prop_features features ON (features.property_id = prop.id)
although all works well here, i have a situation where i have a table called prop_amenities below are the content of this table.
as the table above have multiple property_id if i query it using JOINS then mostly it will return duplicate records or single record omitting others depending on the type of JOIN i use. so instead i would like to deal it this way.
use the table prop_amenities to only deal with conditions not to return the result.
for example i am searching for a property with amenity id 1,5,9,17 and 24, then it should check if all the records exist in the prop_amenities table, i.e 1,5,9,17 and 24 in this case. and return the appropriate records with all above selected columns.
i am clueless on dealing this situation using MySQL. how do i go on this?
thank you..
You said "check if all the records exist in the prop_amenities table" and that's the key word here.
SELECT ...
FROM properties AS prop
LEFT JOIN ...
WHERE EXISTS (SELECT 1 FROM prop_amenities AS pa WHERE pa.property_id = prop.property_id AND pa.amenity_id = 7);

I need to finalize this MySQL multiple table JOIN

I have entires, equipments, brands, times and seasons.
entries:
id
time
equipment_1
equipment_2
equipments:
id
id_brand
brands:
id
name
times:
id
id_season
seasons:
id
name
My actual SQL query is:
SELECT entries.*, times.id_season AS id_season
FROM entries, seasons
WHERE entries.time = times.id
But in the final query I need the next information that I don't know how to obtain it:
The name for each entries.equipment_ as equipment_1_name and equipment_2_name which is set in brands.name.
The name of the season as season_name.
Thank you in advance!
Assuming you have normalized data. This avoid costly cartesian joins. I never use cartesian joins myself, although there are some cases where they are useful. Not here, though.
SELECT
entries.*,
times.id_seasons AS id_season,
b1.name AS equipment_1_name,
b2.name AS equipment_2_name,
seasons.name AS season_name
FROM entries
LEFT JOIN equipments AS equipments_1
ON equipments_1.id = entries.equipment_1
LEFT JOIN brands AS brands_1
ON brands_1.id = equipments_1.id_brand
LEFT JOIN equipments AS equipments_2
ON equipments_2.id = entries.equipment_2
LEFT JOIN brands AS brands_2
ON brands_2.id = equipments_2.id_brand
LEFT JOIN times
ON times.id = entries.time
LEFT JOIN seasons
ON seasons.id = times.id_season;