SQL - Trouble with simple select query - sql

I'm having some trouble figuring out why the SQL query below isn't working ... when members_only is set to 0, it's still showing them...
SELECT *
FROM reports
WHERE story = "1"
OR barebones = "1"
AND members_only = "1"

It depends on your data, but you may not be aware that AND has higher precedence in SQL than OR, so your query really evaluates to this:
SELECT *
FROM reports
WHERE story = '1'
OR (barebones = '1' AND members_only = '1')
Consider using different brackets per the other answers to explicitly declare your intentions

Use brackets to distinguish your clarify the WHERE-condition.
SELECT *
FROM reports
WHERE (story = '1' OR barebones = '1')
AND members_only = '1'

I would say because it reads the query as:
WHERE (story = '1') OR (barebones = '1' AND members_only = '1')
since story = '1', the condition is satisfied
OR clauses can be tricky - you often need to explicitly tell the query where it belongs. I assume, you want this:
WHERE (story = '1' OR barebones = '1') AND members_only = '1'

Missing parenthesis?
Did you want to do something like this:
SELECT *
FROM reports
WHERE (story = "1" OR barebones = "1") AND members_only = "1"

You are missing parenthesis.
The following code will work, assuming members_only HAS to be "1", but only story or barebones has to be "1".
SELECT *
FROM reports
WHERE
(story = "1" OR barebones = "1")
AND members_only = "1"
You should read up on TSQL Operator Precedence
In your original code, assume the following:
store = 1
barebones = 1
*members_only* = 0
Due to Operator Precedence, barebones and *members_only* is evaluated first, and evaluates to false.
Following this, the result of the first boolean evaluation (false) (also known as The Right Side) is compared to (story = "1") (also known as The Left Side).
The Right Side evaluates to false, but The Left Side evaluates to true.
Since the final boolean compression uses the OR operator, the end result is a TRUE, thus that record is indeed returned, no matter the value of either barebones or *members_only*, since The Left Side always evaluates to True.

Related

How to write an Open SQL statement with substring in the JOIN ON condition? [duplicate]

