Counting the number min records within groups - mysql

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.

Related

count records is not giving the right number

When I type the following query
SELECT
COUNT(*) AS COUNT
FROM
OP_table OP
WHERE
OP.TARGET_ID= 4330000000000369;
I get a count of 55
When I try to use it in a join
SELECT
TS.TARGET_ID, T.TARGET_NAME, T.TARGET_PUBLIC_NAME, count( DISTINCT OP.OP_ID) AS OP_COUNT
FROM
TS_table TS
INNER jOIN
T_table T
ON
T.TARGET_ID = TS.TARGET_ID
OUTER JOIN
OP_TABLE OP
ON
OP.TARGET_ID = T.TARGET_ID
WHERE
TS.TARGET_SERVICE_ID = number
Then I get
TARGET_ID, TARGET_NAME, TARGET_PUBLIC_NAME, OP_COUNT
number, target name, Ebook Central History 33781
with an count of 33781. I want to use the 2nd functions structure but get the right count of 55
for some reason it's getting the count of the Target_id's instead of Target_service ID's
also I noticed if I type the following
SELECT
COUNT(*) AS COUNT
FROM
KB_OBJECT_PORTFOLIOS OP
WHERE
OP.TARGET_ID=4330000000000383;
where that number corresponds will produce the result 33781.
somewhere within the joining it's getting rid of the target ID of 4330000000000369 and using a different target ID 4330000000000383
Ok, I get mixed up from the stupid column names OP.target_ID = TS.target_service_id and not TS.target_ID...

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.

I need to sort by the most changed GROUP by in a table

I have a MySQL table called EssayStats with three columns, EssayDate, WordCount and EssayId.
Each row is a record of when the bot recorded how many words were in an essay at a particular point in time.
I'm trying to write a query that will group by EssayId and sort by the largest increase in WordCount from a particular EssayDate to an ending EssayDate.
I'm not really sure where to start. I've tried a handful of things but they obviously don't accomplish what I jeed. My most recent query attempt was
SELECT *
FROM EssayStats
WHERE EssayDate >= "2014-01-01" AND EssayDate <= "2014-05-31"
GROUP BY EssayId
ORDER BY (WordCount)
Start by getting the dates at the beginning and end for each essay. Then join back the original tables to get the counts and do some arithmetic:
select es.EssayId, (esmax.WordCount - esmin.WordCount)
from (select es.EssayId, min(es.EssayDate) as mined, max(es.EssayDate) as maxed
from EssayStats es
group by es.EssayId
) es join
EssayStats esmin
on es.EssayId = esmin.EssayId and es.mined = esmin.EssayDate join
EssayStats esmax
on es.EssayId = esmax.EssayId and es.maxed = esmax.EssayDate;

Leave out certain dates on Access report

I have a report in Access 2013 that prints an equipment log. There is a bunch of dates listed for each piece of equipment. I wanted to only print the newest date for each piece of equipment. I have searched the internet and this site with no luck. So any suggestions will be greatly appreciated.
My SQL statement is:
SELECT dbo_eq_location_transfer_d.equipment_id, dbo_equipment.description, dbo_eq_location_transfer_d.transaction_no, dbo_eq_location_transfer_d.job_no, dbo_jobs.description, dbo_eq_location_transfer_d.date_booked, dbo_eq_location_transfer_d.delivery_time, dbo_eq_location_transfer_d.line_no, dbo_eq_location_transfer_d.row_modified_by, dbo_eq_location_transfer_d.comment
FROM (dbo_eq_location_transfer_d INNER JOIN dbo_jobs ON dbo_eq_location_transfer_d.job_no = dbo_jobs.job_no) INNER JOIN dbo_equipment ON dbo_eq_location_transfer_d.equipment_no = dbo_equipment.equipment_no
ORDER BY dbo_eq_location_transfer_d.equipment_id, dbo_eq_location_transfer_d.transaction_no;
The date_booked field is the date field I am trying narrow down. I have a simple SQL query that works and I have been trying copy that into the about SQL but cannot seem to get it to mesh. It is:
SELECT [dbo_eq_location_transfer_d.equipment_no], Max(dbo_eq_location_transfer_d.date_booked) AS ["Newest Date"]
FROM dbo_eq_location_transfer_d
GROUP BY [dbo_eq_location_transfer_d.equipment_no];
In your query set the date fields criteria to:
>Now()-30
This will show any dates for the last 30 days just change 30 to the number of days you want to see.
Now that I understand your structure & data, here is what I did:
(1) Create the following query to select only the most recent 'date_booked' for each 'equipment_no'; save the query with name '23020071_A':
SELECT dbo_eq_location_transfer_d.equipment_no,
First(dbo_eq_location_transfer_d.transaction_no) AS FirstOftransaction_no,
First(dbo_eq_location_transfer_d.job_no) AS FirstOfjob_no,
First(dbo_eq_location_transfer_d.date_booked) AS FirstOfdate_booked
FROM (dbo_eq_location_transfer_d
INNER JOIN dbo_jobs ON dbo_eq_location_transfer_d.job_no = dbo_jobs.job_no)
INNER JOIN dbo_equipment ON dbo_eq_location_transfer_d.equipment_no = dbo_equipment.equipment_no
GROUP BY dbo_eq_location_transfer_d.equipment_no
ORDER BY First(dbo_eq_location_transfer_d.date_booked) DESC;
(2) I created the following query combining the new query with your existing query:
SELECT dbo_eq_location_transfer_d.equipment_id, dbo_equipment.description,
dbo_eq_location_transfer_d.transaction_no, dbo_eq_location_transfer_d.job_no,
dbo_jobs.description, dbo_eq_location_transfer_d.date_booked,
dbo_eq_location_transfer_d.delivery_time, dbo_eq_location_transfer_d.line_no,
dbo_eq_location_transfer_d.row_modified_by, dbo_eq_location_transfer_d.comment
FROM 23020071_A INNER JOIN ((dbo_eq_location_transfer_d
INNER JOIN dbo_jobs ON dbo_eq_location_transfer_d.job_no = dbo_jobs.job_no)
INNER JOIN dbo_equipment ON dbo_eq_location_transfer_d.equipment_no = dbo_equipment.equipment_no)
ON ([23020071_A].FirstOftransaction_no = dbo_eq_location_transfer_d.transaction_no)
AND ([23020071_A].equipment_no = dbo_eq_location_transfer_d.equipment_no)
AND ([23020071_A].FirstOfjob_no = dbo_eq_location_transfer_d.job_no)
ORDER BY dbo_eq_location_transfer_d.equipment_id, dbo_eq_location_transfer_d.transaction_no;
Now when I run the second query, it returns only the most recent row for that piece of equipment.

