How to use data from WHERE query MYSQL - mysql

I have this MySQL query:
SELECT * FROM A
LEFT JOIN B
ON B.id = A.id
LEFT JOIN C
ON C.other = A.other
WHERE
(SELECT SUM(C.quantity) FROM C WHERE C.other = A.other) < A.quantity
Is any way to get values from SELECT from WHERE clause? For example for PHP to use? Something like:
WHERE
(SELECT SUM(C.quantity) FROM C WHERE C.other = A.other) AS quantity < A.quantity
I need to compare this two values in mysql and then i need them both in my script. I can of course put this subquery into first SELECT - but i belive there is better way to do this than repeat code in many places.

You could do that as follows:
SELECT A.*, B.*, C.*, D.sumq
FROM A
LEFT JOIN B
ON B.id = A.id
LEFT JOIN C
ON C.other = A.other
LEFT JOIN (
SELECT other, SUM(quantity) sumq
FROM C
GROUP BY other
) AS D
ON D.other = A.other
WHERE COALESCE(D.sumq, 0) < A.quantity

Related

Select the first record of another table inside a select - MYSQL

I´m trying to make a query listing all clients, and also get the last comment and
the date of that comment inside the table of history_client inside a single query for it to be listed.
select a.id_client,a.name,a.lastname,(select b.date_created,b.comentary
from history_of_client b where a.id_client = b.id_client_asociate) from clients_main_table
You could use an inner join on max(date_created) for id_client on history table and join
SELECT a.id_client,a.name,a.lastname, h.commentary
FROM clients_main_table a
INNER join (
select b.id_client_asociate, max(b.date_created) max_date
from history_of_client
group by b.id_client_asociate ) t on t.id_client_asociate = a.id_client
INNER JOIN history_of_client h on h.id_client_asociate = t.id_client_asociate
and h.date_created = t.max_date
Use the LEFT JOIN and INNER join to get your desired result set.
select a.id_client,
a.name,
a.lastname,
hc.date_created,
hc.comentary
from clients_main_table c
left join (select id_client_asociate,max(date_created) dt from history_of_client group by id_client_asociate) h
on (c.id_client = b.id_client_asociate)
inner join history_of_client hc
on (hc.id_client_asociate = b.id_client_asociate and hc.date_created = h.date_created)

Make multiple row result to one row SQL

I'm trying to create
select c.FullName, b.*, e.Description as Posisilama, f.Description as Posisibaru, g.Description,
GROUP_CONCAT('b.nilai' SEPARATOR ',') AS nilai
from penilaian_header a
left join penilaian_detail b on a.KodePenilaian = b.KodePenilaianH
left join employee c on a.Nip = c.Nip
left join HistoryPosition d on a.KodePenilaian = d.KodePenilaian
left join Position e on d.OldPosition = e.PositionCode
left join Position f on d.NewPosition = f.PositionCode
left join Outlet g on c.OutletCode = g.OutletCode
Can you check my query, because I got this error:
Incorrect syntax near 'SEPARATOR'
What I need to do is to make multiple row result in to one row SQL. Because my result is like this
I found a solution. I use pivot.
select * from
(
select row, c.Nilai,b.Fullname,a.KodePenilaian,d.Description from penilaian_header a
left join employee b on a.Nip = b.Nip
left join outlet d on a.Outlet = d.OutletCode
left join (select ROW_NUMBER() OVER(PARTITION BY KodePenilaianH ORDER BY idPenilaiand DESC) AS Row, Nilai,KodePenilaianH from penilaian_Detail
) c on a.KodePenilaian = c.KodePenilaianH where a.Outlet like '%%' and Periode like '%%'
) nilai
pivot
(
sum(nilai)
for row in ([1],[2],[3],[4],[5])
) piv;
miss a group by clause,check this :
How to use GROUP_CONCAT in a CONCAT in MySQL
i will write like this :
select c.FullName, b.*, e.Description as Posisilama
, f.Description as Posisibaru, g.Description,
GROUP_CONCAT('b.nilai' SEPARATOR ',') AS nilai
from penilaian_header a
left join penilaian_detail b on a.KodePenilaian = b.KodePenilaianH
left join employee c on a.Nip = c.Nip
left join HistoryPosition d on a.KodePenilaian = d.KodePenilaian
left join Position e on d.OldPosition = e.PositionCode
left join Position f on d.NewPosition = f.PositionCode
left join Outlet g on c.OutletCode = g.OutletCode
group by c.FullName, b.*, e.Description
, f.Description , g.Description

MySQL with monthly tables and monthly joins