I have the following select statement in ABAP:
SELECT munic~mandt VREFER BIS AB ZZELECDATE ZZCERTDATE CONSYEAR ZDIMO ZZONE_M ZZONE_T USAGE_M USAGE_T M2MC M2MT M2RET EXEMPTMCMT EXEMPRET CHARGEMCMT
INTO corresponding fields of table GT_INSTMUNIC_F
FROM ZCI00_INSTMUNIC AS MUNIC
INNER JOIN EVER AS EV on
MUNIC~POD = EV~VREFER(9).
"where EV~BSTATUS = '14' or EV~BSTATUS = '32'.
My problem with the above statement is that does not recognize the substring/offset operation on the 'ON' clause. If i remove the '(9) then
it recognizes the field, otherwise it gives error:
Field ev~refer is unknown. It is neither in one of the specified tables
nor defined by a "DATA" statement. I have also tried doing something similar in the 'Where' clause, receiving a similar error:
LOOP AT gt_instmunic.
clear wa_gt_instmunic_f.
wa_gt_instmunic_f-mandt = gt_instmunic-mandt.
wa_gt_instmunic_f-bis = gt_instmunic-bis.
wa_gt_instmunic_f-ab = gt_instmunic-ab.
wa_gt_instmunic_f-zzelecdate = gt_instmunic-zzelecdate.
wa_gt_instmunic_f-ZZCERTDATE = gt_instmunic-ZZCERTDATE.
wa_gt_instmunic_f-CONSYEAR = gt_instmunic-CONSYEAR.
wa_gt_instmunic_f-ZDIMO = gt_instmunic-ZDIMO.
wa_gt_instmunic_f-ZZONE_M = gt_instmunic-ZZONE_M.
wa_gt_instmunic_f-ZZONE_T = gt_instmunic-ZZONE_T.
wa_gt_instmunic_f-USAGE_M = gt_instmunic-USAGE_M.
wa_gt_instmunic_f-USAGE_T = gt_instmunic-USAGE_T.
temp_pod = gt_instmunic-pod.
SELECT vrefer
FROM ever
INTO wa_gt_instmunic_f-vrefer
WHERE ( vrefer(9) LIKE temp_pod ). " PROBLEM WITH SUBSTRING
"AND ( BSTATUS = '14' OR BSTATUS = '32' ).
ENDSELECT.
WRITE: / sy-dbcnt.
WRITE: / 'wa is: ', wa_gt_instmunic_f.
WRITE: / 'wa-ever is: ', wa_gt_instmunic_f-vrefer.
APPEND wa_gt_instmunic_f TO gt_instmunic_f.
WRITE: / wa_gt_instmunic_f-vrefer.
ENDLOOP.
itab_size = lines( gt_instmunic_f ).
WRITE: / 'Internal table populated with', itab_size, ' lines'.
The basic task i want to implement is to modify a specific field on one table,
pulling values from another. They have a common field ( pod = vrefer(9) ). Thanks in advance for your time.
If you are on a late enough NetWeaver version, it works on 7.51, you can use the OpenSQL function LEFT or SUBSTRING. Your query would look something like:
SELECT munic~mandt VREFER BIS AB ZZELECDATE ZZCERTDATE CONSYEAR ZDIMO ZZONE_M ZZONE_T USAGE_M USAGE_T M2MC M2MT M2RET EXEMPTMCMT EXEMPRET CHARGEMCMT
FROM ZCI00_INSTMUNIC AS MUNIC
INNER JOIN ever AS ev
ON MUNIC~POD EQ LEFT( EV~VREFER, 9 )
INTO corresponding fields of table GT_INSTMUNIC_F.
Note that the INTO clause needs to move to the end of the command as well.
field(9) is a subset operation that is processed by the ABAP environment and can not be translated into a database-level SQL statement (at least not at the moment, but I'd be surprised if it ever will be). Your best bet is either to select the datasets separately and merge them manually (if both are approximately equally large) or pre-select one and use a FAE/IN clause.
They have a common field ( pod = vrefer(9) )
This is a wrong assumption, because they both are not fields, but a field an other thing.
If you really need to do that task through SQL, I'll suggest you to check native SQL sentences like SUBSTRING and check if you can manage to use them within an EXEC_SQL or (better) the CL_SQL* classes.

PostgreSQL conditional where clause

In my Ruby on Rails app I'm using blazer(https://github.com/ankane/blazer) and I have the following sql query:
SELECT *
FROM survey_results sr
LEFT JOIN clients c ON c.id = sr.client_id
WHERE sr.client_id = {client_id}
This query works really well. But I need to add conditional logic to check if client_id variable is present. If yes then I filter by this variable, if not then I not launching this where clause. How can I do it in PostgreSQL?
Check if its null OR your condition like this:
WHERE {client_id} IS NULL OR sr.client_id = {client_id}
The WHERE clause evaluate as follow: If the variable is empty, then the WHERE clause evaluate to true, and therefore - no filter. If not, it continue to the next condition of the OR
If anyone faced with the psql operator does not exist: bigint = bytea issue, here is my workaround:
WHERE ({client_id} < 0 AND sr.client_id > {client_id}) OR sr.client_id = {client_id}
Please consider that, client_id generally cannot be negative so you can use that information for eleminating the operation cast issue.
My solution:
I use spring data jpa, native query.
Here is my repository interface signature.
#Query(... where (case when 0 in :itemIds then true else i.id in :itemIds end) ...)
List<Item> getItems(#Param("itemIds) List<Long> itemIds)
Prior calling this method, I check if itemIds is null. If yes, I set value to 0L:
if(itemIds == null) {
itemIds = new ArrayList<Long>();
itemIds.add(0L);
}
itemRepo.getItems(itemIds);
My IDs starts from 1 so there is no case when ID = 0.

Gain more Results on enhancing the query on one specific Server

I wrote an Access add-in (VBA) which works perfectly fine on my and other test servers, but on one server I encountered a very strange problem. When I execute the query with the data condition, I get the correct results (which are none). When I add the date condition I get more results than before. These results do not even match with my other conditions. I use the exact same database on both servers.
Here is the Query:
select BE.* from dbo.KHKBuchungserfassung AS BE
left join KHKSachkonten AS SSK on BE.KtoSoll = SSK.SaKto and BE.Mandant = SSK.Mandant
left join KHKSachkonten AS HSK on BE.KtoHaben = HSK.SaKto and BE.Mandant = HSK.Mandant
where ((((BE.KtoSollTyp = 1) or (BE.KtoSollTyp = 2)) and (HSK.Kontenart = 'BF' or HSK.Kontenart = 'BG')) or
(((BE.KtoHabentyp = 1) or (BE.KtoHabentyp = 2)) and (SSK.Kontenart = 'BF' or SSK.Kontenart = 'BG')))
and BE.Mandant= 88 and BE.Buchungsdatum>={d '2016-01-01'} AND BE.Buchungsdatum<={d '2016-06-30'}
If I execute this on that specific server with from date < a specific date ('2016-02-24') it also works perfectly fine (e.g. '2016-01-01' & '2016-06-30'). Any given date higher than this one gives results that violate my first condition... (the one in the parenthesis). I already checked the number of parenthesis. I also rotated the places of the given conditions. In addition to that, I am pretty sure my DBMS would give me an error if there is a problem with my syntax (not sure though).
This is the Result Set:
Dim rs As ADODB.Recordset
sQry = ...
Set rs = goMandant.oData.rsOpenRecordset(sQry, adOpenStatic)
Do Until rs.EOF
...
I am sorry that I can not provide test data due to juridical reasons, but if you would also select SSK.Kontenart and HSK.Kontenart there would be 'NULL' on both sides which is not at all possible in my first condition...
I would also like to note that this is my first question and if I made any mistakes, I would appreciate it if you told me.
Regards
TK

Decode with AND clause oracle

I want to use parameter in my query but I can't handle with it
I have 3 big selects to raport and I just want to use parameter for some part of code which depends from choice
I have 3 different Where conditions
1st
..WHERE A.CANCELLED = 'FALSE' AND a.open_amount!=0 AND A.IDENTITY = '&client_id'..
2nd
...WHERE A.CANCELLED = 'FALSE' AND A.IDENTITY = '&client_id' ...
3rd
WHERE AND A.CANCELLED = 'FALSE' AND a.invoice_amount != a.open_amount AND A.IDENTITY = '&client_id'
I tried with decode but I guess it could be ok if there would be value in 2nd case but there isn't and I cant decode like this
WHERE decode(xxx,x1,'AND a.open_amount!= 0',x2,'',x3, 'AND a.invoice_amount != a.open_amount')
How I should solve that problem any tips?
Do you mean, if the first "where condition" OR the second OR the third is/are TRUE, you want the overall to be TRUE (select the row), and you are looking for a simplified way to write it? That is, without simply combining them with OR?
To achieve that, you don't need CASE and nested CASE statements or DECODE. You could do it like this:
WHERE A.CANCELLED = 'FALSE'
AND A.IDENTITY = '&client_id'
AND ( (xxx = x1 AND a.open_amount != 0) OR (xxx = x2) OR
(xxx = x3 AND a.invoice_amount != a.open_amount) )
This is more readable, the intent is clear, it will be easier to modify if needed, ...
You can try something like -
WHERE A.CANCELLED = 'FALSE'
AND A.IDENTITY = '&client_id'
AND a.open_amount <>
(CASE
WHEN x1 THEN 0
WHEN x2 THEN a.open_amount + 1 -- This needs to be something that is always TRUE, to nullify the condition
WHEN x3 THEN a.invoice_amount
END);
Edit: This is based on the assumption that a.open_amount is a NUMBER and uses a quick hack where we create an always TRUE condition like x <> x + 1. You should probably change this to whatever suits you better based on your data.

Query Not returning exactly what I want

I'm a little confused to why my query is not returning exactly what I expect. This is my query in SQL.
"SELECT \"users\".* FROM \"users\" INNER JOIN \"alerts\" ON \"alerts\".\"user_id\" = \"users\".\"id\" WHERE (bus_route = 'The 06:30 To Wexford' AND stop = 'Camolin' AND first_alert = '5' OR second_alert = '5' OR third_alert = '5')"
And this is what I have in Rails:
Alert.where("bus_route = '#{b}' AND stop = '#{s}' AND first_alert = '#{t}' OR second_alert = '#{t}' OR third_alert = '#{t}'")
The conditions I am aiming for here is to find an alert with the bus_route passed, stop passed and either the first, second or third alert can equal the time in minutes passed.
But what my query is doing is returning is an alert where as long as any of the alert fields equal the parameter passed and the bus_route and stop do not equal.
I am a big SQL and Rails query noob for the record and this is my first "complex" query.
Help would be appreciated thanks.
Add parentheses around the first_alert = '#{t}' OR second_alert = '#{t}' OR third_alert = '#{t}' section, OR has a lower priority than AND.
you can try to enclose the OR statements in a parenthesis
"SELECT \"users\".* FROM \"users\" INNER JOIN \"alerts\" ON \"alerts\".\"user_id\" = \"users\".\"id\" WHERE ((bus_route = 'The 06:30 To Wexford' AND stop = 'Camolin') AND (first_alert = '5' OR second_alert = '5' OR third_alert = '5'))"