MS Access query multiple criteria

I am trying to build an access query with multiple criteria. The table to be queried is "tblVendor" which has information about vendor shipment data as shown below:
The second table is "tblSchedule" which has the schedule for each Vendor cutoff date. This table has cutoff dates for data analysis.
For each vendor, I need to select records which have the ShipDate >= CutoffDate. Although not shown in the data here, it may be possible that multiple vendors have same CutoffDate.
For small number of records in "tblCutoffdate", I can write a query which looks like:
SELECT tblVendors.ShipmentId, tblVendors.VendorNumber, tblVendors.VendorName,
tblVendors.Units, tblVendors.ShipDate
FROM tblVendors INNER JOIN tblCutoffDate ON tblVendors.VendorNumber =
tblCutoffDate.VendorNumber
WHERE (((tblVendors.VendorNumber) In (SELECT VendorNumber FROM [tblCutoffDate] WHERE
[tblCutoffDate].[CutoffDate] = #2/1/2014#)) AND ((tblVendors.ShipDate)>=#2/1/2014#)) OR
(((tblVendors.VendorNumber) In (SELECT VendorNumber FROM [tblCutoffDate] WHERE
[tblCutoffDate].[CutoffDate] = #4/1/2014#)) AND ((tblVendors.ShipDate)>=#4/1/2014#));
As desired, the query gives me a result which looks like:
What concerns me now is that I have a lot of records being added to the "tblCutoffDate" which makes it difficult for me to hardcode the dates in the query. Is there a better way to write the above SQL statement without any hardcoding?
You might try something like -- this should handle vendors having no past cutoff,
or those having no future cutoff
"today" needs a suitable conversion to just date w/o time
comparison "=" may go on both, or one, or none Max/Min
"null" may be replaced by 1/1/1900 and 12/31/3999 in Max/Min
SELECT tblvendors.shipmentid,
tblvendors.vendornumber,
tblvendors.vendorname,
tblvendors.units,
tblvendors.shipdate
FROM tblvendors
LEFT JOIN
( SELECT vendornum,
Max( iif cutoffdate < today, cutoffdate, null) as PriorCutoff,
Min( iif cutoffdate >= today, cutoffdate, null) as NextCutoff
FROM tblcutoffdate
GROUP BY vendornum
) as VDates
ON vendornumber = vendornum
WHERE tblvendors.shipdate BETWEEN PriorCutoff and NextCutoff
ORDER BY vendornumber, shipdate, shipmentid
A simpler WHERE clause should give you what you want.
SELECT
v.ShipmentId,
v.VendorNumber,
v.VendorName,
v.Units,
v.ShipDate
FROM
tblVendors AS v
INNER JOIN tblCutoffDate AS cd
ON v.VendorNumber = cd.VendorNumber
WHERE v.ShipDate >= cd.CutoffDate;