Inserting Data into a table using subquery - mysql

I am trying to insert data using a subquery. I am only going to post my SELECT statement below.
SELECT PlaylistCode
FROM Playlists
WHERE Name_Of_Playlist = 'X'
AND
(SELECT Code
FROM Songs
INNER JOIN Artists ON Artists.PageURL = Songs.PageURL
WHERE Artist = 'X'
LIMIT 200)
Error Code: 1242. Subquery returns more than 1 row 0.016 sec

Try to Below Query
SELECT PlaylistCode
FROM Playlists
WHERE exits
(SELECT Code
FROM Songs
INNER JOIN Artists ON Artists.PageURL = Songs.PageURL
WHERE Artist = 'X'
LIMIT 200) and Name_Of_Playlist = 'X'

Based on your requirements, you need to use select case then join corresponding tables
INSERT INTO Playlists (PlaylistCode)
SELECT CASE WHEN a.Artist = 'X' THEN 'X' ELSE s.Code END
FROM Songs s
INNER JOIN Artists a ON a.PageURL = s.PageURL

Related

MySQL: Invalid use of group function updating two columns with update/select

I am trying to update two columns within a table from a select statment in MySQL 5.7.
The error I get is "invalid use of group function"
Stmt:
UPDATE
catalog mpc
JOIN
reviews mpr ON mpr.merchant_id = mpc.MERCHANT_ID and mpr.sku = mpc.ARTICLE_ID
SET
mpc.RATING = avg(mpr.rating),
mpc.RATINGS = count(mpr.rating)
WHERE
mpr.MERCHANT_ID = 1
AND mpr.sku = '133';
It looks about right to me, what could be the problem here?
You must aggregate first in reviews and then join to catalog:
UPDATE catalog mpc
INNER JOIN (
SELECT merchant_id, sku, AVG(rating) avg_rating, COUNT(rating) count_rating
FROM reviews
WHERE merchant_id = 1 AND sku = '133'
GROUP BY merchant_id, sku
) mpr ON mpr.merchant_id = mpc.MERCHANT_ID and mpr.sku = mpc.ARTICLE_ID
SET mpc.RATING = mpr.avg_rating,
mpc.RATINGS = mpr.count_rating

MYSQL - CONCATENATE a lookup tables columns into one row

I have the following table structure:
tbl_catalogue_state
In tbl_catalogue there is a part number 58674 that has three states in the tbl_catalogue_state_lk table. Here is the result when I run a query inner joining the three tables.
As expected there are multiple rows returned.
Is there a way to only return one row having the values for each catalgue_state_id on the same row?
I would also like the ability to ignore a row for example:
select tbl_catalogue.catalogue_part, tbl_catalogue_state.catalogue_state_id from tbl_catalogue
inner join tbl_catalogue_state_lk on tbl_catalogue.catalogue_id = tbl_catalogue_state_lk.catalogue_id
inner join tbl_catalogue_state on tbl_catalogue_state_lk.catalogue_state_id = tbl_catalogue_state.catalogue_state_id
where tbl_catalogue_state_lk.catalogue_state_id <> 1;
The above select still returns two rows.
UPDATE
I was able to use GROUP_CONCAT:
select tbl_catalogue.catalogue_part, GROUP_CONCAT(tbl_catalogue_state.catalogue_state_id) as cat_state from tbl_catalogue
inner join tbl_catalogue_state_lk on tbl_catalogue.catalogue_id = tbl_catalogue_state_lk.catalogue_id
inner join tbl_catalogue_state on tbl_catalogue_state_lk.catalogue_state_id = tbl_catalogue_state.catalogue_state_id
where tbl_catalogue_state_lk.catalogue_state_id <> 1
group by tbl_catalogue.catalogue_id;
My issue is the above statement still returns a row. I need it to return nothing.
I was able to use not exists:
select tc.catalogue_part, GROUP_CONCAT(tcs.catalogue_state_id) as cat_state from tbl_catalogue as tc
inner join tbl_catalogue_state_lk as tcsl on tc.catalogue_id = tcsl.catalogue_id
inner join tbl_catalogue_state as tcs on tcsl.catalogue_state_id = tcs.catalogue_state_id
where
not exists
(
select tcsl2.catalogue_state_id from tbl_catalogue_state_lk as tcsl2
where tcsl2.catalogue_state_id = 6 and tcsl2.catalogue_id = tc.catalogue_id
)
and
not exists
(
select tcsl3.catalogue_state_id from tbl_catalogue_state_lk as tcsl3
where tcsl3.catalogue_state_id = 1 and tcsl3.catalogue_id = tc.catalogue_id
)
and
not exists
(
select tcsl3.catalogue_state_id from tbl_catalogue_state_lk as tcsl3
where tcsl3.catalogue_state_id = 2 and tcsl3.catalogue_id = tc.catalogue_id
)
group by tc.catalogue_id;

