How to using ORDER BY and LIMIT in UNION mysql query - mysql

i have a litte problem, i have a MySQL query code like this:
SELECT a.id, b.name AS itemName, b.slug AS itemSlug FROM table_idx a
INNER JOIN table_product b ON b.id = a.targetid AND a.target='PRODUCT'
WHERE a.memberid=$memberid
UNION
SELECT a.id, c.name AS itemName, c.slug AS itemSlug FROM table_idx a
INNER JOIN table_news c ON c.id = a.targetid AND a.target='NEWS'
WHERE a.memberid=$memberid
UNION
SELECT a.id, d.name AS itemName, d.slug AS itemSlug FROM table_idx a
INNER JOIN table_promo d ON d.id = a.targetid AND a.target='PROMO'
WHERE a.memberid=$memberid
How to add ORDER BY a.id DESC LIMIT 0,10 in query above? Thanks for your help.

Wrap it with another select.
SELECT * FROM (
SELECT a.id, b.name AS itemName, b.slug AS itemSlug FROM table_idx a
INNER JOIN table_product b ON b.id = a.targetid AND a.target='PRODUCT'
WHERE a.memberid=$memberid
UNION
SELECT a.id, c.name AS itemName, c.slug AS itemSlug FROM table_idx a
INNER JOIN table_news c ON c.id = a.targetid AND a.target='NEWS'
WHERE a.memberid=$memberid
UNION
SELECT a.id, d.name AS itemName, d.slug AS itemSlug FROM table_idx a
INNER JOIN table_promo d ON d.id = a.targetid AND a.target='PROMO'
WHERE a.memberid=$memberid
) AS t ORDER BY t.id DESC LIMIT 0,10

Unless your intensions are to ORDER BY and LIMIT each query befor the UNION, Just add
ORDER BY id DESC LIMIT 0,10
At the bottom of the query.

Related

unloading an additional column for one specific value specified in the "WHERE" condition

From such a request:
WITH t as(
SELECT a.Id,
a.Name,
a.Description,
b.Title,
c.Role
FROM aTable AS a
LEFT JOIN bTable AS b ON a.Id=b.uuid
LEFT JOIN cTable AS c ON b.uuid=c.roleId
WHERE c.role='major' OR c.role='captian'
GROUP BY a.Id)
SELECT t.Id,
t.Name,
t.Description,
t.Title,
t.Role,
d.Email
FROM t
LEFT JOIN dTable AS d ON t.Id=d.Guid
I receive mail for both roles (for major and for captain).
Q: How to get mail for captain only?
I attach the result of my script
and the result I expect
Use an IF() expression.
WITH t as(
SELECT a.Id,
a.Name,
a.Description,
b.Title,
c.Role
FROM aTable AS a
INNER JOIN bTable AS b ON a.Id=b.uuid
INNER JOIN cTable AS c ON b.uuid=c.roleId
WHERE c.role='major' OR c.role='captain'
GROUP BY a.Id)
SELECT t.Id,
t.Name,
t.Description,
t.Title,
t.Role,
IF(c.role = 'captain', d.Email, '') AS Email
FROM t
LEFT JOIN dTable AS d ON t.Id=d.Guid

SQL Server Max Function

I have the following query:
SELECT
a.name, a.address, n.date, n.note
FROM a
LEFT JOIN n ON a.id = n.id
The a.id has a one to many relationship with n.id, so that many notes can be assocaited with one name.
How do I return just the latest note for each name instead of all the notes?
I'm using SQL Server 2008.
Thanks.
Here's one way using ROW_NUMBER()
SELECT t.name, t.address, t.date, t.note
FROM (
SELECT
a.name, a.address, n.date, n.note,
ROW_NUMBER() OVER (PARTITION BY a.name ORDER BY n.date DESC) rn
FROM a
LEFT JOIN n ON a.id = n.id
) t
WHERE t.rn = 1
alternative you can use a correlated subquery too get the max date, something like this
SELECT
a.name, a.address, n.date, n.note
FROM a
LEFT JOIN n ON a.id = n.id
WHERE n.date = (SELECT MAX(nn.date)
FROM n AS nn
WHERE a.id = nn.id)

Can not join more than two table

I have 3 tables:
table1
fields : id, title, cat1_id
table2
fields : id, title, cat2_id
table3
fields : id, title
My SQL :
SELECT a.id, a.title, b.title, c.title
FROM table1 AS a
INNER JOIN table2 AS b ON b.id = a.cat1_id
AND INNER JOIN table3 AS c ON c.id = b.cat2_id
ORDER BY a.id DESC
it's not working.
I try this SQL, it's working:
SELECT a.id, a.title, b.title, c.title
FROM table1 AS a
INNER JOIN table2 AS b ON b.id = a.cat1_id
ORDER BY a.id DESC
but double INNER JOIN does not work.
You do not need to use AND before JOIN to join more that two tables.
Your query should be
SELECT a.id, a.title, b.title, c.title
FROM table1 AS a
INNER JOIN table2 AS b ON b.id = a.cat1_id
INNER JOIN table3 AS c ON c.id = b.cat2_id
ORDER BY a.id DESC
Have a look at MySQL JOIN Syntax

SQL - selecting all rows with maximum value

