Way to combine filtered results using LIKE - sql

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

Related

Union query to hide records that have a blank in a specific field

I've got a query that returns values from two tables:
SpecSheet which is static and has all product codes
InputWalls which is tied to a userform that allows people to select the code.
A Join argument is used, Join takes the 'InputSheet.codes' & 'SpecSheet.Code' as the target to match on both tables. Problem I have is that if Inputsheet.code is empty, It will still try pull the record of everything with it.
Here's my code:
SELECT
"Kitchen Main Walls" AS Type, InputWalls.Client, InputWalls.Site, InputWalls.PlotNO, InputWalls.KitchenMainCode, SpecSheet.DESCRIPTIONONE, SpecSheet.DESCRIPTIONTWO, SpecSheet.SIZE, SpecSheet.BOXQTY
FROM
InputWalls LEFT JOIN SpecSheet ON (InputWalls.Client = SpecSheet.Client) AND (InputWalls.KitchenMainCode = SpecSheet.Code)
WHERE
(((InputWalls.Client)="BARRATT") And ((InputWalls.Site)="LG") And ((InputWalls.PlotNO)="1"));
UNION ALL
SELECT
"Kitchen Feature Walls" AS Type, InputWalls.Client, InputWalls.Site, InputWalls.PlotNO, InputWalls.KitchenFeatureCode, SpecSheet.DESCRIPTIONONE, SpecSheet.DESCRIPTIONTWO, SpecSheet.SIZE, SpecSheet.BOXQTY
FROM
InputWalls LEFT JOIN SpecSheet ON (InputWalls.Client = SpecSheet.Client) AND (InputWalls.KitchenFeatureCode = SpecSheet.Code)
WHERE
(((InputWalls.Client)=Forms!MainMenu!ClientSearch.value) And ((InputWalls.Site)=Forms!MainMenu!SiteSearch.value) And ((InputWalls.PlotNO)=Forms!MainMenu!PlotSearch.value));
I have tried looking online for a solution, but I got nothing when It come to targeting a specific field. Kind regards.

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.

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.

Produce a Query viewing multiple tables

I have been given a database, the structure and data values are all unchangable and have been provided with a question.
Produce a query to list the holiday code, holiday description, holiday duration and site description for all holidays which visit site code 101. Your answer must not assume that site code 101 will always have the same site description.
I am confused on how to tackle this question. I have tried Multiple joins, different dot notation and googled the question to hell and back. Any help?
Table 1 - Holiday_Details
Holiday_Code - Country_Visited - Holiday_Duration - Holiday_Desc - Rating_Code - Cost
Table 2 - Site_Of_Holiday
Site_Description - Site_Code
Table 3 - Site_Visited
Holiday_Code - Site_Code
Comments have asked for previous attempts. This was my first.
SELECT holiday_code,
holiday_desc,
holiday_duration site_of_holiday.Site_Name
FROM holiday_details
JOIN site_visited
ON holiday_code = site_visited.holiday_code
JOIN site_of_holiday
ON site_visited.site_code = site_of_holiday.site_code
WHERE site_of_holiday.site_code = 101;
For future reference, you'll get a better response if you post a lot more detail about your failed attempts. By that, I mean code. Using SO to solve your homework assignments is frowned upon but, like a commenter said, once you've wracked your brain we're willing to help.
You seem like you may have actually tried real hard, so I'll throw you a bone...
The trick to navigating multiple tables is to find the "pairs" of matching columns. In this case you want to find a path between the tables Site_Of_Holiday (which has Site_Description) and Holiday_Details (which has everything else).
The columns that match between each pair of tables are:
Holiday_Code is found in both Site_Visited and Holiday_Details
Site_Code is found in both Site_Of_Holiday and Site_Visited
This allows you to build a path between the tables that contain all of the columns we want in the output. You would do this, in this case, using INNER JOINs across those matching column pairs.
Once you've joined the tables, think of the result like a giant table whose columns include all columns from all three tables (prefixed with whatever you 'name' the table during the joins). Now you just filter on the Site_Code with the usual WHERE clause.
Here's the full example - let me know if it works for you:
SELECT hd.Holiday_Code, hd.Holiday_Desc, hd.Holiday_Duration, soh.Site_Description
FROM Holiday_Details hd
INNER JOIN Site_Visited sv ON hd.Holiday_Code = sv.Holiday_Code
INNER JOIN Site_Of_Holiday soh ON sv.Site_Code = soh.Site_Code
WHERE sv.Site_Code = 101
Good luck!
P.S. In case any Americans get a similar assignment, here's the translation ;-)
SELECT vd.Vacation_Code, vd.Vacation_Desc, vd.Vacation_Duration, sov.Site_Description
FROM Vacation_Details vd
INNER JOIN Site_Visited sv ON vd.Vacation_Code = sv.Vacation_Code
INNER JOIN Site_Of_Vacation sov ON sv.Site_Code = sov.Site_Code
WHERE sv.Site_Code = 101

Trying to use table aliases in SQL

