Using results of one query into the next with unlike column names - mysql

My Platform is MySql
I have two queries that I need to combine, using the first query as a type of filter for the second query.
Query 1:
SELECT * FROM INVENTORY
WHERE INV_ID = 1
AND FSCL_YR = 2017
From this query we will get results back that includes a column named STR_NBR.
Which we then want to use in the second query as 'If the store number appears in the first query, give me the results where it shows in the second'. The second query tables use the column name SND_LOC_NBR instead of STR_NBR.
Query 2:
SELECT * FROM Transfer A
LEFT JOIN Transfer_Detail B
ON A.XFER_NBR = B.XFER_NBR
WHERE A.XFER_NBR = B.XFER_NBR
AND A.XFER_STAT_IND IN ('S','C')
AND (where the SND_LOC_NBR needs to match STR_NBRs found from Query 1)

Try this:
SELECT * FROM Transfer A
LEFT JOIN Transfer_Detail B
ON A.XFER_NBR = B.XFER_NBR
WHERE A.XFER_STAT_IND IN ('S','C')
AND SND_LOC_NBR IN
(SELECT STR_NBR FROM INVENTORY
WHERE INV_ID = 1 AND FSCL_YR = 2017 )

Related

Subtract the sum of one column from another table's column

What I have tried:
SELECT requestformtbl.employee_name, requestformtbl.request_type, requestformtbl.total_day,
requestformtbl.request_status, requestformtbl.admin_remark, requestformtbl.confirmed_by, requestformtbl.date_confirmed, requesttbl.max_allotment,
(requesttbl.max_allotment - sum(requestformtbl.total_day)) as Available from requestformtbl inner join requesttbl on
requestformtbl.request_type = requesttbl.request_type;
error: Column 'requestformtbl.employee_name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
If requestttbl.request_type="Vacation Leave" has requesttbl.max_allotment=20,
when a new entry in requestformtbl is inserted with requestformtbl.request_type="Vacation Leave" and requestformtbl.total_day=5
I want to get the remaining available leave
You can get the results you want without using a GROUP BY by using a correlated subquery to get the sum of the employees used days:
SELECT rft.employee_name,
rft.request_type,
rft.total_day,
rft.request_status,
rft.admin_remark,
rft.confirmed_by,
rft.date_confirmed,
rt.max_allotment,
rt.max_allotment - (select sum(total_day)
from requestformtbl rft2
where rft2.employee_name = rft.employee_name) as Available
from requestformtbl rft
inner join requesttbl rt on rft.request_type = rt.request_type;
Note I've used table aliases to make the query more readable.

Select only distinct values for a particular column mysql

We have two tables in mysql database.Screenshots are attached below.
Given table ads_testTable
here is the screenshot of my dimesnionvalue_flattable
We have to run a query like the one below.
SELECT Quiz_Attempt.L1_Key dimID,
Quiz_Attempt.L1_Label CatVars,
COALESCE(**xyz**,0) AS series0
FROM DSQ_ADSSCHEMA.ADS_TestTable dataTable
RIGHT OUTER JOIN LS_CONFIG.DSQ_DIMENSIONVALUES_FLAT Quiz_Attempt on dataTable.Quiz_Attempt = Quiz_Attempt.L1_Key
WHERE Quiz_Attempt.L0_Key = 'All Levels' AND
Quiz_Attempt.DimensionID = 'Packet'
GROUP BY Quiz_Attempt.L1_Key, Quiz_Attempt.L1_Label;
My motive is to write a query in place of xyz so that I can get avg of obtainedMarks column in testtable according to the value of dimID I get.Each distinct Quiz_Attempt is a different test so If a Packet is repeating for a particular Quiz_Attempt in testTable, it should take only one value for that AttemptID.
I think you query could take the form of:
SELECT
L1_Key dimID,
L1_Label CatVars,
COALESCE('**xyz**',0) AS series0
FROM (
SELECT *
FROM (SELECT * FROM ADS_TestTable GROUP BY ADS_TestTable.Quiz_Attempt) dataTable
RIGHT OUTER JOIN DSQ_DIMENSIONVALUES_FLAT Quiz_Attempt on dataTable.Quiz_Attempt = Quiz_Attempt.L1_Key
WHERE Quiz_Attempt.L0_Key = 'All Levels' AND
Quiz_Attempt.DimensionID = 'Packet'
GROUP BY dataTable.Quiz_Attempt
) A GROUP BY dimID, CatVars;
The JOIN is done in an inner query, and grouped by Quiz_Attempt, so that you get a single row per attempt. This result is then used to compute what you need.

