MySQL Error in Nested Query - php

I have the following code in PHP:
SELECT (
SELECT (
SELECT `forum_posts.id`,`forum_posts.author`,`forum_posts.author_id`, `forum_boards.date`, MIN(`forum_posts.date`) FROM `forum_posts`
WHERE `parent` IN
(SELECT `id` FROM `forum_boards` WHERE `parent`="'.Oflow(intval((isset($_GET['id']) ? $_GET['id'] : '0'))).'")
INNER JOIN `forum_boards`
ON `forum_boards.id`=`forum_posts.id`
ORDER BY `update_date` DESC
LIMIT 1
GROUP BY `parent`;
) ORDER BY `order_large`,`order`;
) UNION (
SELECT `name`,`id`,`info`,`parent_name` FROM `forum_boards` WHERE `parent`="'.Oflow(intval((isset($_GET['id']) ? $_GET['id'] : '0'))).'" ORDER BY `order_large`,`order
)
This is a script to get a list of boards and posts in a forum system. What it's supposed to do is get data from a table "boards" and "posts". It then tries to find the most recent post in the sub-board of the board currently being viewed. Then, it tries to join the "parent" and board "id" togeather, in order that the columns can be matched and the posts be sorted accordingly. Finally, a UNION is performed to combine the newly found and ordered posts with the actual forum data.
The error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INNER JOIN forum_boards ON forum_boards.id=forum_posts.id ORDER BY' at line 7
The problem is, it don't work! I've double checked every column and table name, and they all exist. This is a very "alpha" code, so if you have any efficiency tips that's be great.

You can't INNER JOIN in the WHERE clause which is what your query is trying to do
SELECT (
SELECT (
SELECT `forum_posts.id`,`forum_posts.author`,`forum_posts.author_id`, `forum_boards.date`, MIN(`forum_posts.date`) FROM `forum_posts`
WHERE `parent` IN
(SELECT `id` FROM `forum_boards` WHERE `parent`="'.Oflow(intval((isset($_GET['id']) ? $_GET['id'] : '0'))).'")
INNER JOIN `forum_boards` ## This is effectively JOINing within a WHERE clause
ON `forum_boards.id`=`forum_posts.id`
ORDER BY `update_date` DESC
LIMIT 1
GROUP BY `parent`;
) ORDER BY `order_large`,`order`;
) UNION (
SELECT `name`,`id`,`info`,`parent_name` FROM `forum_boards` WHERE `parent`="'.Oflow(intval((isset($_GET['id']) ? $_GET['id'] : '0'))).'" ORDER BY `order_large`,`order
)
You might need to rethink your query a little bit.

Related

Solution for "Subquery returns more than 1 row"

I'm trying to substitute my join SQL code to a different code without any of JOIN statements for faster data retrieval. However, i'm getting the error below.
#1242 - Subquery returns more than 1 row
What i would like to do, get all rows from one table 'tbl_my_itemlist' and JOIN to other more tables, tbl_register and tbl_register without using JOIN statements.
The Code using JOIN statement (works fine).
SELECT
tbl_screenshots.screenshot_image_url,
mit.my_itemlist_id,
mit.item_name,
mit.item_initial_cost,
mit.item_offer_cost,
mit.offer_date_from,
mit.offer_date_to
FROM
(
SELECT
my_itemlist_id
FROM
tbl_my_itemlist
WHERE
offer_date_from >='2020-10-20' AND offer_date_to <= '2020-10-30' AND
item_deleted_status = 'active'
) mlist
JOIN tbl_my_itemlist mit ON
mit.my_itemlist_id = mlist.my_itemlist_id
RIGHT JOIN tbl_screenshots ON mit.my_itemlist_id =
tbl_screenshots.my_itemlist_id
RIGHT JOIN tbl_register ON tbl_register.register_id = mit.register_id
GROUP BY
mit.my_itemlist_id
ORDER BY mit.offer_date_to ASC LIMIT 2
The code i'm substituting the JOIN statement code with.
SELECT
mit.my_itemlist_id,
mit.item_name,
mit.item_initial_cost,
mit.item_offer_cost,
mit.offer_date_from,
mit.offer_date_to,
(
SELECT
reg.business_name
FROM
tbl_register reg
WHERE
reg.register_id = mit.register_id
) reg_sql,
(
SELECT
sshots.screenshot_image_url
FROM
tbl_screenshots sshots
WHERE
sshots.my_itemlist_id = mit.my_itemlist_id
) sshots_sq
FROM
tbl_my_itemlist mit
WHERE
mit.offer_date_from >= '2020-10-20' AND mit.offer_date_to <= '2020-10-30' AND mit.item_deleted_status = 'active'
GROUP BY
mit.my_itemlist_id
ORDER BY
mit.offer_date_to ASC
LIMIT 2
I'm trying to build an SQL query that can retrieve data from million records within very short period of time as compared to using the JOIN statement.