I'm a graphic designer trying my best to understand table aliases, but it's not working.
Here's what I have so far:
SELECT colours.colourid AS colourid1,
combinations.manufacturercolourid AS colourmanid1,
colours.colourname AS colourname1,
colours.colourhex AS colourhex1,
combinations.qecolourid2 AS colouridqe2,
colours.colourid AS colourid2,
colours.colourname AS colourname2,
colours.colourhex AS colourhex2,
colours.colourid AS colourid3,
combinations.qecolourid3 AS colouridqe3,
colours.colourname AS colourname3,
colours.colourhex AS colourhex3,
colours.colourid AS colourid4,
combinations.qecolourid4 AS colouridqe4,
colours.colourname AS colourname4,
colours.colourhex AS colourhex4,
combinations.coloursupplierid
FROM combinations
INNER JOIN colours
ON colours.colourid = combinations.manufacturercolourid;
Now, the idea is that in the colours lookup table, the id will pull the colour code, hex and name from the lookup table so that I can pull the colour code, hex and name for the 4 colours that I'm looking for. I can get this to work, but it only pulls up the first name, code and hex and I'm just not seeing what I'm doing wrong.
Your problem is that you are linking in only a single record from the colours table because you only have a single JOIN in your SQL. That record will match the color specified by manufacturer_colour_id.
You may also have a further problem in that your combinations table does not appear to be in proper normal form (although I could be wrong, not knowing the actual nature of the data you're trying to represent).
If I understand your problem correctly, the solution (using your current table structures) will be something more like:
SELECT C1.colourid AS colourid1,
CMB.manufacturercolourid AS colourmanid1,
C1.colourname AS colourname1,
C1.colourhex AS colourhex1,
CMB.qecolourid2 AS colouridqe2,
C2.colourid AS colourid2,
C2.colourname AS colourname2,
C2.colourhex AS colourhex2,
C3.colourid AS colourid3,
CMB.qecolourid3 AS colouridqe3,
C3.colourname AS colourname3,
C3.colourhex AS colourhex3,
C4.colourid AS colourid4,
CMB.qecolourid4 AS colouridqe4,
C4.colourname AS colourname4,
C4.colourhex AS colourhex4,
CMB.coloursupplierid
FROM combinations CMB
LEFT OUTER JOIN colours C1
ON C1.colourid = CMB.manufacturercolourid
LEFT OUTER JOIN colours C2
ON C2.colourid = CMB.qecolourid2
LEFT OUTER JOIN colours C3
ON C3.colourid = CMB.qecolourid3
LEFT OUTER JOIN colours C4
ON C4.colourid = CMB.qecolourid4
What's happening here is that I'm linking the colours table four times, once for each of the colour_id fields in the combinations table. To do so, I need to alias the table name each time so that I know which of the four possible instances of colours to use in the list of returned columns. Also, I'm using OUTER JOINs in the event that one or more colour_id columns might be empty. If that happened with INNER JOINs, the entire row would drop out of the result set.
You can use table aliases to reduce the amount of typing needed - by adding something like this:
SELECT
cl.colourid AS colourid1,
cb.manufacturercolourid AS colourmanid1,
cl.colourname AS colourname1,
... and so on.....
FROM
combinations AS cb
INNER JOIN
colours AS cl ON cl.colourid = cb.manufacturercolourid;
By defining a table alias cb for your table combinations, you can use that shorter alias in your SELECT and other parts of your statement, instead of having to always spell out the entire table name.
But your problem really is in the JOIN - you're only joining once, yet you expect to get four results back....
What you need to do is something like this:
SELECT
col1.colourid AS colourid1,
cb.manufacturercolourid AS colourmanid1,
col1.colourname AS colourname1,
col1.colourhex AS colourhex1,
cb.qecolourid2 AS colouridqe2,
col2.colourid AS colourid2,
col2.colourname AS colourname2,
col2.colourhex AS colourhex2,
col2.colourid AS colourid3,
cb.qecolourid3 AS colouridqe3,
col3.colourname AS colourname3,
col3.colourhex AS colourhex3,
col3.colourid AS colourid4,
cb.qecolourid4 AS colouridqe4,
col4.colourname AS colourname4,
col4.colourhex AS colourhex4,
cb.coloursupplierid
FROM
combinations cb
INNER JOIN colours AS col1 ON col1.colourid = cb.manufacturercolourid
INNER JOIN colours AS col2 ON col2.colourid = cb.qecolourid2
INNER JOIN colours AS col3 ON col3.colourid = cb.qecolourid3
INNER JOIN colours AS col4 ON col4.colourid = cb.qecolourid4
This is not an exhaustive answer, but your problem has to do with your how you are using the JOINs. Table and column aliases do not affect the output result set.
You are selecting the same field names four times, and that is why you are getting strange results.
These are all great, but for some reason when I try to use them, I get an error in the page:
[Microsoft][ODBC Microsoft Access Driver] Syntax error (missing operator) in query expression
I think I understand how to use the table aliases now, but for some reason, even though I'm sure it should work, the page doesn't like it.