Error in my MYSQL query? - mysql

Trying some queries on the database, but I have a problem. Can somebody help me with proper query?
This is what I need
SELECT
IdNews, Caption, NewsText, NumberOfViews, NumberOfComments,
PublishDate, CoinValue, category.IdNewsCategory,
NewsCategory, country.IdCountry, CountryName, news.IdUser,
FirstName, LastName, Picture, DateTimeUpCoin
FROM
news
INNER JOIN
category ON category.IdNewsCategory = news.IdNewsCategory
INNER JOIN
country ON news.IdCountry = country.IdCountry
INNER JOIN
user ON user.IdUser = news.IdUser
WHERE
news.IdCountry = 1
LIMIT 0, 10
ORDER BY
NumberOfViews DESC

You have written wrong query for Order by.
In query, LIMIT comes always last.
You need to write corrected query as per below :
SELECT
IdNews,Caption,NewsText,NumberOfViews,NumberOfComments,
PublishDate,CoinValue,category.IdNewsCategory,
NewsCategory,country.IdCountry,CountryName,news.IdUser,
FirstName, LastName,Picture, DateTimeUpCoin
FROM news
INNER JOIN category ON category.IdNewsCategory = news.IdNewsCategory
INNER JOIN country ON news.IdCountry = country.IdCountry
INNER JOIN user ON user.IdUser = news.IdUser
WHERE news.IdCountry = 1
ORDER BY NumberOfViews DESC
LIMIT 0, 10

IdCountry column is present in both the tables news and country. That's why it is showing error. Prepend table name before IdCountry in where clause. Put ORDER BY before LIMIT.
SELECT IdNews,Caption,NewsText,NumberOfViews,NumberOfComments,PublishDate,CoinValue,category.IdNewsCategory, NewsCategory,country.IdCountry,CountryName,news.IdUser,FirstName, LastName,Picture, DateTimeUpCoin
FROM news
INNER JOIN category ON category.IdNewsCategory = news.IdNewsCategory
INNER JOIN country ON news.IdCountry = country.IdCountry
INNER JOIN user ON user.IdUser = news.IdUser
WHERE news.IdCountry =1
ORDER BY NumberOfViews DESC
LIMIT 0 , 10

Related

How to fix query results not showing up?

I have a MySQL query which I want to execute to see who is the employee with the best skill X in a company I work for. To do this I randomly pick a company from my cv_profile (skill_cv_test) and find all users who work there for the same employer. And then I randomly choose a skill I have.
The result should either be zero or a list.
But when testing with PHPMyAdmin I get results where I don't see any row, but the status says there is at least one row.
Here's an example of the message I get: https://imgur.com/bVMH716
I have been trying different structures, even "walling" the query with another query, different joins.
SELECT
DISTINCT(sv.usr_id),
u.first_name AS fn,
u.last_name AS ln,
c.name AS company,
s.name AS skill
FROM
(
SELECT
MAX(last_change) as date,
id,
usr_id,
skill_id
FROM skill_valuations
GROUP BY usr_id, skill_id
ORDER BY date
) sv
LEFT JOIN skill_valuations skv ON skv.last_change = sv.date
INNER JOIN
(
SELECT
DISTINCT(skct.comp_id),
skct.usr_id AS usr_id,
skct.category
FROM skill_cv_test skct
WHERE skct.end_date IS NULL AND skct.comp_id IN (SELECT comp_id FROM (SELECT comp_id FROM skill_cv_test WHERE usr_id = 1 ORDER BY RAND() LIMIT 1) x)
) uqv ON uqv.usr_id = sv.usr_id
INNER JOIN
(
SELECT skill_id
FROM usr_skills
WHERE usr_id = $uid
ORDER BY RAND()
LIMIT 1
) usq ON usq.skill_id = sv.skill_id
LEFT JOIN companies c ON c.id = uqv.comp_id
LEFT JOIN skills s ON s.id = sv.skill_id
LEFT JOIN users u ON u.id = sv.usr_id
As mentioned before, I expect either no results or a result of at least one row.

SQL multiple join tidy up

I have this statement:
SELECT board.*,numlikes
FROM board
LEFT JOIN (
SELECT pins.board_id, COUNT(source_user_id) AS numlikes
FROM likes
INNER JOIN pins ON pins.id = likes.pin_id
GROUP BY pins.board_id
) likes ON board.id = likes.board_id
WHERE who_can_tag=''
ORDER BY numlikes DESC
LIMIT 10
I can then extract rows from board using ".$info['board_name'].".
However, I'm not good with multiple joins and I need to join another table to this besides the board and likes tables.
The third table is user and matches to board.user_id with user.user_id.
how can I then use this data to extract a username from user?
Wouldn't ".$info['username']." search for the field username in the table board still?
This will do what you want:
SELECT board.*,
`user`.username,
numlikes
FROM board
INNER JOIN `user` ON board.user_id = `user`.user_id
LEFT JOIN (
SELECT pins.board_id, COUNT(source_user_id) AS numlikes
FROM likes
INNER JOIN pins ON pins.id = likes.pin_id
GROUP BY pins.board_id
) likes ON board.id = likes.board_id
WHERE who_can_tag=''
ORDER BY numlikes DESC
LIMIT 10