MYSQL SELECT including COUNT within the same table with reference to specific column

So, I'm getting data from one table with a simple SELECT statement with SELECT COUNT included.
SELECT *,
(SELECT COUNT(`message_id`)
FROM `user_message`
WHERE `status_to` = 0
) AS `unread`
FROM `user_message`
Here, unread counts for unread messages coming from other users. But that's not quite enough. What I want is to reference SELECT COUNT to a specific column, user_id, within the same table:
SELECT *,
(SELECT COUNT(`message_id`)
FROM `user_message`
WHERE `status_to` = 0 AND `user_message`.`user_id` = `user_message`.`user_id`
) AS `unread`
FROM `user_message`
.. if that makes sense. My second statement disregards this part: AND user_message.user_id = user_message.user_id, and gives me the same result for each user_id.
What am I missing??
You need to give different aliases to your table to get the related count
SELECT *, (
SELECT COUNT(`message_id`)
FROM `user_message` b
WHERE `status_to` = 0
AND `a`.`user_id` = `b`.`user_id`
) AS `unread`
FROM `user_message` a

Mysql error in a count query which counts a union subquery

Can you please check this mysql query and maybe help with what's wrong with it?
When I run it through mysql as my host i get this error:
#1248 - Every derived table must have its own alias
Here is the code:
mysql_query("
SELECT COUNT(*)
FROM
(
(SELECT 1 as sort_col,id,pic0 FROM `cronjob_reloaded` WHERE id IS NOT NULL AND id LIKE '%car%')
UNION
(SELECT 2 as sort_col,id,pic0 FROM `cronjob_reloaded` WHERE id IS NOT NULL AND category IN ('bmw'))
ORDER BY sort_col
)
")
Ty!
PS. I have posted an unclear question some time ago, can a admin please delete that one? And sorry for any inconvenience. The question is here
As the error says, derived tables must be aliased.
SELECT COUNT(*)
FROM
(
(SELECT 1 as sort_col,id,pic0 FROM `cronjob_reloaded` WHERE id IS NOT NULL AND id LIKE '%car%')
UNION
(SELECT 2 as sort_col,id,pic0 FROM `cronjob_reloaded` WHERE id IS NOT NULL AND category IN ('bmw'))
ORDER BY sort_col
) q /* I added the alias "q" */

Distinct in complex sql query

I have another one for you guys. I've searched around but I can't figure out the cause of this issue.
Basically, I want to do a DISTINCT on user_id, which is a column being naturally joined and exists in the tables "user" and "leaderboard_entry".
This is my original query which works great, but I'd like to filter out duplicates and show only the first fastest user score. The inner query basically grabs 100 of the most recent rows, and the outer query resorts them by ascending leaderboard_entry_elapsed_time_ms.
set #t1=0; select * from
(
select #t1 := #t1+1 as leaderboard_entry_youngness_rank, 1-#t1/100 as
leaderboard_entry_youngness_based_on_expiry,
leaderboard_entry.*,
NOW()-leaderboard_entry_timestamp as leaderboard_entry_age_in_some_units ,
TO_DAYS(NOW())-TO_DAYS(leaderboard_entry_timestamp)
as leaderboard_entry_age_in_days , leaderboard.leaderboard_quiz_mode ,
leaderboard.leaderboard_load_key ,
user.user_name
from leaderboard_entry
natural join
leaderboard
natural join
user
where
(leaderboard_load_key = 'es-en-animals-1'
or leaderboard_load_key = '-es-en-animals-1' )
and leaderboard_quiz_mode = '0'
order by leaderboard_entry_age_in_some_units asc ,
leaderboard_entry_timestamp asc limit 0, 100
) as outer_temp
order by
leaderboard_entry_elapsed_time_ms asc ,
leaderboard_entry_timestamp asc
limit 0, 50
I've tried the following, which is removing "leaderboard_entry.*, " and adding the DISTINCT keyword like so with explicit naming of the columns I need:
set #t1=0; select * from
(
select #t1 := #t1+1 as leaderboard_entry_youngness_rank, 1-#t1/100 as
leaderboard_entry_youngness_based_on_expiry,
NOW()-leaderboard_entry_timestamp as leaderboard_entry_age_in_some_units ,
TO_DAYS(NOW())-TO_DAYS(leaderboard_entry_timestamp)
as leaderboard_entry_age_in_days , leaderboard.leaderboard_quiz_mode ,
leaderboard.leaderboard_load_key ,
user.user_name
distinct leaderboard_entry.user_id,
leaderboard_entry.leaderboard_entry_id,
leaderboard_entry.leaderboard_id,
leaderboard_entry.leaderboard_entry_timestamp,
leaderboard_entry.leaderboard_entry_elapsed_time_ms,
from leaderboard_entry
natural join
leaderboard
natural join
user
where
(leaderboard_load_key = 'es-en-animals-1'
or leaderboard_load_key = '-es-en-animals-1' )
and leaderboard_quiz_mode = '0'
order by leaderboard_entry_age_in_some_units asc ,
leaderboard_entry_timestamp asc limit 0, 100
) as outer_temp
order by
leaderboard_entry_elapsed_time_ms asc ,
leaderboard_entry_timestamp asc
limit 0, 50
But i get this error and it makes no sense... :(
#1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL
server version for the right syntax to use near
'distinct leaderboard_entry.user_id, leaderboard_entry.leaderboard_entry_id, '
at line 12
Any help much appreciated!
swine
Answered by The Scrum Meister as above

unique field from mysql database to php

I have a sample database like this, in which, id is always unique, but the user_id is not unique.
id,user_id,message,msg_datetime
111,u1, msg from u1,time present here
112,u2, msg from u2,time present here
113,u3, msg from u3,time present here
114,u2, msg from u2,time present here
115,u7, msg from u7,time present here
116,u2, msg from u2,time present here
117,u1, msg from u1,time present here
118,u5, msg from u5,time present here
so i want to grab only those unique users who have messaged and order them in DESC by msg_datetime.
This is the query i have.
select id,DISTINCT user_id,msg_datetime ORDER BY msg_datetime DESC but i am getting an error as:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DISTINCT. any help here? what is the correct syntax for what i am trying to achieve?
I want to show only one entry for each user, it does not matter which ID i am showing but only 1 per user.
If you don't care which record with the same user_id query should return, then
SELECT id,user_id,msg_datetime FROM table_1 GROUP BY user_id ORDER BY msg_datetime DESC
If you want to display, for instance, the last record for each user, you need
SELECT a.user_id, a.last_time, b.id
FROM
(SELECT user_id, MAX(msg_datetime) as last_time
FROM table1)a
INNER JOIN table1 b ON (b.user_id = a.user_id AND b.msg_datetime = a.last_time)
ORDER BY a.last_time;
SELECT syntax:
SELECT (fieldlists)
FROM (table)
[WHERE (conditions)]
ORDER BY (something)
You kindof forgot to say which table you want the data from.
You misunderstand how DISTINCT works. It works on rows not fields. What you want is a groupwise maximum, also known as greatest-n-per-group.
Here's one way to do it in MySQL:
SELECT id, user_id, message, msg_datetime
FROM (
SELECT
id, user_id, message, msg_datetime,
#rn := CASE WHEN #prev_user_id = user_id
THEN #rn + 1
ELSE 1
END AS rn,
#prev_user_id := user_id
FROM (SELECT #prev_user_id := NULL) vars, Table1 T1
ORDER BY user_id, msg_datetime DESC
) T2
WHERE rn = 1
ORDER BY msg_datetime

Categories