SQL Join where is its own alias - sql

Select IM_ITEM.ITEM_NO As "Item #",
IM_BARCOD.BARCOD AS "Barcode",
IM_INV.MIN_QTY AS "Min Qty"
FROM IM_ITEM
INNER JOIN IM_INV ON IM_INV.ITEM_NO = IM_ITEM.ITEM_NO
INNER JOIN IM_BARCOD ON IM_BARCOD.ITEM_NO = IM_ITEM.ITEM_NO
where IM_BARCOD.BARCOD_ID ='BIN#'
or IM_BARCOD.BARCOD_ID ='ITEM'
or IM_BARCOD.BARCOD_ID ='ALT1'
ORDER BY IM_ITEM.CATEG_SUBCAT ASC, IM_ITEM.ITEM_NO ASC;
This works great for me however it repeats the part number for every row there is more than one barcode. I want the different barcodes in their own column instead of having to duplicate the part number on every row there is a different barcode. ever better would be if it selected all barcodes and put them in their own column for that part number. Thanks for the help I am very new to any type of coding!

Related

Calculate differences between two columns of two different tables

I want to calculate the difference between purchase order amount and purchase invoice amount. But I am not able to fetch the purchase invoice amount i.e. "pi.grand_total" and hence also not able to fetch the difference of "(pi.grand_total - po.grand_total)" . Please help.Below is my query.
PO = Purchase Order
PI = Purchase Invoice
SELECT DISTINCT
po.name AS "PO #:Link/Purchase Order:120",
po.supplier AS "Supplier:Link/Supplier:120",
po.Company AS "Company:Data:120",
po.currency AS "Currency:Link/Currency:120",
po.base_grand_total AS "Grand Total:Currency:120",
po.status AS "Status:Data:120",
po.per_received AS "Per Received:Data:120",
CEILING(po.per_billed) AS "Per Billed:Data:120",
po.delivery_date AS "Delivery Date:Date:120",
pi.grand_total AS "Final PI Total:120",
(pi.grand_total - po.grand_total) AS "Amount Difference:120"
FROM
"tabPurchase Order" as po
LEFT JOIN "tabPurchase Invoice" as pi ON po.name = pi.parent
WHERE
po.per_received = 100
AND
CEILING(po.per_billed) < 100
ORDER BY po.delivery_date ASC
You are using LEFT JOIN. This means when your second table has no data which matches with your first table you will receive no data from second table but nonetheless your first table will return all of its data.
You probably should check your join condition. If you wanted to join these two tables the way you want then use NVL Function for pi.grand_total column. Because it is on the left join it could have a NULL value thus NULL minus po.grand_total will give you NULL. NVL function turns NULL values into intended values like NVL(pi.grand_total,0)
A good example how joins work

SQL report filtering, results stop after first item