Order by most of items with Join

I've a 'items' table with the following structure:
id, person_id, active
and 'people' table with id and name columns.
I want to order by most active items and join the people.name column to sql.
I tried to do something like that, but it's not working:
SELECT people.id, COUNT(*) as items_count
FROM items, people
WHERE items.active = true AND people.id = items.person_id
GROUP BY items.person_id
ORDER BY items_count DESC
Use Joins this will match the condition. Order by items_count will give you most active user
Select people.id, COUNT(items.active) as items_count
FROM items
LEFT JOIN people on people.id = items.person_id
WHERE items.active = true
GROUP BY people.id
ORDER BY items_count DESC
select * from (SELECT people.id, COUNT(*) as items_count
FROM items
left outer join people on people.id = items.person_id
where items.active = true
GROUP BY items.person_id) as A
ORDER BY A.items_count DESC

MySQL query and count from other table

I would like to get the data from one table, and count all results from other table, depending on the first table data, here is what I tried:
SELECT
cars.*, (
SELECT
COUNT(*)
FROM
uploads
WHERE
uploads.cid = cars.customer
) AS `count`,
FROM
`cars`
WHERE
customer = 11;
I dont really have an idea why its not working, as I'm not a regular MySQL user/coder...
Could anyone direct me in the right direction with this one?
SELECT
c.*, COUNT(u.cid) AS count
FROM
cars c
LEFT JOIN
uploads u
ON
u.cid=c.customer
WHERE
u.customer = 11;
GROUP BY c.cid
Try it by joining both tables using LEFT JOIN
SELECT a.customer, COUNT(b.cid) totalCount
FROM cars a
LEFT JOIN uploads b
ON a.customer = b.cid
WHERE a.customer = 11
GROUP BY a.customer
using COUNT(*) in LEFT JOIN will have records to have a minimum count of 1.
SELECT cars.*,COUNT(uploads.*) as uplloaded
from cars
left outer join uploads on uploads.cid = cars.customer
where cars.customer = 11
group by uploads.cid;
Try this :
SELECT customer, COUNT(cid) totalCount
FROM cars
INNER JOIN uploads
ON (customer = cid)
WHERE customer = 11
GROUP BY customer

MySQL how to select 1 if MAX() equals current row SUM() aggregate value?

I'd like to select a new column named sliced (value can be 1/0 or true/false it doesn't matter) if area of the current row equals MAX(SUM(c.area)), that is flag the row with highest aggregate value:
SELECT p.name AS name, SUM(c.area) AS area
FROM City AS c
INNER JOIN Province AS p ON c.province_id = p.id
INNER JOIN Region AS r ON p.region_id = r.id
WHERE r.id = ?
GROUP BY p.id
ORDER BY p.name ASC
I've tried adding to the selection area = MAX(area) AS sliced or even area = SUM(MAX(c.area)) AS sliced but i'm getting a syntax error. I've to admit i'm not so good in SQL. Thank you.
As I understand your question, this should do it. Creates a pseudo-column which returns 1 when the area is the same as max(area) without any conditions to restrict your selection.
SELECT name
, area
, case area when max_area then 1 else 0 end as sliced
FROM ( SELECT name
, area
, max(area) over (partition by 1) as max_area
FROM ( SELECT p.name AS name
, SUM(c.area) AS area
FROM City AS c
INNER JOIN Province AS p ON c.province_id = p.id
INNER JOIN Region AS r ON p.region_id = r.id
WHERE r.id = ?
GROUP BY p.id
ORDER BY p.name ASC )
)
EDIT As #Glide says you can't perform nested aggregation so sum(max(area)) won't work and you need to perform these operations one query at a time.
Here's a way to do it with just one group by:
set #row := 0;
select name, area, sliced
from (
select name, area, (#row := #row + 1) = 1 as sliced
from (
SELECT p.name, SUM(c.area) AS area
FROM City AS c
INNER JOIN Province AS p ON c.province_id = p.id
INNER JOIN Region AS r ON p.region_id = r.id
WHERE r.id = ?
GROUP BY 1
ORDER BY 2 desc) t1
) t2
order by 1;
The inner query (t1) does the group by and orders by total area largest first.
The next query (t2) gives the first row a value of true for column sliced, all other rows false.
The outer query orders the rows in the way you want - by name.
Since there's only one table scan and group by, this should be very efficient.
As comments have mentioned, you'd have to check all the values against another query. This is normal practice in SQL.
SELECT
p.name AS name,
SUM(c.area) AS area,
CASE WHEN SUM(c.area) = (SELECT MAX(area) FROM <repeat your query here>) THEN 1 ELSE 0 END
FROM
City AS c
INNER JOIN
Province AS p
ON c.province_id = p.id
INNER JOIN
Region AS r
ON p.region_id = r.id
WHERE
r.id = ?
GROUP BY
p.id
ORDER BY
p.name ASC
The biggest downside to this is that you've had to repeat the code, which is just messy and a maintenance headache.
The alternative is to insert all the data into a temporary table, with the sliced field being 0 for all records. Then update that table, setting sliced to 1 for the record(s) with the highest area.