Mysql query distinct + multiple - mysql

I want to do this query:
SELECT *
FROM user k
INNER JOIN (
SELECT id, tagName, b.guid, name, owner, publicKey
FROM noteTags a
INNER JOIN (
SELECT *
FROM note
ORDER BY guid
LIMIT 0 , 12
)b ON a.guid = b.guid ORDER BY b.id DESC
)l ON k.owner = l.owner
But I want it to return DISTINCT b.guids.
Structure of the tables:
note
|
|=id
|=name
|=guid
|=owner
|=publicKey
noteTags
|
|=guid
|=tagName
user
|
|=owner
|=username
|=auth
Basically I want to select ALL data (with the limit on the deeper inner join) and return DISTINCT guids
Thanks!

Here's my initial answer,
SELECT *
FROM note a
INNER JOIN user b
ON a.owner = b.owner
INNER JOIN notetags c
ON a.guid = b.guid
INNER JOIN
(
SELECT guid, MAX(tagName) maxTag
FROM notetags
GROUP BY guid
) d ON c.guid = d.guid AND
c.tagName = d.maxTag

How about:
SELECT *
FROM user k
INNER JOIN (
SELECT id, tagName, b.guid, name, owner, publicKey
FROM noteTags a
INNER JOIN (
select id, name, MIN(guid) as guid, owner, publicKey
FROM note
GROUP BY guid
LIMIT 0 , 12
)b ON a.guid = b.guid ORDER BY b.id DESC
)l ON k.owner = l.owner

Related

Sum of grouped COUNT IN MySQL

I wrote this query
SELECT
country,
COUNT(DISTINCT tmp_tbl.user_guid) AS number_of_customers
FROM complete_tests c INNER JOIN
( SELECT DISTINCT d.dog_guid,
u.user_guid,
u.country
FROM dogs d INNER JOIN users u ON d.user_guid = u.user_guid
WHERE (u.exclude = 0 OR u.exclude IS NULL)
AND (d.exclude = 0 OR d.exclude IS NULL)
)
AS tmp_tbl ON c.dog_guid = tmp_tbl.dog_guid
GROUP BY country
ORDER BY number_of_customers DESC
And I need to add another variable that calculates the percentage of total
when I add
number_of_customers/SUM(number_of_customers)
or SUM(COUNT(DISTINCT tmp_tbl.user_guid)) / COUNT(DISTINCT tmp_tbl.user_guid)
it gives me error
Analytic functions come in handy here. Assuming you are using MySQL 8+:
SELECT country,
COUNT(DISTINCT tmp_tbl.user_guid) AS number_of_customers,
100.0 * COUNT(DISTINCT tmp_tbl.user_guid) /
SUM(COUNT(DISTINCT tmp_tbl.user_guid)) OVER () AS pct_customers
FROM complete_tests c
INNER JOIN
(
SELECT DISTINCT d.dog_guid, u.user_guid, u.country
FROM dogs d
INNER JOIN users u ON d.user_guid = u.user_guid
WHERE (u.exclude = 0 OR u.exclude IS NULL) AND
(d.exclude = 0 OR d.exclude IS NULL)
) AS tmp_tbl
ON c.dog_guid = tmp_tbl.dog_guid
GROUP BY
country
ORDER BY
number_of_customers DESC;

Limit results to 1 row for each group in subquery

as a result of the execution of this query, situations are possible when two rows have the same minimum price, but i still need to select one. I understand perfectly well that the standard limit cannot be dispensed with here. I do not have enough knowledge to understand from which side to approach the solution of this issue. Thank you in advance for your attension.
UPDATE offers t1
SET t1.deleted_at = NOW()
WHERE t1.id
NOT IN
(
SELECT f.id
FROM (
SELECT name, MIN(net_price) as minprice
FROM offers
WHERE
supplier_id = (SELECT id FROM suppliers WHERE name = 'somename')
group BY name
)
AS x inner join (SELECT * FROM offers) AS f ON f.name = x.name AND f.net_price = x.minprice
)
AND
t1.supplier_id = (SELECT id FROM suppliers WHERE name = 'somename');
I don't know somehowe, but this works for me:
UPDATE offers t1
SET t1.deleted_at = NOW()
WHERE t1.id
NOT IN
(
SELECT f.id
FROM (
SELECT id, name, MIN(net_price) as minprice
FROM offers
WHERE
supplier_id = (SELECT id FROM suppliers WHERE name = 'somename')
group BY name
)
AS x inner join (SELECT * FROM offers) AS f ON f.id = x.id
)
AND
t1.supplier_id = (SELECT id FROM suppliers WHERE name = 'somename');
Just add id to subquery select and put it on inner join f.id = x.id

How to select data from mutiple tables in SQL instead of SELECT statements?

