I have the below query in mysql, when I run the query, it gives me the complete report and "where clause does not work"
SELECT oo.dateaccessioned AS 'Date',
oo.barcode AS 'Acc. No.',
ooo.title AS 'Title',
ooo.author AS 'Author/Editor',
concat_ws(' , ', o.editionstatement, oo.enumchron) AS 'Ed./Vol.',
concat_ws(' ', o.place, o.publishercode) AS 'Place & Publisher',
ooo.copyrightdate AS 'Year', o.pages AS 'Page(s)',
ooooooo.name AS 'Source',
oo.itemcallnumber AS 'Class No./Book No.',
concat_ws(', ₹', concat(' ', ooooo.symbol, oooo.listprice), oooo.rrp_tax_included) AS 'Cost',
concat_ws(' , ', oooooo.invoicenumber, oooooo.shipmentdate) AS 'Bill No. & Date',
'' AS 'Withdrawn Date',
'' AS 'Remarks'
FROM biblioitems o
LEFT JOIN items oo ON oo.biblioitemnumber=o.biblioitemnumber
LEFT JOIN biblio ooo ON ooo.biblionumber=o.biblionumber
LEFT JOIN aqorders oooo ON oooo.biblionumber=o.biblionumber
LEFT JOIN currency ooooo ON ooooo.currency=oooo.currency
LEFT JOIN aqinvoices oooooo ON oooooo.booksellerid=oo.booksellerid
LEFT JOIN aqbooksellers ooooooo ON ooooooo.id=oo.booksellerid
WHERE cast(oo.barcode AS UNSIGNED) BETWEEN <<Accession Number>> AND <<To Accession Number>>
GROUP BY oo.barcode
ORDER BY oo.barcode ASC
Can you please help me to generate a report based on above query – oo.barcode (it is a varchar). I am a Library team member than a database administrator. My oo.barcode begins with HYD and then numercs. I know if it(oo.barcode) is a number only field the above query works without any issue.
I search about how cast works but not able to understand as i am not into database administration.
2
Answers
Try this :
SUBSTRING_INDEX(oo.barcode,'HYD',-1)
will transform HYD132453741 to 132453741demo here
If the barcode column is
VARCHAR
and begins with "HYD",CAST AS UNSIGNED
will cause a value ofHYD123
to result in0
.The non-numeric characters of the string would need to be removed prior to casting the value as an integer.
This can be achieved by trimming the leading text "HYD" from the barcode.
Otherwise, if the prefix is always 3 characters, the substring position of barcode can be used.
If any other non-numeric characters are contained within the string, such as
HYD-123-456-789
,HYD123-456-789PT
,HYD123-456.789
, etc, they will also needed to be removed, as the type conversion will treat them in unexpected ways.In addition, any leading 0’s of the resulting numeric string value will be truncated from the resulting integer, causing
0123
to become123
.For more details on how
CAST
functions see: 12.3 Type Conversion in Expression EvaluationExamples db<>fiddle
Results
JOIN optimization
To obtain the expected results, you most likely want an
INNER JOIN
of theitems
table with anON
criteria matching the desiredbarcode
range condition. SinceINNER JOIN
is the equivalent of usingWHERE oo.barcode IS NOT NULL
, as is the case with your current criteria –NULL
matches within theitems
table are already being excluded.Full-Table Scanning
It is important to understand that transforming the column value to suit a criteria will cause a full-table scan that does not benefit from indexing, which will run very slowly.
Instead it is best to store the integer only version of the value in the database to see the benefits of indexing.
This can be accomplished in many ways, such as generated columns.
GROUP BY without an aggregate
Lastly, you should avoid using
GROUP BY
without an aggregate function. You most likely are expectingDISTINCT
or similar form of limiting the record set. Please see MySQL select one column DISTINCT, with corresponding other columns on ways to accomplish this.To ensure MySQL is not selecting "any value from each group" at random (leading to differing results between query executions), limit the subset data to the distinct
biblioitemnumber
column values from the availablebarcode
matches. One approach to accomplish the limited subset is as follows.