MySQL Query gets too complex for me

I'm trying to write a MYSQL Query that updates a cell in table1 with information gathered from 2 other tables;
The gathering of data from the other 2 tables goes without much issues (it is slow, but that's because one of the 2 tables has 4601537 records in it.. (because all the rows for one report are split in a separate record, meaning that 1 report has more than 200 records)).
The Query that I use to Join the two tables together is:
# First Table, containing Report_ID's: RE
# Table that has to be updated: REGI
# Join Table: JT
SELECT JT.report_id as ReportID, REGI.Serienummer as SerialNo FROM Blancco_Registration.TrialTable as REGI
JOIN (SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92) AS JT ON JT.Value_string = REGI.Serienummer
WHERE REGI.HardwareType="PC" AND REGI.BlanccoReport=0 LIMIT 100
This returns 100 records (I limit it because the database is in use during work hours and I don't want to steal all resources).
However, I want to use these results in a Query that updates the REGI table (which it uses to select the 100 records in the first place).
However, I get the error that I cannot select from the table itself while updateing it (logically). So I tried selecting the select statement above into a temp table and than Update it; however, then I get the issue that I get to much results (logically! I only need 1 result and get 100) however, I'm getting stuck in my own thougts.. I ultimately need to fill the ReportID into each record of REGI.
I know it should be possible, but I'm no expert in MySQL.. is there anybody that can point me into the right direction?
Ps. fixing the table containing 400k records is not an option, it's a program from an external developer and I can only read that database.
The errors I'm talking about are as follows:
Error Code: 1093. You can't specify target table 'TrialTable' for update in FROM clause
When I use:
UPDATE TrialTable SET TrialTable.BlanccoReport =
(SELECT JT.report_id as ReportID, REGI.Serienummer as SerialNo FROM Blancco_Registration.TrialTable as REGI
JOIN (SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92) AS JT ON JT.Value_string = REGI.Serienummer
WHERE REGI.HardwareType="PC" AND REGI.BlanccoReport=0 LIMIT 100)
WHERE TrialTable.HardwareType="PC" AND TrialTable.BlanccoReport=0)
Then I tried:
UPDATE TrialTable SET TrialTable.BlanccoReport = (SELECT ReportID FROM (<<and the rest of the SQL>>> ) as x WHERE X.SerialNo = TrialTable.Serienummer)
but that gave me the following error:
Error Code: 1242. Subquery returns more than 1 row
Haveing the Query above with a LIMIT 1, gives everything the same result
Firstly, your query seems to be functionally identical to the following:
SELECT RE.report_id ReportID
, REGI.Serienummer SerialNo
FROM Blancco_Registration.TrialTable REGI
JOIN Blancco_new.mc_report_Entry RE
ON RE.Value_string = REGI.Serinummer
WHERE REGI.HardwareType = "PC"
AND REGI.BlanccoReport=0
AND RE.path_id=92
LIMIT 100
So, why not use that?
EDIT:
I still don't get it. I can't see what part of the problem the following fails to solve...
UPDATE TrialTable REGI
JOIN Blancco_new.mc_report_Entry RE
ON RE.Value_string = REGI.Serinummer
SET TrialTable.BlanccoReport = RE.report_id
WHERE REGI.HardwareType = "PC"
AND REGI.BlanccoReport=0
AND RE.path_id=92;
(This is not an answer, but maybe a pointer towards a few points that need further attention)
Your JT sub query looks suspicious to me:
(SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92
GROUP BY RE.report_id)
You use group by but don't actually use any aggregate functions. The column RE.Value_string should strictly be something like MAX(RE.Value_string) instead.

SQL Query Assistance - Left join unexpected result

I have these 2 queries:
$sql = "SELECT *
FROM ultrait_wpl_properties
LEFT JOIN ultrait_wpl_property_types
ON ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id ";
$sql2 = "SELECT *
FROM ultrait_wpl_properties, ultrait_wpl_property_types
WHERE ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id";
For some odd reason when the IDs are output some are duplicated? By my reseaning these queries should get everything from the table in the first part and join the second table based on the WHERE condition.
<property><id>13</id></property>
<property><id>6</id></property>
<property><id>6</id></property>
<property><id>6</id></property>
<property><id>6</id></property>
<property><id>7</id></property>
This may be slightly unclear but for some reason I'm getting duplicate IDs, all i want really is to be able to access the property type which links to the ID in the second table.
I have tested both queries in phpMyAdmin and they yeild the desired result, however when I use the queries in my php script they return unexpected results.
You are getting one row for each row in table ultrait_wpl_properties. What else do you expect? If it is just one record per type, then you would have to re-write your query accordingly. You select * from both tables. But is it only the type ID you need? Then why join the tables at all?
Get all type IDs:
select id from ultrait_wpl_property_types;
Get all type IDs in table ultrait_wpl_properties:
select distinct property_type from ultrait_wpl_properties;
Get all type data for types in ultrait_wpl_properties:
select * from ultrait_wpl_property_types
where id in (select property_type from ultrait_wpl_properties);
You are getting a Cartesian result in the case the ultrait_wpl_property_types table has multiple records for a single property. Such as a property type could be Type A, Type B, Type C which might be descriptive "types". So a single property would be accounted for each entry.
You might just need to do SELECT DISTINCT, or GROUP BY ultrait_wpl_properties.id to make sure only one record per ID, but with generic "Select * ", I would first try with GROUP BY.

Counting the number min records within groups

I'm building a report for a database where I need to determine the number of "first scans" grouping by company, job, and date.
The scan table can contain multiple scans for the same item, however I only want to include the original scan in my COUNT, which can only be identified as being the scan with the earliest date that matches a particular item.
My first attempt at this was:
SELECT
_item_detail.job_id,
_item_group.group_id,
_scan.company_id,
DATE(scan_date_time) as scan_date,
COUNT(1)
FROM _scan
INNER JOIN _item_detail ON _item_detail.company_id = _scan.company_id
AND
_item_detail.serial_number = _scan.serial_number
INNER JOIN _item_group ON _item_group.group_id = _item_detail.group_id
WHERE _item_detail.job_id = '0326FCM' AND _scan.company_id = '152345' AND _item_group.group_id = 13
GROUP BY
_item_detail.job_id,
_item_group.group_id,
_scan.company_id, scan_date -- first_scan_count
HAVING min(scan_date_time);
This is giving me incorrect results, though (about 3x too many). I am assuming it's because the MIN record is being recalculated for each date, so if the min was found on day 1, it may also be found on day 3 and counted again.
How can I modify my query to achieve the desired results?
Something similar to this should work... I'm not completely sure of how your tables are laid out or how the data relates them together, but this is the general idea:
SELECT
_item_detail.job_id,
_item_group.group_id,
_scan.company_id,
DATE(scan_date_time) as scan_date,
COUNT(1)
FROM
_scan s1
INNER JOIN _item_detail
ON _item_detail.company_id = s1.company_id
AND _item_detail.serial_number = s1.serial_number
AND _item_detail.job_id = '0326FCM'
INNER JOIN _item_group
ON _item_group.group_id = _item_detail.group_id
AND _item_group.group_id = 13
WHERE
s1.company_id = '152345'
AND s1.scan_date_time = (
SELECT MIN(s2.scan_date_time)
FROM _scan s2
WHERE
s2.company_id = s1.company_id
AND s2.serial_number = s1.serial_number
)
GROUP BY
_item_detail.job_id,
_item_group.group_id,
s1.company_id
I don't quite follow your query, but based on the description of the problem, I'd say create a subquery that gives the min scan date for for each item, group by items, the perform your outer select on that.