I have used SELECT statements to select data from multiple tables but it takes long time to execute this query.
select t.id,
t.department,
t.owner,
t.client,
(select username from tbl_user u where u.id = t.owner) as owner_name,
(select name from tbl_task_catagery c where c.id = t.catagery) as catagery,
(select dept_name from tbl_department d where d.id = t.department) as deptname,
(select name from tbl_task_catagery c where c.id = t.subcatagery) as subcatagery,
t.periority,
t.status,
t.estimate,
c.takeaway_name
from tbl_task t,
tbl_clients c
where c.id = t.client
and t.status = 0
and (t.id in (select task_id
from tbl_task_note tn
where tn.user_id = '130'
and tn.id in (select max(id)
from tbl_task_note tt
where tt.task_id = tn.task_id)))
order by t.id
How to do it in an easier way?
You may over-simplify your query to:
select t.id,
t.department,
t.owner,
t.client,
(select username from tbl_user u where u.id = t.owner) as owner_name,
(select name from tbl_task_catagery c where c.id = t.catagery) as catagery,
(select dept_name from tbl_department d where d.id = t.department) as deptname,
(select name from tbl_task_catagery c where c.id = t.subcatagery) as subcatagery,
t.periority,
t.status,
t.estimate,
c.takeaway_name
from tbl_task t
join tbl_clients c on c.id = t.client
where t.status = 0
and exists (select 1
from tbl_task_note tn
where tn.user_id = '130'
and t.id = tn.task_id
order by id desc
limit 1)
Then, you can have indices on tbl_task(status, client) and tbl_clients(id). Presumably, tbl_clients(id) is the primary key so already have an index over it.

Can anyone help me to optimize my query?

SELECT p.ID, Name
FROM Policies p
INNER JOIN ProgramYears py ON p.ProgramYearID = py.id
INNER JOIN (SELECT MemberID, max(EffectiveDate) AS EffectiveDate
FROM Policies
GROUP BY MemberID) TEMP
ON p.memberid = TEMP.MemberID
AND p.EffectiveDate = TEMP.effectivedate
AND p.memberid NOT IN (SELECT MemberID
FROM InvoiceDetail
WHERE ProgramYear = NAME)
NOT EXISTS is usually a better substitute for NOT IN, but your choices largely depend on the data and the structure of your tables and indexes.
Try the query below, but compare its execution plan to that of your current query; what works for one scenario may not work for another.
SELECT p.ID, Name
FROM Policies p
INNER JOIN ProgramYears py ON p.ProgramYearID = py.id
INNER JOIN (SELECT MemberID, max(EffectiveDate) AS EffectiveDate
FROM Policies
GROUP BY MemberID) TEMP
ON p.memberid = TEMP.MemberID
AND p.EffectiveDate = TEMP.effectivedate
WHERE NOT EXISTS
(SELECT MemberID
FROM InvoiceDetail AS ID
WHERE ID.ProgramYear = NAME
AND p.MemberId = ID.MemberId)
You can try:
SELECT a.ID, a.Name
FROM (SELECT p.ID, Name,
ROW_NUMBER()OVER(PARTITION BY p.memberid ORDER BY p.EffectiveDate DESC) AS rnk
FROM Policies p
INNER JOIN ProgramYears py ON p.ProgramYearID = py.id
WHERE NOT EXISTS (SELECT MemberID
FROM InvoiceDetail AS ID
WHERE ID.ProgramYear = NAME
AND p.MemberId = ID.MemberId)
) a
WHERE a.rnk = 1

GROUP_CONCAT multiple values from table

I just added a table which holds a url and description for each item in place. The below query works ok ... but it's only returning the url and I need the desc also. I m not sure how to make this work.
$query_str = "SELECT a.userid, a.cat, a.id, a.name, a.image,
a.desc, a.country, b.user_id, c.username,
c.fbook, d.cat_id,
(
SELECT GROUP_CONCAT(url)
FROM one_add o
WHERE a.id=o.one_id
) AS url,
(
SELECT COUNT(id)
FROM one_msg m
WHERE m.guest_id = ? AND
m.one_id=a.id
) AS count
FROM place a
LEFT OUTER JOIN wait b
ON a.id=b.post_id AND
b.user_id= ?
JOIN users c
ON a.userid=c.id
LEFT JOIN (
SELECT userid, user_id,
GROUP_CONCAT( cat_id ) AS cat_id
FROM user_cat
WHERE userid='$user_id'
GROUP BY user_id
) AS d ON d.userid='$user_id' AND
d.user_id=a.userid
WHERE a.cat != ? ORDER BY a.date desc";
This is what I want to accomplish: desc
You can achibe this by using CONCAT inside GROUP_CONCAT function as:
(SELECT GROUP_CONCAT(CONCAT('',desc,''))
FROM one_add o
WHERE a.id=o.one_id) AS url
full query:
(SELECT COUNT(id) FROM one_msg m WHERE m.guest_id = ? AND m.one_id=a.id ) AS count
FROM place a
LEFT OUTER JOIN wait b ON a.id=b.post_id AND b.user_id= ?
JOIN users c ON a.userid=c.id
LEFT JOIN ( SELECT userid, user_id, GROUP_CONCAT( cat_id ) AS cat_id FROM user_cat WHERE userid='$user_id' GROUP BY user_id ) AS d ON d.userid='$user_id' AND d.user_id=a.userid
WHERE a.cat != ? ORDER BY a.date desc";