I need to write query that joins several tables and I need distinct value from one table based on max count().
These are my tables names and columns:
bands:
db|name|
releases_artists:
release_db|band_db
releases_styles
release_db|style
Relations between tables are (needed for JOINs):
releases_artists.band_db = bands.db
releases_styles.release_db = releases_artists.release_db
And now the query that I need to write:
SELECT b.name, most_common_style
LEFT JOIN releases_artists ra ON ra.band_db = b.db
and here I need to find the most common style from all band releases
JOIN(
SELECT DISTINCT style WHERE releases_styles.release_db = ra.release_db ORDER BY COUNT() DESC LIMIT 1
)
FROM bands b
WHERE b.name LIKE 'something'
This is just a non working example of what I want to accomplish. It would be great if someone could help me build this query.
Thanks in advance.
EDIT 1
Each artist from table bands can have multiple records from releases_artists table based on band_db and each release can have multiple styles from releases_styles based on release_db
So if I search for b.name LIKE '%ray%' it returns something similar to:
`bands`:
o7te|Ray Wilson
9i84|Ray Parkey Jr.
`releases_artists` for Ray Wilson:
tv5c|o7te (for example album `Change`)
78wz|o7te (`The Next Best Thing`)
nz7c|o7te (`Propaganda Man`)
`releases_styles`
tv5c|Pop
tv5c|Rock
tv5c|Alternative Pop/Rock
----
78wz|Rock
78wz|Pop
78wz|Classic Rock
I need style name that repeats mostly from all artist releases as this artist main style.
Ok, this is a bit of a hack. But the only alternatives I could think of involve heaps of nested subqueries. So here goes:
SELECT name
, SUBSTRING_INDEX(GROUP_CONCAT(style ORDER BY release_count DESC SEPARATOR '|'), '|', 1) AS most_common_style
FROM (
SELECT b.db
, b.name
, rs.style
, COUNT(*) AS release_count
FROM bands b
JOIN releases_artists ra ON ra.band_db = b.db
JOIN releases_styles rs ON rs.release_db = ra.release_db
GROUP BY b.db, rs.style
) s
GROUP BY db;
Related
We have two tables one is properties and another one is property meta when we are getting data from one table "properties" , query only take less then one second in execution but when we are use join to get the data using bellow query from both tables its taking more then 5 second to fetch the data although we have only 12000 record in the tables , i think there is an issue in the sql query any help or suggestion will be appreciated.
SELECT
u.id,
u.property_title,
u.description,
u.city,
u.area,
u.address,
u.slug,
u.latitude,
u.longitude,
u.sync_time,
u.add_date,
u.is_featured,
u.pre_construction,
u.move_in_date,
u.property_status,
u.sale_price,
u.mls_number,
u.bedrooms,
u.bathrooms,
u.kitchens,
u.sub_area,
u.property_type,
u.main_image,
u.area_size as land_area,
pm7.meta_value as company_name,
pm8.meta_value as virtual_tour,
u.year_built,
u.garages
FROM
tbl_properties u
LEFT JOIN tbl_property_meta pm7
ON u.id = pm7.property_id
LEFT JOIN tbl_property_meta pm8
ON u.id = pm8.property_id
WHERE
u.status = 1
AND (pm7.meta_key = 'company_name')
AND (pm8.meta_key = 'virtual_tour')
AND (
(
( u.city = 'Delta'
OR u.post_code LIKE '%Delta%'
OR u.sub_area LIKE '%Delta%'
OR u.state LIKE '%Delta%')
AND country = 'Canada'
)
OR (
( u.city = 'Metro Vancouver Regional District'
OR u.post_code LIKE '%Metro Vancouver Regional District%'
OR u.sub_area LIKE '%Metro Vancouver Regional District%'
OR u.state LIKE '%Metro Vancouver Regional District%' )
AND country = 'Canada'
)
)
AND
u.pre_construction ='0'
GROUP BY
u.id
ORDER BY
u.is_featured DESC,
u.add_date DESC
Try adding this compound index:
ALTER TABLE tbl_property_meta ADD INDEX id_key (property_id, meta_key);
If it doesn't help make things faster, try this one.
ALTER TABLE tbl_property_meta ADD INDEX key_id (meta_key, property_id);
And, you should know that column LIKE '%somevalue' (with a leading %) is a notorious performance antipattern, resistant to optimization via indexes. (There's a way to create indexes for that shape of filter in PostgreSQL, but not in MariaDB / MySQL.)
Add another column with the meta stuff; throw city, post_code, sub_area, and state and probably some other things into it. Then build a FULLTEXT index on that column. Then use MATCH(..) AGAINST("Delta Metro Vancouver Regional District") in the WHERE clause _instead of the LEFT JOINs (which are actually INNER JOINs) and the really messy part of the WHERE clause.
Also, the GROUP BY is probably unnecessary, thereby eliminating extra sort on the intermediate set of rows.
I have a SQL query that links 2 tables to provide the data if a horse is in both the tables:
SELECT ProformSystem.TheDate as racedate,
ProformSystem.Course as course,
ProformSystem.TheTime as thetime,
ProformSystem.Horse as horse,
ATRSpeedRatings.rank as rank
FROM ATRSpeedRatings
INNER JOIN ProformSystem ON (ATRSpeedRatings.Horse = trim(ProformSystem.Horse)) AND (ATRSpeedRatings.TheDate = ProformSystem.TheDate) order by ProformSystem.TheTime;"
Is it possible that if the horse in ProformSystem.Horse is NOT in ATRSpeedRatings.Horse then I just make rank = 0 as a default value, or would I need to run a separate query?
This way I can display all horses from ProformSystem even if they don't have a rank in ATRSpeedRatings.
I think you want a left join and coalesce():
SELECT ps.TheDate as racedate, ps.Course as course, ps.TheTime as thetime,
ps.Horse as horse, COALESCE(sr.rank, 0) as rank
FROM ProformSystem ps LEFT JOIN
ATRSpeedRatings sr
ON sr.Horse = TRIM(ps.Horse) AND sr.TheDate = ps.TheDate)
ORDER BY ps.TheTime;
Note that this query uses table aliases. These make the query easier to write and to read.
Also, the JOIN condition sr.Horse = trim(ps.Horse) is highly suspect. You should fix the data so there are no spaces in ProformSystem. Fixing the data is more efficient and it will prevent problems on future queries.
I am having some strange issue with the SQL statement below. The result groups by user IDs and some of them turn out right but for one of them (user ID = 1) the "initial_average" is multiplied by 3. I really have no idea why.. Is there something wrong with the structure of the statement? If it is not clear, the aim is to sum the field "initial_avg" in the "tasks" table and have it broken out by user. Some help with this is much appreciated. I am using MySQL.
SELECT sum(initial_avg) AS initial_average
, sum(initial_std) AS initial_standard_dev
, tasks.user
, hourly_rate
FROM tasks
INNER JOIN user_project
ON tasks.user=user_project.user
AND tasks.project=59
AND tasks.user=1
GROUP BY tasks.user
I just solved it by adding another "and" clause (AND user_project.project=59 )
Optimize your query (Try it):
SELECT SUM(initial_avg) AS initial_average, SUM(initial_std) AS initial_standard_dev, tasks.user, hourly_rate FROM tasks INNER JOIN user_project ON tasks.user = user_project.user AND tasks.project = User_project.project WHERE tasks.project = 59 AND tasks.user = 1 GROUP BY tasks.user, hourly_rate
I need to select the first row of a database joined with another main database.
The main database collects informations about dogs, their race, size, name eccc…
The joined database is linked to the frist and provide dog’s images.
Each dog has different images, more than one.
In the list page of the dogs, I need to show, for each dog, all dog’s details and only the frist image of the joined database, as it was the profile image.
So here u are the structure of the two databases:
//dog_pages database:
id
--
slug
--
name
--
race
--
size
--
description
--
created
--
updated
and:
//dog_images database:
id
--
dog_page_id //this is for the join
--
content
--
img_title
--
img_url
--
img_ftp_path
--
thumb_ftp_path
--
thumb_delete_path
I use this code to generate the query:
SELECT dog_pages.id, dog_pages.slug, dog_pages.name, dog_pages.race, dog_pages.size, dog_pages.description, dog_pages.created, dog_pages.updated, dog_images.id, dog_images.dog_page_id, dog_images.img_url, dog_images.thumb_ftp_path, dog_images.content AS image_content
FROM dog_pages
LEFT JOIN dog_images
ON dog_pages.id = (
SELECT dog_images.dog_page_id
FROM dog_images
WHERE dog_pages.id = dog_images.dog_page_id
LIMIT 1
)
Unfortunately this doesn’t work, the results is to have more than one image for each dog. I needjust one, that in the frist row of the dog_images.
There are multiple methods (including variables). But, taking your method, you can use an aggregation function instead of limit:
SELECT p.id, p.slug, p.name, p.race, p.size, p.description, dog_pages.created, p.updated,
i.id, i.dog_page_id, i.img_url, i.thumb_ftp_path, dog_images.content AS image_content
FROM dog_pages p LEFT JOIN
dog_images i
ON p.id = i.dog_page_id AND
i.id = (SELECT MIN(i2.id)
FROM dog_images i2
WHERE p.id = i2.dog_page_id
);
In the second select you are choosing only Id for joining and you can replace it just with
..=dog_images.dog_page_id
It's exactly what you get from the select
To solve the problem try to use group by dog_pages_I'd
And you should get information only about one image
Here is a brief explanation of what I'm trying to accomplish; my query follows below.
There are 4 tables and 1 view which are relevant for this particular query (sorry the names look messy, but they follow a strict convention that would make sense if you saw the full list):
Performances may have many Performers, and those associations are stored in PPerformer. Fans can have favorites, which are stored in Favorite_Performer. The _UpcomingPerformances view contains all the information needed to display a user-friendly list of upcoming performances.
My goal is to select all the data from _UpcomingPerformances, then include one additional column that specifies whether the given Performance has a Performer which the Fan added as their favorite. This involves selecting the list of Performers associated with the Performance, and also the list of Performers who are in Favorite_Performer for that Fan, and intersecting the two arrays to determine if anything is in common.
When I execute the below query, I get the error #1054 - Unknown column 'up.pID' in 'where clause'. I suspect it's somehow related to a misuse of Correlated Subqueries but as far as I can tell what I'm doing should work. It works when I replace up.pID (in the WHERE clause of t2) with a hard-coded number, and yes, pID is an existing column of _UpcomingPerformances.
Thanks for any help you can provide.
SELECT
up.*,
CASE
WHEN EXISTS (
SELECT * FROM (
SELECT RID FROM Favorite_Performer
WHERE FanID = 107
) t1
INNER JOIN
(
SELECT r.ID as RID
FROM PPerformer pr
JOIN Performer r ON r.ID = pr.Performer_ID
WHERE pr.Performance_ID = up.pID
) t2
ON t1.RID = t2.RID
)
THEN "yes"
ELSE "no"
END as pText
FROM
_UpcomingPerformances up
The problem is scope related. The nested Selects make the up table invisible inside the internal select. Try this:
SELECT
up.*,
CASE
WHEN EXISTS (
SELECT *
FROM Favorite_Performer fp
JOIN Performer r ON fp.RID = r.ID
JOIN PPerformer pr ON r.ID = pr.Performer_ID
WHERE fp.FanID = 107
AND pr.Performance_ID = up.pID
)
THEN 'yes'
ELSE 'no'
END as pText
FROM
_UpcomingPerformances up