I have this SQL query:
SELECT id, COUNT(*) AS price
FROM (SELECT * FROM rt WHERE somecondition) AS st
JOIN tt
ON st.id = tt.id
GROUP BY id;
Now, I want to select all rows which have the maximum price of the table. I have tried this, which unfortunately returns no row at all:
SELECT id, COUNT(*) AS price
FROM (SELECT * FROM rt WHERE somecondition) AS st
JOIN tt
ON st.id = tt.id
GROUP BY id
HAVING price = MAX(price);
I'm somewhat lost, does anybody have any pointers?
This looks fairly simple to me:
select * from <table>
where <column name> in(
SELECT MAX(column name) FROM table
)
Try this solution:
SELECT a.id, a.price
FROM
(
SELECT aa.id, COUNT(1) AS price
FROM rt aa
INNER JOIN tt bb ON aa.id = bb.id
WHERE aa.somecondition
GROUP BY aa.id
) a
INNER JOIN
(
SELECT MAX(aa.price) AS maxprice
FROM
(
SELECT COUNT(1) AS price
FROM rt aaa
INNER JOIN tt bbb ON aaa.id = bbb.id
WHERE aaa.somecondition
GROUP BY aaa.id
) aa
) b ON a.price = b.maxprice
Edit: While I can't think of any way to rewrite this so as to not have to write the base-queries redundantly, what you could perhaps do is this:
SELECT GROUP_CONCAT(a.id) AS ids, a.price
FROM
(
SELECT aa.id, COUNT(1) AS price
FROM rt aa
INNER JOIN tt bb ON aa.id = bb.id
WHERE aa.somecondition
GROUP BY aa.id
) a
GROUP BY a.price
ORDER BY a.price DESC
LIMIT 1
This produces a comma-separated-list of the ids that share the same maximum value. This is probably not the format you are looking for though, but it is one way to avoid having to write the base-query twice. Just putting that out there.
try this, put MAX in select, this should be the correct way
SELECT id, COUNT(*) AS price, MAX(price) AS max_price
FROM (SELECT some_table_name FROM rt WHERE somecondition LIMIT 1) AS st
JOIN thenextTable as tt
ON st.id = tt.id
GROUP BY id;
Assuming that #Zane's answer is what you do want, here's a portable version of his query that also avoids LIMIT/TOP operations. I'm not really familiar with mysql dialects, but I imagine this will work without problem.
SELECT a.id, a.price
FROM (
SELECT aa.id, COUNT(1) AS price
FROM rt aa
INNER JOIN tt bb ON aa.id = bb.id
WHERE [somecondition]
GROUP BY aa.id
) a
WHERE
a.price >= ALL (
SELECT COUNT(1) AS maxprice
FROM rt aa
INNER JOIN tt bb ON aa.id = bb.id
WHERE [somecondition]
GROUP BY aa.id
)
HAVING is used to check conditions after the aggregation takes place.
WHERE is used before the aggregation takes place.
SELECT id, COUNT(*) AS price
FROM (SELECT * FROM rt WHERE somecondition) AS st
JOIN tt
ON st.id = tt.id
WHERE price = (SELECT MAX(price) FROM ...table)
GROUP BY id
You asked for an approach that didn't require the redundancy of stating the inner query more than once. That's certainly what a cte is good for. These are two other solutions rewritten to use that tactic.
WITH basequery as (
SELECT aa.id, COUNT(1) AS price
FROM rt aa INNER JOIN tt bb ON aa.id = bb.id
WHERE [aa.somecondition]
GROUP BY aa.id
)
SELECT a.id, a.price
FROM
basequery as a INNER JOIN
(SELECT MAX(price) AS maxprice FROM basequery) as b
ON a.price = b.maxprice
-- or
WITH basequery as (
SELECT aa.id, COUNT(1) AS price
FROM rt aa INNER JOIN tt bb ON aa.id = bb.id
WHERE [aa.somecondition]
GROUP BY aa.id
)
SELECT a.id, a.price
FROM
basequery as a
WHERE
a.price >= ALL (SELECT price FROM basequery)

MySQL - Use select field value in nested SQL statement of the same SQL

I have the following SQL query
SELECT
a.id AS ID, a.title,
(
SELECT Group_Concat( title )
FROM (
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.id = ID
UNION
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.another_id = ID
) AS other_titles
FROM table_a
However it is not working and is having a problem with the parts WHERE b.id = ID and WHERE b.another_id = ID in the nested SQL part.
How can I use the ID from the first select (SELECT a.id AS ID) in the nested select?
I think what you have here is called correlated subquery. It looks quite promising and seems to only lack a couple of final strokes (highlighted in bold italic):
SELECT
a.id AS ID,
a.title,
(
SELECT Group_Concat( title )
FROM (
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.id = a.ID
UNION
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.another_id = a.ID
) AS other_titles
FROM table_a AS a
Keep in mind that what you are actually referencing in the subquery is a.id, not the ID alias. (You can't reference the alias there.)
If a.id is a complex expression and you are not very happy about repeating it in the subquery, then you might need to restructure the entire query, maybe like this:
SELECT
x.ID,
x.title,
(
SELECT Group_Concat( title )
FROM (
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.id = x.ID
UNION
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.another_id = x.ID
) AS other_titles
FROM (
SELECT
a.id AS ID,
a.title,
FROM table_a AS a
) x
You cannot select values into the FROM clause. You may only use variables to dynamically set the table name.