I am an trainee as a software developer. I have a question: How can I access to multiple tables with select and join?
The name of the main-tables are like:
logs_0215
logs_0315
logs_mmyy -> m = month; y = year
The name of the timestamp-tables are like:
timestamp_0215
timestamp_0315
timestamp_mmyy -> m = month; y = year
My query which works only for one table is like:
SELECT a.id, b.stamp, c.name AS portal, d.name AS company, e.name AS protocol, a.value
FROM logs_0315 AS a
LEFT JOIN timestamp_0315 AS b ON a.time_id = b.id
LEFT JOIN portale AS c ON a.portal_id = c.id
LEFT JOIN companies AS d ON a.comp_id = d.id
LEFT JOIN proocols AS e ON a.prot_id = e.id
WHERE b.stamp BETWEEN '2015-05-01' AND '2015-06-25'
How can I access to all tables which contains logs_mmyy with its timestamp?
Thank you for your help in advance.
Yours sincerely
t.koelpin
You would have to explicitly identify each table; each table has to be identified by name in a FROM clause. SQL does not support wildcard pattern matching for identifiers (table names, column names, etc.).
Given what you've posted, it looks like you could use a UNION ALL set operator to combine results from multiple SELECT statements as a single query:
SELECT a.id, ...
FROM logs_0315 a
LEFT JOIN timestamp_0315 AS b ON a.time_id = b.id
...
WHERE b.stamp BETWEEN '2015-05-01' AND '2015-06-25'
UNION ALL
SELECT a.id, ...
FROM logs_0415 a
LEFT JOIN timestamp_0415 AS b ON a.time_id = b.id
...
WHERE b.stamp BETWEEN '2015-05-01' AND '2015-06-25'
UNION ALL
SELECT a.id, ...
FROM logs_0515 a
LEFT JOIN timestamp_0515 AS b ON a.time_id = b.id
...
WHERE b.stamp BETWEEN '2015-05-01' AND '2015-06-25'
If you need an ORDER BY on the combined result, you can enclose each SELECT statement in parens. Like this:
( SELECT a.id, ...
FROM logs_0315 a
LEFT JOIN timestamp_0315 AS b ON a.time_id = b.id
...
WHERE b.stamp BETWEEN '2015-05-01' AND '2015-06-25'
)
UNION ALL
( SELECT a.id, ...
FROM logs_0415 a
LEFT JOIN timestamp_0415 AS b ON a.time_id = b.id
...
WHERE b.stamp BETWEEN '2015-05-01' AND '2015-06-25'
)
UNION ALL
( SELECT a.id, ...
FROM logs_0515 a
LEFT JOIN timestamp_0515 AS b ON a.time_id = b.id
...
WHERE b.stamp BETWEEN '2015-05-01' AND '2015-06-25'
)
ORDER BY ...
In order to make this dynamic, to get all tables of the pattern logs_mmyy, you could query information_schema.tables and get the list of tables, and then use that to dynamically generate a statement as above. This approach requires (at a minimum) two separate SQL statements. It's not possible to achieve this type of result in a single SQL statement.

Incorrect id returned on LEFT JOIN in Mysql statement

I need to get the id and timestamps of table sellers and all other columns (without knowing the column names) from these results returned from this MySql statement:
SELECT * FROM sellers a
LEFT JOIN users b ON a.user_id = b.id
LEFT JOIN country_types c ON a.country_type_id = c.id
LEFT JOIN language_types d ON a.language_type_id = d.id
WHERE a.email=?
The seller id though is incorrectly set because users, country_types, and language_types all have a value id. How can I set seller_id and seller_timestamp? I tried this but it is incorrect:
SELECT a.id seller_id, a.timestamp seller_timestamp, * FROM sellers a ...
You want this:
SELECT a.id as seller_id, a.timestamp as seller_timestamp, a.*, b.*, c.*, d.*
FROM sellers a
LEFT JOIN users b ON a.user_id = b.id
LEFT JOIN country_types c ON a.country_type_id = c.id
LEFT JOIN language_types d ON a.language_type_id = d.id
WHERE a.email=?
Im not sure but try alias, for example:
a.id AS seller_id
and etc.
In joins you can't select other columns in this way:
SELECT a.id seller_id, a.timestamp seller_timestamp, * FROM sellers a...
You need to write required column names.

MySQL GROUP BY performance issue

This is the query I'm performing (without some Joins that are not relevant):
SELECT a.*, c.id
FROM a
LEFT OUTER JOIN b ON a.id = b.id_anunciante
LEFT OUTER JOIN c ON c.id = b.id_rubro
GROUP BY a.id
Each row of "a" is linked with 1 to 5 rows in "b".
The problem is that GROUP BY has performance issues (it takes 10x or more using GROUP BY than not using it). I need to retrieve only one row of each member in "a".
How can I make this faster?
edit: I need to be able to filter by a.id AND/OR c.id. The resultset I should be getting is only 1 row per "valid" member of "a", meaning the rows that match the constraints. Rows that don't match the filters shouldn't be returned.
In my original query, this would be done this way:
SELECT a.*, c.id
FROM a
LEFT OUTER JOIN b ON a.id = b.id_anunciante
LEFT OUTER JOIN c ON c.id = b.id_rubro
WHERE c.id = 1
OR a.id = 1
GROUP BY a.id
a.id, b.id_anunciante, b.id_rubro, c.id are all indexes.
SELECT a.*,
(
SELECT c.id
FROM b
JOIN с
ON c.id = b.id_rubro
WHERE b.id_anunciante = a.id
-- add the ORDER BY condition to define which row will be selected.
LIMIT 1
)
FROM a
Create the index on b (id_anunciante) for this to work faster.
Update:
You don't need the OUTER JOINs here.
Rewrite your query as this:
SELECT a.*, c.id
FROM a
JOIN b
ON b.id_anunciante = a.id
JOIN c
ON c.id = b.id_rubro
WHERE a.id = 1
UNION ALL
SELECT a.*, 1
FROM a
WHERE EXISTS
(
SELECT NULL
FROM c
JOIN b
ON b.id_rubro = c.id
WHERE c.id = 1
AND b.id_anunciante = a.id
)
Add ORDER BY NULL to avoid the implicit sorting MySQL does when doing a group by.
I suppose you have indexes/PKs on a.id, b.id_anunciante, b.id_rubro and c.id ? I guess you could try adding a composite index on (b.id_anunciante, b.id_rubro) if your mysql version is not able to do an index merge.