SQL counting different column values

I have a table called spider_status which has a status_code and a locationid. I am retrieving all cities from region_select_city which I joined in the code below. Now I am trying to count all the unique values in status_code in the table spider_status grouping by cities.
SELECT region_select_city.name as stad , COUNT(spider_status.id) as spider_aantal,
CASE WHEN spider_status.status_code = 1 THEN COUNT(spider_status.status_code) ELSE 0 END as LIVE
FROM
spider_status
JOIN
location
ON spider_status.location_id = location.id
JOIN
location_select_addressid
ON location.id = location_select_addressid.locationid
JOIN
location_address
ON location_select_addressid.addressid = location_address.id
JOIN
region_select_city
ON location_address.city_id = region_select_city.id
JOIN
spider_status_code
ON spider_status.status_code = spider_status_code.id
WHERE spider_status.current = 1
GROUP BY region_select_city.name
Hope the following code help you to solve the issue
SELECT count(DISTINCT s.status_code)
FROM spider_status AS s
JOIN location AS l
ON l.locationid = s.locationid
JOIN location_address AS loc_add
ON loca_add.locationid = loc_add.locationid
GROUP BY loc_add.city_id
At the end of the 2nd last line, should the AND be there?

How to query mysql to select and group by multiple values

I'm trying to select and group by all the contentid values of the table below where the match criteria can be several different values.
the contentid values actually represent cars, so I need to select [and group by] all the contentis where the values are 'GMC' and the values are 'sedan' and the value is 'automatic.
i.e. I'm trying to select all the GMC sedans with an automatic transmission.
a query like this fails [obviously]:
select * from modx_site_tmplvar_contentvalues WHERE
`value` = 'gmc' and
`value` = 'tacoma'
group by contentid
I have no idea how to create a query like that. Any suggestions?
You need to "pivot" these data on "tmplvarid", but unfortunately for you MySQL doesn't have a PIVOT statement like other RDBMS. However, you can pivot it yourself by joining in the table multiple times for each variable you care about:
SELECT
contents.contentid,
transmission.value as transmission,
type.value as type,
make.value as make
FROM
(SELECT DISTINCT contentid FROM modx_site_tmplvar_contentvalues) AS contents
LEFT JOIN
modx_site_tmplvar_contentvalues AS transmission
ON contents.contentid = transmission.contentid
AND transmission.tmplvarid = 33 -- id for transmission
LEFT JOIN
modx_site_tmplvar_contentvalues AS make
ON contents.contentid = make.contentid
AND make.tmplvarid = 13 -- id for make
LEFT JOIN
modx_site_tmplvar_contentvalues AS type
ON contents.contentid = type.contentid
AND type.tmplvarid = 17 -- id for type
WHERE
type.value = 'sedan'
AND make.value = 'GMC'
AND transmission.value = 'automatic'
You can expand this with additional joins for other criteria such as year (id 15) or mileage (id 16).
If you need to use the value only, you could try:
SELECT DISTINCT
contents.contentid,
transmission.value as transmission,
type.value as type,
make.value as make
FROM
(SELECT DISTINCT contentid FROM modx_site_tmplvar_contentvalues) AS contents
INNER JOIN
modx_site_tmplvar_contentvalues AS transmission
ON contents.contentid = transmission.contentid
AND transmission.value = 'automatic'
INNER JOIN
modx_site_tmplvar_contentvalues AS make
ON contents.contentid = make.contentid
AND make.value = 'GMC'
INNER JOIN
modx_site_tmplvar_contentvalues AS type
ON contents.contentid = type.contentid
AND type.value = 'sedan'
In any case, make sure you have an index on the value column; these queries are going to get slow.
please try this:
SELECT *
FROM modx_site_tmplvar_contentvalues t1 INNER JOIN modx_site_tmplvar_contentvalues t2 ON t1.contentid = t2.content_id
WHERE
t1.`value` = 'gmc'
AND t2.`value` = 'tacoma';
You can do this with a group by. This is the most flexible in terms of expressing the conditions. In MySQL, multiple joins will often perform better:
select contentid
from modx_site_tmplvar_contentvalues
group by contentid
having sum(`value` = 'gmc') > 0 and
sum(`value` = 'tacoma') > 0;
This is always false:
`value` = 'gmc' and
`value` = 'tacoma'
Instead, use OR:
`value` = 'gmc' OR
`value` = 'tacoma'
In a condition "and" means "this and this is true at the same time". If you want all foos and all bars, then your condition is "foo OR bar".
EDIT:
To select groups containing your values, you can write subqueries:
SELECT DISTINCT name FROM table WHERE name IN (SELECT name FROM table WHERE value='value1') AND name IN (SELECT name FROM table WHERE value='value2')

