I have the following query that I've used to pull out a vehicle ID, it's registration, a driver id and the driver's name. The _core_people table you see referenced in this query also a field I wish to set to the vehicle's plate.
Here's the query:
SELECT fv._plate, cp._people_name
FROM
_fleet_vehicle fv,
_fleet_vehicle_status fvs,
_core_people cp,
_fleet_allocation fa
WHERE
cp._id_hierarchy = fv._id_hierarchy
AND fv._id_status = fvs._id
AND fvs._status_live = 1
AND fa._id_person = cp._id
AND fa._id_vehicle = fv._id
AND fa._alloc_end_date IS NULL
ORDER BY cp._people_name ASC
Now, I want to write an UPDATE...FROM clause that utilises this to set _core_people._plate (not shown here) to the plate field of their vehicle.
However, I'm not sure how to go about structuring the UPDATE...FROM clause.
Also, some drivers have 2 cars. Will it still work?
Thanks in advance!
UPDATE _core_people
SET _plate = fv._plate
FROM _fleet_vehicle fv,
_fleet_vehicle_status fvs,
_core_people cp,
_fleet_allocation fa
WHERE cp._id_hierarchy = fv._id_hierarchy
AND fv._id_status = fvs._id
AND fvs._status_live = 1
AND fa._id_person = cp._id
AND fa._id_vehicle = fv._id
AND fa._alloc_end_date IS NULL
If there are more than 1 record for _core_people matching the condition, _core_people will be updated to only one of them (it is not possible to tell which one exactly).
Related
I've been working on this problem, researching what I could be doing wrong but I can't seem to find an answer or fault in the code that I've written. I'm currently extracting data from a MS SQL Server database, with a WHERE clause successfully filtering the results to what I want. I get roughly 4 rows per employee, and want to add together a value column. The moment I add the GROUP BY clause against the employee ID, and put a SUM against the value, I'm getting a number that is completely wrong. I suspect the SQL code is ignoring my WHERE clause.
Below is a small selection of data:
hr_empl_code hr_doll_paid
1 20.5
1 51.25
1 102.49
1 560
I expect that a GROUP BY and SUM clause would give me the value of 734.24. The value I'm given is 211461.12. Through troubleshooting, I added a COUNT(*) column to my query to work out how many lines it's running against, and it's giving a result of 1152, furthering reinforces my belief that it's ignoring my WHERE clause.
My SQL code is as below. Most of it has been generated by the front-end application that I'm running it from, so there is some additional code in there that I believe does assist the query.
SELECT DISTINCT
T000.hr_empl_code,
SUM(T175.hr_doll_paid)
FROM
hrtempnm T000,
qmvempms T001,
hrtmspay T166,
hrtpaytp T175,
hrtptype T177
WHERE 1 = 1
AND T000.hr_empl_code = T001.hr_empl_code
AND T001.hr_empl_code = T166.hr_empl_code
AND T001.hr_empl_code = T175.hr_empl_code
AND T001.hr_ploy_ment = T166.hr_ploy_ment
AND T001.hr_ploy_ment = T175.hr_ploy_ment
AND T175.hr_paym_code = T177.hr_paym_code
AND T166.hr_pyrl_code = 'f' AND T166.hr_paid_dati = 20180404
AND (T175.hr_paym_type = 'd' OR T175.hr_paym_type = 't')
GROUP BY T000.hr_empl_code
ORDER BY hr_empl_code
I'm really lost where it could be going wrong. I have stripped out the additional WHERE AND and brought it down to just T166.hr_empl_code = T175.hr_empl_code, but it doesn't make a different.
By no means am I any expert in SQL Server and queries, but I have decent grasp on the technology. Any help would be very appreciated!
Group by is not wrong, how you are using it is wrong.
SELECT
T000.hr_empl_code,
T.totpaid
FROM
hrtempnm T000
inner join (SELECT
hr_empl_code,
SUM(hr_doll_paid) as totPaid
FROM
hrtpaytp T175
where hr_paym_type = 'd' OR hr_paym_type = 't'
GROUP BY hr_empl_code
) T on t.hr_empl_code = T000.hr_empl_code
where exists
(select * from qmvempms T001,
hrtmspay T166,
hrtpaytp T175,
hrtptype T177
WHERE T000.hr_empl_code = T001.hr_empl_code
AND T001.hr_empl_code = T166.hr_empl_code
AND T001.hr_empl_code = T175.hr_empl_code
AND T001.hr_ploy_ment = T166.hr_ploy_ment
AND T001.hr_ploy_ment = T175.hr_ploy_ment
AND T175.hr_paym_code = T177.hr_paym_code
AND T166.hr_pyrl_code = 'f' AND T166.hr_paid_dati = 20180404
)
ORDER BY hr_empl_code
Note: It would be more clear if you have used joins instead of old style joining with where.
I have an Access Database which links into Excel for a college database project. The goal is to fix incorrect/incomplete data before importation through the use of Update/SQL queries. There is one item in particular which is a field containing the order status. If an order is complete = Complete, if an order is missing a few parts = Backorder and nothing at all = Open. The issue I have is there is multiple parts on one PO ID# which makes it difficult to determine if an order is on backorder as 2/5 parts may be complete while 3/5 may be on backorder. Any ideas on how I can force access to automatically set a default order status or is this a long sql query?
Thanks
With SQL you can return a query to find the order status, using a CASE statement. I'm not sure of the table/column names in the parent table you have but you can probably tweak it from here (I'm just assuming identity columns):
SELECT P.Id, P.Name, "Status" =
CASE
WHEN R.QuantityReceived < I.QuantityOrdered THEN 'Backorder'
WHEN R.QuantityReceived = I.QuantityOrdered THEN 'Complete'
WHEN R.QuantityReceived > I.QuantityOrdered THEN 'Open'
END
FROM PurchaseOrders P INNER JOIN POItem I on P.PurchaseOrderId = I.PurchaseOrderId
INNER JOIN POReceipt R on I.ItemId = R.ItemId
So first you need to join your tables to get the related records (this is also assuming that there is only one of each), then use a CASE statement to return the value you are looking for based on a comparison between fields.
I'm working with PeopleSoft Campus Solutions, and we need to update about 22,000 rows of data. This is data between the tables of ACAD_PLAN_VW and ACAD_PROG. Students are listed on both, so their IDs match between the two.
Basically what we are trying to do is say that when the ID, academic career, student career number, effective sequence, and effective date match, AND where the academic plan (their degree, as stored on the ACAD_PLAN_VW) is a specific value, update the ACAD_PROG on the ACAD_PROG table to X value.
I tried to do some very interesting combinations of FROM statements, constantly getting errors. After some researching, I found out that SQLTools doesn't really like FROM statements within UPDATE statements, so I rewrote it to just make the connections manually. I'm assuming I'm doing this right, unless I need to reword it.
The statement I have is:
UPDATE PS_ACAD_PROG SET PS_ACAD_PROG.ACAD_PROG = 'UGDS'
WHERE PS_ACAD_PLAN_VW.EMPLID = PS_ACAD_PROG.EMPLID
AND PS_ACAD_PLAN_VW.ACAD_CAREER = PS_ACAD_PROG.ACAD_CAREER
AND PS_ACAD_PLAN_VW.STDNT_CAR_NBR = PS_ACAD_PROG.STDNT_CAR_NBR
AND PS_ACAD_PLAN_VW.EFFSEQ = PS_ACAD_PROG.EFFSEQ
AND PS_ACAD_PLAN_VW.EFFDT = PS_ACAD_PROG.EFFDT
AND PS_ACAD_PLAN_VW.ACAD_PLAN = 'DSTDS'
Theoretically, I would assume that this would update any student who has those connections. However, the error that I'm currently getting is as follows:
ORA-00904: "PS_ACAD_PLAN_VW"."ACAD_PLAN": invalid identifier
I have, as of yet, been unable to figure out the issue. I do have the correct access to view and update those fields, and the field does indeed exist.
Oracle doesn't know it should use the PS_ACAD_PLAN_VW table. Somehow you should reference it.
For example can you try this way?
UPDATE (
select
PS_ACAD_PROG.ACAD_PROG,
PS_ACAD_PLAN_VW.ACAD_PLAN
from
PS_ACAD_PROG,
PS_ACAD_PLAN_VW
where
PS_ACAD_PLAN_VW.EMPLID = PS_ACAD_PROG.EMPLID
AND PS_ACAD_PLAN_VW.ACAD_CAREER = PS_ACAD_PROG.ACAD_CAREER
AND PS_ACAD_PLAN_VW.STDNT_CAR_NBR = PS_ACAD_PROG.STDNT_CAR_NBR
AND PS_ACAD_PLAN_VW.EFFSEQ = PS_ACAD_PROG.EFFSEQ
AND PS_ACAD_PLAN_VW.EFFDT = PS_ACAD_PROG.EFFDT
)
SET
ACAD_PROG = 'UGDS'
WHERE
ACAD_PLAN = 'DSTDS'
Try to use the table which is not getting identified,by keeping in where clause so that you can use the select statement.That will help identifying the tables.
The following implementation should work:
UPDATE PS_ACAD_PROG
SET ACAD_PROG = 'UGDS'
WHERE ROWID IN(SELECT PROG.ROWID
FROM PS_ACAD_PROG PROG
, PS_ACAD_PLAN_VW PLAN
WHERE PLAN.EMPLID = PROG.EMPLID
AND PLAN.ACAD_CAREER = PROG.ACAD_CAREER
AND PLAN.STDNT_CAR_NBR = PROG.STDNT_CAR_NBR
AND PLAN.EFFSEQ = PROG.EFFSEQ
AND PLAN.EFFDT = PROG.EFFDT
AND PLAN.ACAD_PLAN = 'DSTDS');
I have an SQL question based on below table structure.
Database is currently in MS Access, with plans to migrate to SQL Server. Query should work in both DBMS'es.
I want to get devName and the latest dswSW_Version, based on dswTimestamp, for the device in question. If no SW history exists, I want to just return the devName.
The closest I could get was:
SELECT dev.devname, dsw1.dswsw_version
FROM device_sw_history AS dsw1 RIGHT JOIN device AS dev
ON dsw1.dswdevid = dev.devid
WHERE dsw1.dswtimestamp = (SELECT MAX(dswtimestamp) FROM device_sw_history AS dsw2 WHERE dsw1.dswdevid = dsw2.dswdevid)
AND devid = #devid
But nothing is returned for devid = 2, due to MAX returning null. I want to return Apple, null.
Is there a way to construct this statement without using a UNION and still return devname even if no SW history exists ?
Device:
devid devname
1 Samsung
2 Apple
Device_SW_History:
dswid dswdevid dswtimestamp dswsw_version
1 1 5/dec/13 One
2 1 6/dec/13 Two
Thank you !
Just put your condition in the on clause:
SELECT dev.devname, dsw1.dswsw_version
FROM device_sw_history AS dsw1 RIGHT JOIN device AS dev
ON dsw1.dswdevid = dev.devid
AND dsw1.dswtimestamp = (SELECT MAX(dswtimestamp) FROM device_sw_history AS dsw2 WHERE dsw1.dswdevid = dsw2.dswdevid)
WHERE devid = #devid
For inner joins the on and where clauses are identical, and putting a condition in one or the other is merely a question of style and readability. Outer joins introduce a difference between on and where, the on clause only applies to one table, while the where clause applies to their combination.
On SQL Server, a simple subquery should do the trick:
SELECT
devname,
(SELECT TOP 1 dswsw_version FROM device_sw_history WHERE dswdevid = devid
ORDER BY dswtimestamp DESC)
FROM device
This will return all the device names from device, even those that does not have an entry in device_sw_history.
Here is the select statement I'm using. The problem happens with the sorting. When it is like below, it only sorts by t2.userdb_user_first_name, doesn't matter if I put that first or second. When I remove that, it sorts just fine by the displayorder field value pair. So I know that part is working, but somehow the combination of the two causes the first_name to override it. What I want is for the records to be sorted by displayorder first, and then first_name within that.
SELECT t1.userdb_id
FROM default_en_userdbelements as t1
INNER JOIN default_en_userdb AS t2 ON t1.userdb_id = t2.userdb_id
WHERE t1.userdbelements_field_name = 'newproject'
AND t1.userdbelements_field_value = 'no'
AND t2.userdb_user_first_name!='Default'
ORDER BY
(t1.userdbelements_field_name = 'displayorder' AND t1.userdbelements_field_value),
t2.userdb_user_first_name;
Edit: here is what I want to accomplish. I want to list the users (that are not new projects) from the userdb table, along with the details about the users that is stored in userdbelements. And I want that to be sorted first by userdbelements.displayorder, then by userdb.first_name. I hope that makes sense? Thanks for the really quick help!
Edit: Sorry for disappearing, here is some sample data
userdbelements
userdbelements_id userdbelements_field_name userdbelements_field_value userdb_id
647 heat 1
648 displayorder 1 - Sponsored 1
645 condofees 1
userdb
userdb_id userdb_user_name userdb_emailaddress userdb_user_first_name userdb_user_last_name
10 harbourlights info#harbourlightscondosminium.ca Harbourlights 1237 Northshore Blvd, Burlington
11 harbourview info#harbourviewcondominium.ca Harbourview 415 Locust Street, Burlington
12 thebalmoral info#thebalmoralcondominium.ca The Balmoral 2075 & 2085 Amherst Heights Drive, Burlington
You are trying to use an invalid ORDER BY.
ORDER BY (t1.userdbelements_field_name = 'displayorder' AND t1.userdbelements_field_value)
It must reference a table column or returned aliased column.
I really cannot follow how this query would even be possible as you already have limited
t1.userdbelements_field_name = newproject and then you wish to order by the case of it being equal to displayorder.
Could you please modify your question to state exactly what it is that you are trying to accomplish in your order by clause?
From what I understand, you'd have to join to default_en_userdbelements solely for the displayorder value. However, I suspect there's something wrong with your query and that it probably returns duplicate values for userdb_id.
Perhaps you should say what you're trying to actually do, not explain the way you're trying to do it.
SELECT t1.userdb_id
FROM default_en_userdbelements AS t1
JOIN default_en_userdb AS t2 ON t1.userdb_id = t2.userdb_id
JOIN default_en_userdbelements AS o ON (o.userdb_id, o.userdbelements_field_name)
= (t1.userdb_id, 'displayorder')
WHERE t1.userdbelements_field_name = 'newproject'
AND t1.userdbelements_field_value = 'no'
AND t2.userdb_user_first_name != 'Default'
ORDER BY o.userdbelements_field_value,
t2.userdb_user_first_name
You could do something like this:
ORDER BY
(CASE WHEN t1.userdbelements_field_name = 'displayorder'
THEN t1.userdbelements_field_value
ELSE $some_large_number
END),
t2.userdb_user_first_name;
It sorts using the value of t1.userdbelements_field_value when t1.userdbelements_field_name = 'displayorder', but you have to supply some other value of the same type to apply for the ELSE.