Multiple Selects in Single Query - mysql

I'm hoping someone fluent in MySQL will be able to assist me with this. I'm trying to do a select on a select on a select, but the query doesn't seem to want to complete. Any help would be greatly appreciated.
SELECT
product as pid,
leg_name as name,
dimensions as dims
FROM
pmaint
WHERE
product in (
SELECT product
FROM qb_export_items_attributes
WHERE attribute_name = 'Z'
AND product in (
SELECT product
FROM pmainT
WHERE type_ID = (
SELECT ID
FROM type
WHERE SOFTCARTCATEGORY = 'End Table Legs'
)
)
AND attribute_value <= 3.5
)

Try to use INNER JOINs instead of IN subqueries
UPD: I've edited this query according you comment. the first JOIN subquery output all product where both attributes exists and true.
SELECT
pmaint.product as pid,
pmaint.leg_name as name,
pmaint.dimensions as dims
FROM
pmaint
JOIN (select product from qb_export_items_attributes
where ((attribute_name = 'Z') and (attribute_value <= 3.5))
OR
((attribute_name = 'top_square') and (attribute_value >= 4))
GROUP BY product HAVING COUNT(*)=2
)
t1 on (pmaint.product=t1.product )
JOIN type on (pmaint.type_ID=type.ID)
WHERE
type.SOFTCARTCATEGORY = 'End Table Legs'

Related

How to pass a value to a subquery in MySQL

Im having trouble passing a value to a subquery in MySQL, for what i have read this is not possible in MySQL, but i cant manage to find anotherway to do this query.
the value to pass is "pnl_partsA.part_image" from the first part of the query.
What Im tying to obtain is the part_image that is present in more than one manufacturer.
SELECT manufacturer, chapter, part_image
FROM pnl_parts pnl_partsA
WHERE 1 = 1
AND part_image <> ''
#AND manufacturer = 'fiat'
#AND part_image = 'F01A050'
AND ( SELECT COUNT(chapter)
FROM ( SELECT manufacturer, chapter, part_image
FROM pnl_parts
WHERE part_image = pnl_partsA.part_image
AND part_image <> ''
AND manufacturer = pnl_partsA.manufacturer
GROUP BY manufacturer, chapter, part_image
) chaptercount
) > 1
ORDER BY part_image
;
Adding more information...
What I need to get are the chapters that have a duplicate part_image
any help will be appreciated thanks.
You can get all the manufacturer and part_image group(s), which has more than one rows, using Group By and Having COUNT(*) > 1. We will use this result-set in a Derived table, and Join to the main table, to get the relevant row(s):
Try the following query instead:
SELECT
pp1.manufacturer,
pp1.chapter,
pp1.part_image
FROM pnl_parts AS pp1
JOIN (
SELECT
pp2.manufacturer,
pp2.part_image
FROM pnl_parts AS pp2
WHERE pp2.part_image <> ''
GROUP BY
pp2.manufacturer,
pp2.part_image
HAVING COUNT(*) > 1
) AS dt
ON dt.manufacturer = pp1.manufacturer AND
dt.part_image = pp1.part_image

Getting Newest Record from a table using mysql

