SQL query question - sql

So...I'm new to sql and loving what I've learned, but here is a question I'm stumped on.
I've created a website form. It's a timecard type form. A user logs on and clicks a pull down menu (which is being selected from the DB) It's called jobsite, then he scrolls down and clicks Jobsite#2. (both fields are selecting from the same table..) When they submit, it submits into the DB just fine. Showing both fields as the ID number they picked.. Not the name..
SELECT jobsite.Jobsite as 'Customer',
FROM timeCard
LEFT JOIN jobsite ON timeCard.jobsite = jobsite.id
That query works great. Pulling timeCard.jobsite information. If I change it to
LEFT JOIN jobsite ON timeCard.jobsite2 = jobsite.id
That works great too pulling all the inputted data from Jobsite2...What query will work to get them to show as 'Customer 1, and Customer2' on the same query? Does my question make sense? I'm trying to get it to export into Excel so that it would show up with all the information on one line basically. Employee 1, worked at jobsite 1 and jobsite 4 (but instead show: Employee (me) worked at (this place) and (that place)
Where both jobsites come from the same table in the DB
Thanks for any help you guys/gals can give

You're going to need to join to the jobsite table twice, because one timecard record is associated with two different jobsite records (assuming some things about your schema and DBMS...):
SELECT t.EmployeeName, j1.jobsite AS 'Customer 1', j2.jobsite AS 'Customer 2'
FROM timecard t
LEFT JOIN jobsite j1 ON t.jobsite = j1.id
LEFT JOIN jobsite j2 ON t.jobsite2 = j2.id

SELECT js1.jobsite AS customer1, js2.jobsite AS customer2
FROM timecard tc
LEFT JOIN
jobsite js1
ON js1.id = tc.jobsite
LEFT JOIN
jobsite js2
ON js2.id = tc.jobsite2

