INTERSECT not acting as I expect - sql

I'm not sure if this is a symptom of my relative inexperience with SQL, or with h2. I have a view, called VIEW_TRANSACTION_LEGS_DATA, which I need to search in various ways. So, for example, I have:
SELECT HEAD_ID FROM VIEW_TRANSACTION_LEGS_DATA WHERE AMOUNT > 1000
and I also have:
SELECT * FROM
(SELECT HEAD_ID FROM VIEW_TRANSACTION_LEGS_DATA WHERE AMOUNT > 1000)
INTERSECT
(SELECT HEAD_ID FROM VIEW_TRANSACTION_LEGS_DATA WHERE AMOUNT < 2000)
Unfortunately, this isn't working as I expect! There should only be 3 rows returned, whereas I am getting 57 returned.
(Note that the above is a simplified version of what my code actually says; please don't suggest to me to combine the INTERSECTed lines using a BETWEEN since this will not work with the rest of the code.)
I'm sure my problem is a typical SQL newbie type problem, but I simply can't see it! Can some kind person please point me in the right direction?

Related

SQL Sub-Query Troubles

I have a SQL assignment I am working on for school (just a series of query and sub-query questions) and I have them all complete but one. Here is the prompt for reference:
10. Find the AM hours with total traffic load with 200 or more.
I have the code for the first part, the AM hours. It is as such:
select hour(traffic.ttime), sum(traffic.packetsize)
from traffic
where hour(traffic.ttime) <= 12
group by hour(traffic.ttime);
The only thing I cant figure out is how to get only the ones with 200 or more. It should return only 3 rows but regardless of what I try it still returns all or non. I'm pretty sure a sub-query needs to be used here but I cant seem to figure it out. This is what I have tried so far:
select hour(traffic.ttime), sum(traffic.packetsize)
from traffic
where hour(traffic.ttime) <= 12 and (select sum(traffic.packetsize) from
traffic)>=200
group by hour(traffic.ttime) ;
Logically I know that is incorrect due to the fact that it will just return the sum of all the packet sizes in that given table. I cant seem to come up with anyway to make it work without it throwing an error. Any help would be appreciated!
select hour(traffic.ttime), sum(traffic.packetsize)from traffic where hour(traffic.ttime) <= 12 group by hour(traffic.ttime) having sum(traffic.packetsize)>=200

Order by in subquery behaving differently than native sql query?

So I am honestly a little puzzled by this!
I have a query that returns a set of transactions that contain both repair costs and an odometer reading at the time of repair on the master level. To get an accurate Cost per mile reading I need to do a subquery to get both the first meter reading between a starting date and an end date, and an ending meter.
(select top 1 wf2.ro_num
from wotrans wotr2
left join wofile wf2
on wotr2.rop_ro_num = wf2.ro_num
and wotr2.rop_fac = wf2.ro_fac
where wotr.rop_veh_num = wotr2.rop_veh_num
and wotr.rop_veh_facility = wotr2.rop_veh_facility
AND ((#sdate = '01/01/1900 00:00:00' and wotr2.rop_tran_date = 0)
OR ([dbo].[udf_RTA_ConvertDateInt](#sdate) <= wotr2.rop_tran_date
AND [dbo].[udf_RTA_ConvertDateInt](#edate) >= wotr2.rop_tran_date))
order by wotr2.rop_tran_date asc) as highMeter
The reason I have the tables aliased as xx2 is because those tables are also used in the main query, and I don't want these to interact with each other except to pull the correct vehicle number and facility.
Basically when I run the main query it returns a value that is not correct; it returns the one that is second(keep in mind that the first and second have the same date.) But when I take the subquery and just copy and paste it into it's own query and run it, it returns the correct value.
I do have a work around for this, but I am just curious as to why this happening. I have searched quite a bit and found not much(other than the fact that people don't like order bys in subqueries). Talking to one of my friends that also does quite a bit of SQL scripting, it looks to us as if the subquery is ordering differently than the subquery by itsself when you have multiple values that are the same for the order by(i.e. 10 dates of 08/05/2016).
Any ideas would be helpful!
Like I said I have a work around that works in this one case, but don't know yet if it will work on a larger dataset.
Let me know if you want more code.

Excluding records based on multiple variables

SQL noob here. I'm using MS Access to query a table of streetlight data to exclude lights of a certain size and only where the fixture type is a variant of "Cobra". Is anyone kind enough to give me some guidance on what I might be doing wrong?
I can produce the lights I need to be excluded with:
SELECT *
FROM Lighting
WHERE Lighting.TYPE_FIXTURE LIKE '*cobra*'
AND Lighting.SIZ < '16'
Simple enough. I thought this would be easy to tweak a little bit to get it to exclude these instead of produce them.
SELECT *
FROM Lighting
WHERE Lighting.TYPE_FIXTURE NOT IN ('*Cobra*')
AND Lighting.SIZ NOT IN ('10', '15')
This code excludes the lights I need to be excluded, but also every other type of light that is 100 or 150w. For the life of me, I can't figure out how to exclude ONLY Cobra lights 150w or less.
Through extensive internet research, I tried using an IIF expression to produce a temporary column that would have a value of 0 or 1, depending on if it needed to be excluded or not,
SELECT *
,IIf(Lighting.TYPE_FIXTURE LIKE "*cobra*" AND Lighting.SIZ < 15, 0, 1) AS IncludeFlag
INTO #MyTempTable
FROM Lighting
SELECT *
FROM #MyTempTable
WHERE IncludeFlag = 1
but my only result is an error message that I don't know how to resolve. I've spent all day on this one query and I'm starting to pull my hair out!!
Try this...
SELECT *
FROM Lighting
WHERE (Lighting.TYPE_FIXTURE NOT LIKE '*cobra*'
AND Lighting.SIZ < '16')
Converting from a TRUE and TRUE to a NOT(TRUE and TRUE) involves distributing the NOT inside the brackets and switch the AND to an OR.
The following should give you the results you want:
SELECT *
FROM Lighting
WHERE Lighting.TYPE_FIXTURE Not Like '*cobra*' OR Lighting.SIZ>='16';

Access Query Help - Get records within a timeframe of another record

I'm looking for a way of querying a table to get events of a certain type, and all events that happen within the time-frame of the criteria event for the same person. That probably sounded like nonsense. Consider the following;
Imagine I want to get all "SHIFT"s for each person (A person could have multiple shifts per day) and it's associated breaks (But there could be other things as well) a way to query within a date range would be good as well. Eventually I'm going to be working with years worth of data, not all of which is necessary to everybody.
This example would return the first three rows, plus the last two. Row 5 is a BREAK, but it doesn't occur within a SHIFT for person 1.
I would love to provide some code but I honestly can't even think where to start with this one. I guess I'd need a sub query? Any help would be greatly appreciated!
I'm mostly using access 2003 so responses geared towards that would be ideal.
The way you've described the problem, it appears you want the shifts and related breaks as separate rows. To do this you can use union all to combine the two different types. A correlated sub query lets you find breaks that occur during shifts.
Select
*
From
Events
Where
Event_Name = 'SHIFT'
Union All
Select
*
From
Events e1
Where
Event_Name = 'BREAK' And
Exists (
Select
'x'
From
Events e2 -- find corresponding shift for break
Where
e1.Event_Owner = e2.Event_Owner And
e2.Event_Name = 'SHIFT' And
e1.Event_Start >= e2.Event_Start And
e1.Event_End <= e2.Event_End
)

Convert row data into columns Access 07 without using PIVOT

I am on a work term from school. I am not very comfortable using SQL, I am trying to get a hold of it....
My supervisor gave me a task for a user in which I need to take row data and make columns. We used the Crosstab Wizard and automagically created the SQL to get what we needed.
Basically, we have a table like this:
ReqNumber Year FilledFlag(is a checkbox) FilledBy
1 2012 (notchecked) ITSchoolBoy
1 2012 (checked) GradStudent
1 2012 (notchecked) HighSchooler
2 etc, etc.
What the user would like is to have a listing of all of the req numbers and what is checked
Our automatic pivot code gives us all of the FilledBy options (there are 9 in total) as column headings, and groups it all by reqnumber.
How can you do this without the pivot? I would like to wrap my head around this. Nearest I can find is something like:
SELECT
SUM(IIF(FilledBy = 'ITSchoolboy',1,0) as ITSchoolboy,
SUM(IIF(FilledBy = 'GradStudent',1,0) as GradStudent, etc.
FROM myTable
Could anyone help explain this to me? Point me in the direction of a guide? I've been searching for the better part of a day now, and even though I am a student, I don't think this will be smiled upon for too long. But I would really like to know!
I think your boss' suggestion could work if you GROUP BY ReqNumber.
SELECT
ReqNumber,
SUM(IIF(FilledBy = 'ITSchoolboy',1,0) as ITSchoolboy,
SUM(IIF(FilledBy = 'GradStudent',1,0) as GradStudent,
etc.
FROM myTable
GROUP BY ReqNumber;
A different approach would be to JOIN multiple subqueries. This example pulls in 2 of your categories. If you need to extend it to 9 categories, you would have a whole lot of joining going on.
SELECT
itsb.ReqNumber,
itsb.ITSchoolboy,
grad.GradStudent
FROM
(
SELECT
ReqNumber,
FilledFlag AS ITSchoolboy
FROM myTable
WHERE FilledBy = "ITSchoolboy"
) AS itsb
INNER JOIN
(
SELECT
ReqNumber,
FilledFlag AS GradStudent
FROM myTable
WHERE FilledBy = "GradStudent"
) AS grad
ON itsb.ReqNumber = grad.ReqNumber
Please notice I'm not suggesting you should use this approach. However, since you asked about alternatives to your pivot approach (which works) ... this is one. Stay tuned in case someone else offers a simpler alternative. :-)