This has to be a no brainer, but I am stumped. I'm used to using aggregate 'FIRST' in MsAccess, but MySql has no such thing.
Here is a simple table. I want to return the most recent record based on the date,
for each unique 'group ID'. I need the three records in yellow.
I was asked to add my full query. I tried one of the suggestions using the JOIN feature replacing 't' with the temp table name, but it failed to work. "Can't reopen table 't'"
The code is below. I know it's ugly, but it does return the correct data set.
I cleaned up the code a bit and added the JOIN code. Error: "Can't reopen table 't'"
enter code here
DROP TABLE IF EXISTS `tmpMaxLookupResults`;
create temporary table tmpMaxLookupResults
as
SELECT
REPORTS.dtmReportCompleted,
RESULTS.lngMainReport_ID, RESULTS.lngLocationGroupSub_ID
FROM
(tbl_010_040_ProcedureVsTest_Sub as ProcVsSub
INNER JOIN tbl_010_050_CheckLog_RESULTS as RESULTS
ON (ProcVsSub.lngLocationGroupSub_ID = RESULTS.lngLocationGroupSub_ID)
AND (ProcVsSub.lngProcedure_ID = RESULTS.lngProcedure_ID)
AND (ProcVsSub.lngItemizedTestList_ID = RESULTS.lngItemizedTestList_ID)
AND (ProcVsSub.strPasscodeAdmin = RESULTS.strPasscodeAdmin)
AND (ProcVsSub.strCFICode = RESULTS.strCFICode))
INNER JOIN
tbl_000_010_MAIN_REPORT_INFO as REPORTS ON (RESULTS.lngPCC_ID =
REPORTS.lngPCC_ID)
AND (RESULTS.lngProcedure_ID = REPORTS.lngProcedure_ID)
AND (RESULTS.lngMainReport_ID = REPORTS.idMainReport_ID)
AND (RESULTS.strPasscodeAdmin = REPORTS.strPasscodeAdmin)
AND (RESULTS.strCFICode = REPORTS.strCFICode)
WHERE
(((RESULTS.lngProcedure_ID) = 143)
AND ((RESULTS.dtmExpireDate) IS NOT NULL)
AND ((RESULTS.strCFICode) = 'ems'))
GROUP BY RESULTS.lngMainReport_ID, RESULTS.lngLocationGroupSub_ID
ORDER BY (REPORTS.dtmReportCompleted) DESC;
SELECT t.*
FROM tmpMaxLookupResults AS t
JOIN (
SELECT lngLocationGroupSub_ID,
MAX(dtmReportCompleted) AS max_date_completed
FROM tmpMaxLookupResults
GROUP BY lngLocationGroupSub_ID ) AS dt
ON dt.lngLocationGroupSub_ID = t.lngLocationGroupSub_ID AND
dt.max_date_completed = t.dtmReportCompleted
enter code here
Try this
SELECT
tn.*
FROM
tableName tn
RIGHT OUTER JOIN
(
SELECT
groupId, MAX(date_completed) as max_date_completed
FROM
tableName
GROUP BY
groupId
) AS gt
ON
(gt.max_date_completed = nt.date_completed AND gt.groupId = nt.groupId)
You can use the following SQL.
select * from table1 order by date_completed desc Limit 1;
Use Order By
SELECT *
FROM table_name
ORDER BY your_date_column_name
DESC
LIMIT 1
In a Derived Table, get the maximum date_completed value for every group_id.
Join this result-set back to the main table, in order to get the complete row corresponding to maximum date_completed value for every group_id
Try the following query:
SELECT t.*
FROM your_table_name AS t
JOIN (
SELECT group_id,
MAX(date_completed) AS max_date_completed
FROM your_table_name
GROUP BY group_id
) AS dt
ON dt.group_id = t.group_id AND
dt.max_date_completed = t.date_completed

SQL subquery logic confusion