Are you asking for something like this?
SELECT jobsite.Jobsite as 'Customer',
FROM timeCard, jobSite
WHERE timeCard.jobsite = jobsite.id
OR timeCard.jobsite2 = jobsite.id
(PS. Since you mentioned you are new to SQL, I'd like to take this opportunity to make sure you know about parameterized queries (articles on ASP.Net, PHP), which you should always be using instead of concatenating strings)

Related

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.

Bcause of Null Value data is not refleting

I have two tables view_shipment_order_release and order_release_remark. When there is no record in order_release_remark for a given order_release_gid, there is no data shown. I want to show data in view_shipment_order_release even if there is no data in order_release_remark. How can I do this? My query is shown below.
select distinct
vsor.shipment_gid,
vsor.order_release_gid,
orem1.remark_text as Related_Party,
orem2.remark_text as ULTIMATE_CONSIGNEE_TYPE,
orem3.remark_text as CONSIGNEE_TYPE
from
order_release_remark orem1,
order_release_remark orem2,
order_release_remark orem3,
view_shipment_order_release vsor
--order_release_gid in('GECORP.18460727','GECORP.18435030','GECORP.18439869')
where
orem1.REMARK_QUAL_GID ='GECORP.CONSIGNEE TYPE'
and orem1.order_release_gid=vsor.order_release_gid
and orem2.REMARK_QUAL_GID ='GECORP.RELATED PARTY'
and orem2.order_release_gid=vsor.order_release_gid
and orem3.REMARK_QUAL_GID ='GECORP.ULTIMATE CONSIGNEE TYPE'
and orem3.order_release_gid=vsor.order_release_gid
and vsor.shipment_gid='GECORP.101027274'
;
Use left join instead. left join will not be strict and will still display even if there is no data on related party.
select distinct
vsor.shipment_gid,
vsor.order_release_gid,
orem1.remark_text as Related_Party,
orem2.remark_text as ULTIMATE_CONSIGNEE_TYPE,
orem3.remark_text as CONSIGNEE_TYPE
from view_shipment_order_release vsor
LEFT JOIN order_release_remark orem1
ON orem1.REMARK_QUAL_GID ='GECORP.CONSIGNEE TYPE'
and orem1.order_release_gid=vsor.order_release_gid
LEFT JOIN order_release_remark orem2
ON orem2.REMARK_QUAL_GID ='GECORP.RELATED PARTY'
and orem2.order_release_gid=vsor.order_release_gid
LEFT JOIN order_release_remark orem3
ON orem3.REMARK_QUAL_GID ='GECORP.ULTIMATE CONSIGNEE TYPE'
and orem3.order_release_gid=vsor.order_release_gid
where vsor.shipment_gid='GECORP.101027274';
I can only assume that you actually mean order_release_remark.remark_text - which is called Related_Party in your output.
If this is indeed the case - there is nothing in this query that explains such behavior.
However, your query is bases on a view - view_shipment_order_release (at least I hope it's a view). Views are just names for select statements - which means that oracle is combining the query recorded in the view with the select statement you posted. My guess is, that there is something in that view that says that that order_release_remark.remark_text must not be empty. Or may be the records where it's empty do not have a value in order_release_gid?
Bear in mind, oracle believes that null is not equal null - so if order_release_gid is not present (is null) in two records, joining on this field will not return any rows.

SQL - getting data twice from the same table

Good people of the internet, I need your help!
I'm trying to put together some SQL code to create a report. Basically, I'm needing to look at one table - tbl_Schedules - and fetch the maximum of the field SchedDone, which is a regular date field.
This is fair enough. I manage this using GROUP BY and MAX.
The same table also contains SchedFrom and SchedTo fields, and I need to get this from another record, but run alongside this.
Basically, I need a "LatestDate" field (which shows the max SchedDone), and then a "next scheduled" field (or fields), showing when it is next to be done, pulled from a row where the SchedDone is null.
My current code, displayed below (ignore everything but the tbl_Schedules stuff) is working to an extent. It shows the LatestDate as described above, but also shows the maximum of that Task's SchedFrom and SchedTo. These are all from different rows in the tbl_Schedules, which is what I want. I just need to know how to set up rules for the SchedFrom and SchedTo, preferably without involving any other tables or setting up multiple views.
I do have this working, but it's taking up several views and the speed involved is not good. I'd hope I can get it working in a single chunk of SQL code.
PS - tbl_PhysicalAssets is a one-to-many relationship with tbl_Operations (one row in tbl_PhysicalAssets to many in tbl_Operations), and tbl_Operations is a one-to-many relationship with tbl_Schedules (one row in tbl_Operations to many in tbl_Schedules).
Current code below (again, please ignore the other tables!) -
SELECT
dbo.tbl_PhysicalAsset.FKID_Contract,
dbo.tbl_PhysicalAsset.MyLevel,
dbo.tbl_PhysicalAsset.L1_Name,
dbo.tbl_PhysicalAsset.L2_Name,
dbo.tbl_PhysicalAsset.L3_Name,
dbo.tbl_OpList.Operation_Name,
dbo.tbl_Teams.Team_Name,
MAX(tbl_Schedules_1.SchedDone) AS LatestDate,
MAX(tbl_Schedules_1.SchedFrom) AS Expr1,
MAX(tbl_Schedules_1.SchedTo) AS Expr2
FROM
dbo.tbl_Schedules AS tbl_Schedules_1
RIGHT OUTER JOIN
dbo.tbl_PhysicalAsset
INNER JOIN
dbo.tbl_Operations ON dbo.tbl_PhysicalAsset.PKID_PhysicalAsset = dbo.tbl_Operations.FKID_PhysicalAsset
INNER JOIN
dbo.tbl_OpList ON dbo.tbl_Operations.FKID_Operation = dbo.tbl_OpList.PKID_Op
INNER JOIN
dbo.tbl_Teams ON dbo.tbl_Operations.FKID_Team = dbo.tbl_Teams.PKID_Team ON tbl_Schedules_1.FKID_Operation = dbo.tbl_Operations.PKID_Operation
GROUP BY
dbo.tbl_PhysicalAsset.FKID_Contract,
dbo.tbl_PhysicalAsset.MyLevel,
dbo.tbl_PhysicalAsset.L1_Name,
dbo.tbl_PhysicalAsset.L2_Name,
dbo.tbl_PhysicalAsset.L3_Name,
dbo.tbl_OpList.Operation_Name,
dbo.tbl_Teams.Team_Name
HAVING
(dbo.tbl_PhysicalAsset.FKID_Contract = 6)
AND (dbo.tbl_PhysicalAsset.MyLevel = 3)
This is rough as we don't know the exact details of your table structure.
But basically you need to first write the queries that get the two separate bits of information, make sure they work in isolation. You can then just join them together.
So something like (I've assumed FKID_Operation is the 'common' piece of info):
select
a.FKID_Operation
, b.LatestDate
, c.NextToDate
, c.NextFromDate
from tbl_Schedules a
inner join
(
select
m.FKID_Operation
, Max(m.SchedDone) as LatestDate
from tbl_Schedules m
where SchedDone is not null
) b
on a.FKID_Operation = b.FKID_Operation
inner join
(
select
n.FKID_Operation
, n.SchedTo as NextToDate
, n.SchedFrom as NextFromDate
from tbl_Schedules n
where SchedDone is null
) c
on a.FKID_Operation = c.FKID_Operation
I'd also look into CTE's as they can make this kind of query much easier to understand.

Way to combine filtered results using LIKE

I have a many to many relationship between people and some electronic codes. The table with the codes has the code itself, and a text description of the code. A typical result set from a query might be (there are many codes that contain "broken" so I feel like it's better to search the text description rather than add a bunch of ORs for every code.)
id# text of code
1234 broken laptop
1234 broken mouse
Currently the best way for me to get a result set like this is to use the LIKE%broken% filter. Without changing the text description, is there any way I can return only one instance of a code with broken? So in the example above the query would only return 1234 and broken mouse OR broken laptop. In this scenario it doesn't matter which is returned, all I'm looking for is the presence of "broken" in any of the text descriptions of that person's codes.
My solution at the moment is to create a view that would return
`id# text of code
1234 broken laptop
1234 broken mouse`
and using SELECT DISTINCT ID# while querying the view to get only one instance of each.
EDIT ACTUALLY QUERY
SELECT tblVisits.kha_id, tblICD.descrip, min(tblICD.Descrip) as expr1
FROM tblVisits inner join
icd_jxn on tblVisits.kha_id = icd_jxn.kha)id inner join tblICD.icd_fk=tblICD.ICD_ID
group by tblVisits.kha_id, tblicd.descrip
having (tblICD.descrip like n'%broken%')
You could use the below query to SELECT the MIN code. This will ensure only text per id.
SELECT t.id, MIN(t.textofcode) as textofcode
FROM table t
WHERE t.textofcode LIKE '%broken%'
GROUP BY t.id
Updated Actual Query:
SELECT tblVisits.kha_id,
MIN(tblICD.Descrip)
FROM tblVisits
INNER JOIN icd_jxn ON tblVisits.kha_id = icd_jxn.kha)id
INNER JOIN tblicd ON icd_jxn.icd_fk = tbl.icd_id
WHERE tblICD.descrip like n'%broken%'
GROUP BY tblVisits.kha_id

How to create a query to get all records from one table and fill in field information from a second table with a where statement?

I have two tables. One is called prem and contains all ids that exist in a system, and JimsQueryByColl which has most of those ids with various information attached. I am trying to create a single query that will include all of the ids from prem, and all of the records from the JimsQueryByColl where JimsQueryByColl.Collector = "Frederick Road". The current query I have is as follows but only gives the latter part of the information (without the ids from the prem that don't appear in a list of ids with Frederick Road in the collector collumn):
SELECT Prem.meter_miu_id,
JimsQueryByColl.*, Prem.longitude,
Prem.latitude
FROM Prem LEFT JOIN
JimsQueryByColl ON Prem.meter_miu_id =
JimsQueryByColl.[MIU ID]
WHERE
(((JimsQueryByColl.Collector)="Frederick
Road"))
Normally the Left Join would have achieved what i desire but the where statement is making it where the ids that would have blank information for all but the *Prem.meter_miu_id* field are not included. I have tried to add an "or JimsQueryByColl.Collector IS NULL" to the WHERE statement but that didn't get the correct result.
The current two query method I have for getting the right information are titled FredrickRoad and Query3:
FredrickRoad-
SELECT JimsQueryByColl.* FROM
JimsQueryByColl WHERE
(((JimsQueryByColl.Collector)="Frederick
Road"))
Followed by Query3 -
SELECT Prem.meter_miu_id,
JimsQueryByColl.*, Prem.longitude,
Prem.latitude FROM Prem LEFT JOIN
JimsQueryByColl ON Prem.meter_miu_id =
JimsQueryByColl.[MIU ID] WHERE
(((JimsQueryByColl.Collector)="Frederick
Road"));
But I would like to do this in one step if possible. I hope I have written this clearly and if someone needs clarification just ask.
Current Solution
SELECT Prem.meter_miu_id,
JimsQueryByColl.*, Prem.longitude,
Prem.latitude
Into FrederickRoad
FROM Prem LEFT JOIN
JimsQueryByColl ON (Prem.meter_miu_id
= JimsQueryByColl.[MIU ID]
AND JimsQueryByColl.Collector="Frederick
Road")
This gets around the odd bug/error I'm getting with the query since it puts it into a table and doesn't deal with the query directly again. I would however love to know what is causing the problems I'm having.
Try:
SELECT Prem.meter_miu_id, JimsQueryByColl.*, Prem.longitude, Prem.latitude
FROM Prem LEFT JOIN JimsQueryByColl
ON (Prem.meter_miu_id = JimsQueryByColl.[MIU ID]
AND JimsQueryByColl.Collector="Frederick Road")