and thanks in advance. I am a newbie, working on one of my first reports. I have orders, which have a terminal assigned them (a "DC"). The report is set up to return all open orders, the "DC", and a few other columns (driver #, city, etc). I made a drop down filter to use so I can look at one, several, or all of the DCs. My problem is, it stops looking after the first item that is checked in the drop down list. So if the first item in the list has 100 orders, but the rest of them have thousands more, it only shows me the 100 orders. Am I making any sense here? I am not sure what information from my report's setup would be pertinent here.
This is the query that the report is based on. Using SQL Report Builder.
SELECT
o.OrderTrackingID,
cm.accountno,
o.ClientRefNo,
o.DCoName,
o.DStreet,
o.DCity,
o.DState,
o.DZip,
o.DZone,
t.TerminalName as 'OrderDC',
e.LastName as 'DrvLast',
e.FirstName as 'DrvFirst',
e.DriverNo,
et.TerminalName as 'DriverDC'
FROM Orders o
FULL JOIN OrderDrivers od ON o.OrderTrackingID = od.OrderTrackingID
FULL JOIN Employees e ON od.DriverID = e.ID
FULL JOIN ClientMaster cm ON o.ClientID = cm.ClientID
FULL JOIN Terminals t ON o.TerminalID = t.TerminalID
FULL JOIN Terminals et ON e.TerminalID = et.TerminalID
WHERE o.Status = 'N'
Order By o.aTimeStamp ASC
(I am writing this as an answer even if it isn't an complete answer mostly because the comment field is kind of limited.)
In the SQL you posted the below stands out as wrong
FULL JOIN Terminals t ON o.TerminalID = t.TerminalID
FULL JOIN Terminals et ON e.TerminalID = et.TerminalID
You are joining the same table twice but the is nothing that separated the two joins and this is my guess why you are not getting any more orders in your report.
I don't now what the drop down list corresponds to but I assume it is some kind of identifier in the Terminals table.
From a pure SQL point of view I would expect something like this
FULL JOIN Terminals t ON o.TerminalID = t.TerminalID
WHERE t.someColumn IN (value1, value2)
where value1 and value2 comes from the drop down list.
I see in your select part that you include the same column from both of the Terminals JOIN you have and I expect those two columns to always have the same values. You should need that column only once in your select list.
Not a solution but maybe this can get you in the right direction.

Select Max Row from Column

I have scan codes used in a table, but the table doesn't save just the newest scan codes. So I have order numbers with multiple items on those orders.
The issue is I need the last scan code on each item number for each order and not every time it has been scanned. Essentially I don't need to know that it has been scanned from prep to customization to shipping. I just need to know that it is in shipping. I get three results for one item number because it has been scanned three times.I don't need duplicate result from where it has been previously scanned.
The "S3DTNSEQ#" column is the number of times it has been scanned.I need to only keep the rows with the highest scan count. Anything lower than the highest scan count I need to get rid of. The 'Scan To' column is "S3DTSTO". So using the "S3DTNSEQ#" column to determine which row is kept is the idea.
SELECT
TMON as "order number",
TMCPO# as "po#",
TMRQD as "due date",
S3ITNO as "item number",
S3ORQT as "quantity",
TMCUST as "cust#",
TMNAME as, "cust name"
S3DTSTO as "scanned to",
TMSCHID as "sched id,
MAX( S3DTNSEQ# ) AS "S3DTNSEQ#",
S3DTADT as "maintained date"
FROM
TSA400.NRPDTA.SOP114F1 SOP114F1,
TSA400.NRPDTA.SOA SOA,
TSA400.NRPDTA.S3O S3O,
TSA400.NRPDTA.S3DTU S3DTU
WHERE SOP114F1.TMON = SOA.SOON
AND SOP114F1.TMSHP# = SOA.SOSHPN
AND SOP114F1.TMCUST = SOA.SOCUST
AND SOA.SOON = S3O.S3ON
AND SOP114F1.TMON = S3O.S3ON
AND SOA.SOCUST = S3O.S3CUST
AND SOP114F1.TMCUST = S3O.S3CUST
AND SOA.SOSHPN = S3O.S3SHPN
AND SOP114F1.TMON = S3DTU.S3DTON
AND SOP114F1.TMSHP# = S3DTU.S3DTSHP#
GROUP BY
TMON,
TMCPO#,
TMRQD,
S3ITNO,
S3ORQT,
TMCUST,
TMNAME,
S3DTSTO,
TMSCHID,
S3DTADT
I imagine I need a subquery to do this, but i am completely lost, on how to do this. I apologize, the query was created in "Showcase" which uses where clauses extensively instead of joins.

SQL LEFT JOIN WHERE not displaying right result

So I got this query:
Data structure:
Users
id---inlog----name----more stuff
llntoets
id---code----inlog----more stuff
oefeningen
id---speler---status----morestuff
(inlog and speler are always the same values for a user)
SELECT
// Some other stuff working
SUM(o.status) AS oefn
FROM users AS u
LEFT JOIN llntoets AS l
ON (u.inlog = l.inlog)
LEFT JOIN oefeningen AS o
ON (u.inlog = o.speler) AND o.status = 'afgewerkt'
WHERE
code = '$code'
GROUP BY l.inlog
ORDER BY klas ASC, klasnr ASC
Everything runs fine except 1 thing the oefn variable. It shows a number sometimes it shows the correct value and sometimes it shows a value that is much higher than it should be. Someone told me it could be because of the GROUP BY. Can someone help me pls?
It is supposed to count the total records from table oefeningen where status = 'afgewerkt' and where the speler is the inlog from users. Thanks, if you got other questions ask will try to explain more.
the SUM(o.status) in your query it is not supposed to count the total records of table oefeningen.
that sum is the sum of the values of all the joined rows that satisfy your criteria that can be a much higher number.
also note that applying the filter o.status = 'afgewerkt' you are performing a JOIN even if you wrote LEFT JOIN throghout the query.

MySQL to return only last date / time record

We have a database that stores vehicle's gps position, date, time, vehicle identification, lat, long, speed, etc., every minute.
The following select pulls each vehicle position and info, but the problem is that returns the first record, and I need the last record (current position), based on date (datagps.Fecha) and time (datagps.Hora). This is the select:
SELECT configgps.Fichagps,
datacar.Ficha,
groups.Nombre,
datagps.Hora,
datagps.Fecha,
datagps.Velocidad,
datagps.Status,
datagps.Calleune,
datagps.Calletowo,
datagps.Temp,
datagps.Longitud,
datagps.Latitud,
datagps.Evento,
datagps.Direccion,
datagps.Provincia
FROM asigvehiculos
INNER JOIN datacar ON (asigvehiculos.Iddatacar = datacar.Id)
INNER JOIN configgps ON (datacar.Configgps = configgps.Id)
INNER JOIN clientdata ON (asigvehiculos.Idgroup = clientdata.group)
INNER JOIN groups ON (clientdata.group = groups.Id)
INNER JOIN datagps ON (configgps.Fichagps = datagps.Fichagps)
Group by Fichagps;
I need same result I'm getting, but instead of the older record I need the most recent
(LAST datagps.Fecha / datagps.Hora).
How can I accomplish this?
Add ORDER BY datagps.Fecha DESC, datagps.Hora DESC LIMIT 1 to your query.
I'm not sure why you are having any problems with this as Lex's answers seem good.
I would start putting ORDER BY's in your query so it puts them in an order, when it's showing the record you want as the first one in the list, then add the LIMIT.
If you want the most recent, then the following should be good enough:
ORDER BY datagps.Fecha DESC, datagps.Hora DESC
If you simply want the record that was added to the database most recently (irregardless of the date/time fields), then you could (assuming you have an auto-incremental primary key in the datagps table (I assume it's called dataID for this example)):
ORDER BY datagps.dataID DESC
If these aren't showing the data you want - then there is something missing from your example (maybe data-types aren't DATETIME fields? - if not - then maybe a CONVERT to change them from their current type before ORDERing BY would be a good idea)
EDIT:
I've seen the screenshot and I'm confused as to what the issue is still. That appears to be showing everything in order. Are you implying that there are many more than 5 records? How many are you expecting?
Do you mean: for each record returned, you want the one row from the table datagps with the latest date and time attached to the result? If so, how about this:
# To show how the query will be executed
# comment to return actual results
EXPLAIN
SELECT
configgps.Fichagps, datacar.Ficha, groups.Nombre, datagps.Hora, datagps.Fecha,
datagps.Velocidad, datagps.Status, datagps.Calleune, datagps.Calletowo,
datagps.Temp, datagps.Longitud, datagps.Latitud, datagps.Evento,
datagps.Direccion, datagps.Provincia
FROM asigvehiculos
INNER JOIN datacar ON (asigvehiculos.Iddatacar = datacar.Id)
INNER JOIN configgps ON (datacar.Configgps = configgps.Id)
INNER JOIN clientdata ON (asigvehiculos.Idgroup = clientdata.group)
INNER JOIN groups ON (clientdata.group = groups.Id)
INNER JOIN datagps ON (configgps.Fichagps = datagps.Fichagps)
########### Add this section
LEFT JOIN datagps b ON (
configgps.Fichagps = b.Fichagps
# wrong condition
#AND datagps.Hora < b.Hora
#AND datagps.Fecha < b.Fecha)
# might prevent indexes to be used
AND (datagps.Fecha < b.Fecha OR (datagps.Fecha = b.Fecha AND datagps.Hora < b.Hora))
WHERE b.Fichagps IS NULL
###########
Group by configgps.Fichagps;
Similar question here only that that one uses outer joins.
Edit (again):
The conditions are wrong so corrected it. Can you show us the output of the above EXPLAIN query so we can pinpoint where the bottle neck is?
As hurikhan77 said, it will be better if you could convert both of the the columns into a single datetime field - though I'm guessing this would not be possible for your case (since your database is already being used?)
Though if you can convert it, the condition (on the join) would become:
AND datagps.FechaHora < b.FechaHora
After that, add an index for datagps.FechaHora and the query would be fast(er).
What you probably want is getting the maximum of (Fecha,Hora) per grouped dataset? This is a little complicated to accomplish with your column types. You should combine Fecha and Hora into one column of type DATETIME. Then it's easy to just SELECT MAX(FechaHora) ... GROUP BY Fichagps.
It could have helped if you posted your table structure to understand the problem.