I'm writing an SQL query but I'm stuck at a point and can't figure out how to solve this issue. First have a look at the query below:
SELECT user_id, COUNT(*) as count
FROM hwc_attend
WHERE at_id IN
(SELECT evdet_id
FROM eve_detail
WHERE evdet_id IN (SELECT at_id FROM hwc_attend WHERE attendstate=1 )
AND location <> ''
AND evdet_id > 999
AND location NOT IN (SELECT ASIN FROM pReviews )
)
GROUP BY user_id
This query is working fine but giving lesser results than required because the part SELECT ASIN FROM pReviews should be like SELECT ASIN FROM pReviews where cID={place current value of "location" field from table eve_detail here.
For a better understanding, here's the errornous query:
SELECT user_id, COUNT(*) as count
FROM hwc_attend
WHERE at_id IN
(SELECT evdet_id **, location**
FROM eve_detail
WHERE evdet_id IN (SELECT at_id FROM hwc_attend WHERE attendstate=1)
AND location <> ''
AND evdet_id > 999
AND location NOT IN (SELECT ASIN FROM pReviews where cID=**location**)
)
GROUP BY user_id
It's hard to explain.. In short, I have to remove "location" values from the result fetched from table "eve_detail" that also exist in table "pReviews" in column cID.
Additionally, it would be nice if someone can covert it into joins. I would need both queries for learning.
Translating it to a join would use something like this. Using a LEFT OUTER JOIN and checking for NULL instead of NOT IN. I am assuming that hwc_attend has a unique column called id which is used in the count to get distinct rows.
SELECT ha1.user_id, COUNT(DISTINCT ha1.id) as count
FROM hwc_attend ha1
INNER JOIN eve_detail ed ON ha1.at_id = ed.evdet_id
INNER JOIN hwc_attend ha2 ON ed.evdet_id = ha2.at_id
LEFT OUTER JOIN pReviews pr ON ed.location = pr.ASIN AND cID = **location**
WHERE ha2.attendstate = 1
AND ed.location <> ''
AND ed.evdet_id > 999
AND pr.ASIN IS NULL
GROUP BY ha1.user_id
Change
AND location NOT IN (SELECT ASIN FROM pReviews )
To
AND NOT EXISTS (SELECT ASIN FROM pReviews WHERE eve_detail.location = ASIN.cID )

SELECT a field from similar fields by MAX from another field

I have a table with three columns: Item, Quantity, and Date.
The values in the Item column may be duplicates, but the Quantity and Dates will be unique.
For example:
Item - Quantity - Date
Hammer - 3 - 1/12/15
Hammer - 7 - 5/18/15
Hammer - 6 - 8/1/15
Wrench - 8 - 2/24/15
Wrench - 3 - 6/10/15
I am trying to write a query that will only return:
Item - Quantity - Date
Hammer - 6 - 8/1/15
Wrench - 3 - 6/10/15
This is my code:
SELECT DISTINCT stock.stc_st AS Store, stock.art_st AS UPC, articles.descr AS Description, stock.quan_st AS Quantity, articles.rp AS Cost
FROM stock LEFT JOIN articles ON stock.art_st = articles.article
WHERE stock.ym_st =
(SELECT Max(stock.ym_st)
FROM stock t1
WHERE stock.art_st=t1.art_st
GROUP BY t1.art_st)
GROUP BY stock.stc_st, stock.art_st, articles.descr, stock.quan_st, articles.rp, articles.act, articles.stat
HAVING (((stock.stc_st)=[Which Store?]) AND ((articles.act)="Y") AND ((articles.stat)="Y"));
However, my code is returning all items when I only want it to return the items with the max date. If anyone could take a look at this and tell me what I am doing wrong, I would really appreciate it.
========================
Now I'm trying to use this code from the answers below and it's giving me a Syntax Error on JOIN on the Inner Join at tmaxdate.art_st. I'm sure this is something stupid like a parenthesis out of place. Could anyone more familiar with Access's SQL syntax tell me what I'm doing wrong? Thanks!
SELECT DISTINCT stock.stc_st AS Store, stock.art_st AS UPC, articles.descr AS Description, stock.quan_st AS Quantity, articles.rp AS Cost
FROM stock AS t1
INNER JOIN
(
SELECT tmaxdate.art_st, Max(tmaxdate.ym_st) AS MaxOfDate
FROM stock AS tmaxdate
GROUP BY tmaxdate.art_sc
) AS sub
ON (t1.ym_st = sub.MaxOfDate) AND (tmaxdate.art_st = sub.art_st)
LEFT JOIN articles ON stock.art_st = articles.article
GROUP BY stock.stc_st, stock.art_st, articles.descr, stock.quan_st, articles.rp, articles.act, articles.stat
HAVING (((stock.stc_st)=[Which Store?]) AND ((articles.act)="Y") AND ((articles.stat)="Y"));
I couldn't figure out how that sample data is distributed among your tables. So I stored those data in a table named YourTable.
First create a GROUP BY query to show you the most recent Date for each Item:
SELECT t1.Item, Max(t1.Date) AS MaxOfDate
FROM YourTable AS t1
GROUP BY t1.Item
Then you can use that as a subquery which you join back to the main table in order to select only its rows with the matching Item/Date pairs:
SELECT t2.Item, t2.Quantity, t2.Date
FROM
YourTable AS t2
INNER JOIN
(
SELECT t1.Item, Max(t1.Date) AS MaxOfDate
FROM YourTable AS t1
GROUP BY t1.Item
) AS sub
ON (t2.Date = sub.MaxOfDate) AND (t2.Item = sub.Item);
With your sample data in Access 2010, that query returns your requested output.
Since you don't actually have a single YourTable, you will need to adapt that approach for your actual tables, but this strategy should work there, too.
This has not been tested, but it is more along the lines of what you need.
It uses a subquery to find the maximum date for each primary key of stock table (I have assumed this is art_st )
SELECT stock.stc_st AS Store
, stock.art_st AS UPC
, articles.descr AS Description
, stock.quan_st AS Quantity
, articles.rp AS Cost
FROM ( stock
LEFT JOIN articles
ON stock.art_st = articles.article
)
INNER JOIN (SELECT t1.art_st, Max(stock.ym_st) AS t1MaxDate
FROM stock t1
GROUP BY t1.art_st
) AS TabMax
ON ( TabMax.art_st = stock.art_st
AND TabMax.t1MaxDate = stock.ym_st )
GROUP BY stock.stc_st
, stock.art_st
, articles.descr
, stock.quan_st
, articles.rp
, articles.act
, articles.stat
HAVING (((stock.stc_st)=[Which Store?]) AND ((articles.act)="Y") AND ((articles.stat)="Y"));

LEFT JOIN SUM with WHERE clause

The following query always outputs SUM for all rows instead of per userid. Not sure where else to look. Please help.
SELECT * FROM assignments
LEFT JOIN (
SELECT SUM(timeworked) AS totaltimeworked
FROM time_entries
) assignments ON (userid = assignments.userid AND ticketid = ?)
WHERE ticketid = ?
ORDER BY assigned,scheduled
If you want to keep the SELECT *, you would have to add a group by clause in the subquery. Something like this
SELECT * FROM assignments
LEFT JOIN (
SELECT SUM(timeworked) AS totaltimeworked
FROM time_entries
GROUP BY userid
) time_entriesSummed ON time_entriesSummed.userid = assignments.userid
WHERE ticketid = ?
ORDER BY assigned,scheduled
But a better way would be to change the SELECT * to instead select the fields you want a add a group by clause directly. Something like this
SELECT
assignments.id,
assignments.assigned,
assignments.scheduled,
SUM(time_entries.timeworked) AS totalTimeworked
FROM assignments
LEFT JOIN time_entries
ON time_entries.userid = assignments.userid
GROUP BY assignments.id, assignments.assigned, assignments.scheduled
Edit 1
Included table names in query 2 as mentioned in chameera's comment below