MySQL combine UPDATE and SELECT query

I have the following SELECT statement that returns data, example below:
SELECT performers.ID,
performers.Name,
COUNT(*) AS CountOfDeals,
COUNT(DISTINCT(deals.Name)) AS CountOfAliases
FROM deals RIGHT JOIN performers
ON deals.name LIKE CONCAT('%', performers.name, '%')
WHERE performers.ID IN ( 27952, 27951, 27950, 27949, 27948 )
GROUP BY Name;
Example data returned:
ID Name CountOfDeals CountOfAliases
27952 Christine Hoberg 1 0
27951 Indian Jewelry 1 0
27952 Kinky Friedman 5 3
27949 KJ-52 1 0
27960 River Whyless 1 0
I want to combine this with the following UPDATE statement
UPDATE performers
SET RawAliasCount = CountOfAliases,
RawDealCount = CountOfDeals
WHERE ID = ?
All the values needed to run the update statement are returned in the select statement above so hopefully this should be pretty easy.
Thanks.
Use update with join:
UPDATE performers p JOIN
(SELECT performers.ID, performers.Name, COUNT(*) AS CountOfDeals,
COUNT(DISTINCT(deals.Name)) AS CountOfAliases
FROM deals RIGHT JOIN
performers
on deals.name LIKE CONCAT('%', performers.name, '%')
WHERE performers.ID IN (27952, 27951, 27950, 27949, 27948)
GROUP BY Name
) pp
ON pp.id = p.id
SET RawAliasCount = pp.CountOfAliases,
RawDealCount = pp.CountOfDeals;
UPDATE performers
SET performers.RawAliasCount = count_table.CountOfAliases, performers.RawDealCount = count_table.CountOfDeals
FROM performers
INNER JOIN
(
SELECT
performers.ID, performers.Name, COUNT(*) AS CountOfDeals,
COUNT(DISTINCT(deals.Name)) AS CountOfAliases
FROM deals RIGHT JOIN performers on deals.name LIKE CONCAT('%', performers.name, '%')
WHERE performers.ID IN (27952, 27951, 27950, 27949, 27948)
GROUP BY Name
) count_table
ON count_table.ID = performers.ID;
When this type of question is asked, thank you to put the tables schema.
edit : sorry, it's sql-server syntax.